]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
3.18-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 22 Feb 2018 18:18:48 +0000 (19:18 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 22 Feb 2018 18:18:48 +0000 (19:18 +0100)
added patches:
crypto-x86-twofish-3way-fix-rbp-usage.patch
mm-vmscan-make-unregister_shrinker-no-op-if-register_shrinker-failed.patch
net-avoid-skb_warn_bad_offload-on-is_err.patch
netfilter-ipt_clusterip-fix-out-of-bounds-accesses-in-clusterip_tg_check.patch
netfilter-on-sockopt-acquire-sock-lock-only-in-the-required-scope.patch
netfilter-x_tables-avoid-out-of-bounds-reads-in-xt_request_find_-match-target.patch
netfilter-x_tables-fix-int-overflow-in-xt_alloc_table_info.patch
netfilter-xt_rateest-acquire-xt_rateest_mutex-for-hash-insert.patch
provide-a-function-to-create-a-nul-terminated-string-from-unterminated-data.patch
selinux-ensure-the-context-is-nul-terminated-in-security_context_to_sid_core.patch
selinux-skip-bounded-transition-processing-if-the-policy-isn-t-loaded.patch
staging-android-ion-add-__gfp_nowarn-for-system-contig-heap.patch
xfrm-check-id-proto-in-validate_tmpl.patch

14 files changed:
queue-3.18/crypto-x86-twofish-3way-fix-rbp-usage.patch [new file with mode: 0644]
queue-3.18/mm-vmscan-make-unregister_shrinker-no-op-if-register_shrinker-failed.patch [new file with mode: 0644]
queue-3.18/net-avoid-skb_warn_bad_offload-on-is_err.patch [new file with mode: 0644]
queue-3.18/netfilter-ipt_clusterip-fix-out-of-bounds-accesses-in-clusterip_tg_check.patch [new file with mode: 0644]
queue-3.18/netfilter-on-sockopt-acquire-sock-lock-only-in-the-required-scope.patch [new file with mode: 0644]
queue-3.18/netfilter-x_tables-avoid-out-of-bounds-reads-in-xt_request_find_-match-target.patch [new file with mode: 0644]
queue-3.18/netfilter-x_tables-fix-int-overflow-in-xt_alloc_table_info.patch [new file with mode: 0644]
queue-3.18/netfilter-xt_rateest-acquire-xt_rateest_mutex-for-hash-insert.patch [new file with mode: 0644]
queue-3.18/provide-a-function-to-create-a-nul-terminated-string-from-unterminated-data.patch [new file with mode: 0644]
queue-3.18/selinux-ensure-the-context-is-nul-terminated-in-security_context_to_sid_core.patch [new file with mode: 0644]
queue-3.18/selinux-skip-bounded-transition-processing-if-the-policy-isn-t-loaded.patch [new file with mode: 0644]
queue-3.18/series
queue-3.18/staging-android-ion-add-__gfp_nowarn-for-system-contig-heap.patch [new file with mode: 0644]
queue-3.18/xfrm-check-id-proto-in-validate_tmpl.patch [new file with mode: 0644]

diff --git a/queue-3.18/crypto-x86-twofish-3way-fix-rbp-usage.patch b/queue-3.18/crypto-x86-twofish-3way-fix-rbp-usage.patch
new file mode 100644 (file)
index 0000000..f8b333a
--- /dev/null
@@ -0,0 +1,260 @@
+From d8c7fe9f2a486a6e5f0d5229ca43807af5ab22c6 Mon Sep 17 00:00:00 2001
+From: Eric Biggers <ebiggers@google.com>
+Date: Mon, 18 Dec 2017 16:40:26 -0800
+Subject: crypto: x86/twofish-3way - Fix %rbp usage
+
+From: Eric Biggers <ebiggers@google.com>
+
+commit d8c7fe9f2a486a6e5f0d5229ca43807af5ab22c6 upstream.
+
+Using %rbp as a temporary register breaks frame pointer convention and
+breaks stack traces when unwinding from an interrupt in the crypto code.
+
+In twofish-3way, we can't simply replace %rbp with another register
+because there are none available.  Instead, we use the stack to hold the
+values that %rbp, %r11, and %r12 were holding previously.  Each of these
+values represents the half of the output from the previous Feistel round
+that is being passed on unchanged to the following round.  They are only
+used once per round, when they are exchanged with %rax, %rbx, and %rcx.
+
+As a result, we free up 3 registers (one per block) and can reassign
+them so that %rbp is not used, and additionally %r14 and %r15 are not
+used so they do not need to be saved/restored.
+
+There may be a small overhead caused by replacing 'xchg REG, REG' with
+the needed sequence 'mov MEM, REG; mov REG, MEM; mov REG, REG' once per
+round.  But, counterintuitively, when I tested "ctr-twofish-3way" on a
+Haswell processor, the new version was actually about 2% faster.
+(Perhaps 'xchg' is not as well optimized as plain moves.)
+
+Reported-by: syzbot <syzkaller@googlegroups.com>
+Signed-off-by: Eric Biggers <ebiggers@google.com>
+Reviewed-by: Josh Poimboeuf <jpoimboe@redhat.com>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/x86/crypto/twofish-x86_64-asm_64-3way.S |  118 ++++++++++++++-------------
+ 1 file changed, 63 insertions(+), 55 deletions(-)
+
+--- a/arch/x86/crypto/twofish-x86_64-asm_64-3way.S
++++ b/arch/x86/crypto/twofish-x86_64-asm_64-3way.S
+@@ -55,29 +55,31 @@
+ #define RAB1bl %bl
+ #define RAB2bl %cl
++#define CD0 0x0(%rsp)
++#define CD1 0x8(%rsp)
++#define CD2 0x10(%rsp)
++
++# used only before/after all rounds
+ #define RCD0 %r8
+ #define RCD1 %r9
+ #define RCD2 %r10
+-#define RCD0d %r8d
+-#define RCD1d %r9d
+-#define RCD2d %r10d
+-
+-#define RX0 %rbp
+-#define RX1 %r11
+-#define RX2 %r12
+-
+-#define RX0d %ebp
+-#define RX1d %r11d
+-#define RX2d %r12d
+-
+-#define RY0 %r13
+-#define RY1 %r14
+-#define RY2 %r15
+-
+-#define RY0d %r13d
+-#define RY1d %r14d
+-#define RY2d %r15d
++# used only during rounds
++#define RX0 %r8
++#define RX1 %r9
++#define RX2 %r10
++
++#define RX0d %r8d
++#define RX1d %r9d
++#define RX2d %r10d
++
++#define RY0 %r11
++#define RY1 %r12
++#define RY2 %r13
++
++#define RY0d %r11d
++#define RY1d %r12d
++#define RY2d %r13d
+ #define RT0 %rdx
+ #define RT1 %rsi
+@@ -85,6 +87,8 @@
+ #define RT0d %edx
+ #define RT1d %esi
++#define RT1bl %sil
++
+ #define do16bit_ror(rot, op1, op2, T0, T1, tmp1, tmp2, ab, dst) \
+       movzbl ab ## bl,                tmp2 ## d; \
+       movzbl ab ## bh,                tmp1 ## d; \
+@@ -92,6 +96,11 @@
+       op1##l T0(CTX, tmp2, 4),        dst ## d; \
+       op2##l T1(CTX, tmp1, 4),        dst ## d;
++#define swap_ab_with_cd(ab, cd, tmp)  \
++      movq cd, tmp;                   \
++      movq ab, cd;                    \
++      movq tmp, ab;
++
+ /*
+  * Combined G1 & G2 function. Reordered with help of rotates to have moves
+  * at begining.
+@@ -110,15 +119,15 @@
+       /* G1,2 && G2,2 */ \
+       do16bit_ror(32, xor, xor, Tx2, Tx3, RT0, RT1, ab ## 0, x ## 0); \
+       do16bit_ror(16, xor, xor, Ty3, Ty0, RT0, RT1, ab ## 0, y ## 0); \
+-      xchgq cd ## 0, ab ## 0; \
++      swap_ab_with_cd(ab ## 0, cd ## 0, RT0); \
+       \
+       do16bit_ror(32, xor, xor, Tx2, Tx3, RT0, RT1, ab ## 1, x ## 1); \
+       do16bit_ror(16, xor, xor, Ty3, Ty0, RT0, RT1, ab ## 1, y ## 1); \
+-      xchgq cd ## 1, ab ## 1; \
++      swap_ab_with_cd(ab ## 1, cd ## 1, RT0); \
+       \
+       do16bit_ror(32, xor, xor, Tx2, Tx3, RT0, RT1, ab ## 2, x ## 2); \
+       do16bit_ror(16, xor, xor, Ty3, Ty0, RT0, RT1, ab ## 2, y ## 2); \
+-      xchgq cd ## 2, ab ## 2;
++      swap_ab_with_cd(ab ## 2, cd ## 2, RT0);
+ #define enc_round_end(ab, x, y, n) \
+       addl y ## d,                    x ## d; \
+@@ -168,6 +177,16 @@
+       decrypt_round3(ba, dc, (n*2)+1); \
+       decrypt_round3(ba, dc, (n*2));
++#define push_cd()     \
++      pushq RCD2;     \
++      pushq RCD1;     \
++      pushq RCD0;
++
++#define pop_cd()      \
++      popq RCD0;      \
++      popq RCD1;      \
++      popq RCD2;
++
+ #define inpack3(in, n, xy, m) \
+       movq 4*(n)(in),                 xy ## 0; \
+       xorq w+4*m(CTX),                xy ## 0; \
+@@ -223,11 +242,8 @@ ENTRY(__twofish_enc_blk_3way)
+        *      %rdx: src, RIO
+        *      %rcx: bool, if true: xor output
+        */
+-      pushq %r15;
+-      pushq %r14;
+       pushq %r13;
+       pushq %r12;
+-      pushq %rbp;
+       pushq %rbx;
+       pushq %rcx; /* bool xor */
+@@ -235,40 +251,36 @@ ENTRY(__twofish_enc_blk_3way)
+       inpack_enc3();
+-      encrypt_cycle3(RAB, RCD, 0);
+-      encrypt_cycle3(RAB, RCD, 1);
+-      encrypt_cycle3(RAB, RCD, 2);
+-      encrypt_cycle3(RAB, RCD, 3);
+-      encrypt_cycle3(RAB, RCD, 4);
+-      encrypt_cycle3(RAB, RCD, 5);
+-      encrypt_cycle3(RAB, RCD, 6);
+-      encrypt_cycle3(RAB, RCD, 7);
++      push_cd();
++      encrypt_cycle3(RAB, CD, 0);
++      encrypt_cycle3(RAB, CD, 1);
++      encrypt_cycle3(RAB, CD, 2);
++      encrypt_cycle3(RAB, CD, 3);
++      encrypt_cycle3(RAB, CD, 4);
++      encrypt_cycle3(RAB, CD, 5);
++      encrypt_cycle3(RAB, CD, 6);
++      encrypt_cycle3(RAB, CD, 7);
++      pop_cd();
+       popq RIO; /* dst */
+-      popq %rbp; /* bool xor */
++      popq RT1; /* bool xor */
+-      testb %bpl, %bpl;
++      testb RT1bl, RT1bl;
+       jnz .L__enc_xor3;
+       outunpack_enc3(mov);
+       popq %rbx;
+-      popq %rbp;
+       popq %r12;
+       popq %r13;
+-      popq %r14;
+-      popq %r15;
+       ret;
+ .L__enc_xor3:
+       outunpack_enc3(xor);
+       popq %rbx;
+-      popq %rbp;
+       popq %r12;
+       popq %r13;
+-      popq %r14;
+-      popq %r15;
+       ret;
+ ENDPROC(__twofish_enc_blk_3way)
+@@ -278,35 +290,31 @@ ENTRY(twofish_dec_blk_3way)
+        *      %rsi: dst
+        *      %rdx: src, RIO
+        */
+-      pushq %r15;
+-      pushq %r14;
+       pushq %r13;
+       pushq %r12;
+-      pushq %rbp;
+       pushq %rbx;
+       pushq %rsi; /* dst */
+       inpack_dec3();
+-      decrypt_cycle3(RAB, RCD, 7);
+-      decrypt_cycle3(RAB, RCD, 6);
+-      decrypt_cycle3(RAB, RCD, 5);
+-      decrypt_cycle3(RAB, RCD, 4);
+-      decrypt_cycle3(RAB, RCD, 3);
+-      decrypt_cycle3(RAB, RCD, 2);
+-      decrypt_cycle3(RAB, RCD, 1);
+-      decrypt_cycle3(RAB, RCD, 0);
++      push_cd();
++      decrypt_cycle3(RAB, CD, 7);
++      decrypt_cycle3(RAB, CD, 6);
++      decrypt_cycle3(RAB, CD, 5);
++      decrypt_cycle3(RAB, CD, 4);
++      decrypt_cycle3(RAB, CD, 3);
++      decrypt_cycle3(RAB, CD, 2);
++      decrypt_cycle3(RAB, CD, 1);
++      decrypt_cycle3(RAB, CD, 0);
++      pop_cd();
+       popq RIO; /* dst */
+       outunpack_dec3();
+       popq %rbx;
+-      popq %rbp;
+       popq %r12;
+       popq %r13;
+-      popq %r14;
+-      popq %r15;
+       ret;
+ ENDPROC(twofish_dec_blk_3way)
diff --git a/queue-3.18/mm-vmscan-make-unregister_shrinker-no-op-if-register_shrinker-failed.patch b/queue-3.18/mm-vmscan-make-unregister_shrinker-no-op-if-register_shrinker-failed.patch
new file mode 100644 (file)
index 0000000..a2a7386
--- /dev/null
@@ -0,0 +1,110 @@
+From bb422a738f6566f7439cd347d54e321e4fe92a9f Mon Sep 17 00:00:00 2001
+From: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
+Date: Mon, 18 Dec 2017 20:31:41 +0900
+Subject: mm,vmscan: Make unregister_shrinker() no-op if register_shrinker() failed.
+
+From: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
+
+commit bb422a738f6566f7439cd347d54e321e4fe92a9f upstream.
+
+Syzbot caught an oops at unregister_shrinker() because combination of
+commit 1d3d4437eae1bb29 ("vmscan: per-node deferred work") and fault
+injection made register_shrinker() fail and the caller of
+register_shrinker() did not check for failure.
+
+----------
+[  554.881422] FAULT_INJECTION: forcing a failure.
+[  554.881422] name failslab, interval 1, probability 0, space 0, times 0
+[  554.881438] CPU: 1 PID: 13231 Comm: syz-executor1 Not tainted 4.14.0-rc8+ #82
+[  554.881443] Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/01/2011
+[  554.881445] Call Trace:
+[  554.881459]  dump_stack+0x194/0x257
+[  554.881474]  ? arch_local_irq_restore+0x53/0x53
+[  554.881486]  ? find_held_lock+0x35/0x1d0
+[  554.881507]  should_fail+0x8c0/0xa40
+[  554.881522]  ? fault_create_debugfs_attr+0x1f0/0x1f0
+[  554.881537]  ? check_noncircular+0x20/0x20
+[  554.881546]  ? find_next_zero_bit+0x2c/0x40
+[  554.881560]  ? ida_get_new_above+0x421/0x9d0
+[  554.881577]  ? find_held_lock+0x35/0x1d0
+[  554.881594]  ? __lock_is_held+0xb6/0x140
+[  554.881628]  ? check_same_owner+0x320/0x320
+[  554.881634]  ? lock_downgrade+0x990/0x990
+[  554.881649]  ? find_held_lock+0x35/0x1d0
+[  554.881672]  should_failslab+0xec/0x120
+[  554.881684]  __kmalloc+0x63/0x760
+[  554.881692]  ? lock_downgrade+0x990/0x990
+[  554.881712]  ? register_shrinker+0x10e/0x2d0
+[  554.881721]  ? trace_event_raw_event_module_request+0x320/0x320
+[  554.881737]  register_shrinker+0x10e/0x2d0
+[  554.881747]  ? prepare_kswapd_sleep+0x1f0/0x1f0
+[  554.881755]  ? _down_write_nest_lock+0x120/0x120
+[  554.881765]  ? memcpy+0x45/0x50
+[  554.881785]  sget_userns+0xbcd/0xe20
+(...snipped...)
+[  554.898693] kasan: CONFIG_KASAN_INLINE enabled
+[  554.898724] kasan: GPF could be caused by NULL-ptr deref or user memory access
+[  554.898732] general protection fault: 0000 [#1] SMP KASAN
+[  554.898737] Dumping ftrace buffer:
+[  554.898741]    (ftrace buffer empty)
+[  554.898743] Modules linked in:
+[  554.898752] CPU: 1 PID: 13231 Comm: syz-executor1 Not tainted 4.14.0-rc8+ #82
+[  554.898755] Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/01/2011
+[  554.898760] task: ffff8801d1dbe5c0 task.stack: ffff8801c9e38000
+[  554.898772] RIP: 0010:__list_del_entry_valid+0x7e/0x150
+[  554.898775] RSP: 0018:ffff8801c9e3f108 EFLAGS: 00010246
+[  554.898780] RAX: dffffc0000000000 RBX: 0000000000000000 RCX: 0000000000000000
+[  554.898784] RDX: 0000000000000000 RSI: ffff8801c53c6f98 RDI: ffff8801c53c6fa0
+[  554.898788] RBP: ffff8801c9e3f120 R08: 1ffff100393c7d55 R09: 0000000000000004
+[  554.898791] R10: ffff8801c9e3ef70 R11: 0000000000000000 R12: 0000000000000000
+[  554.898795] R13: dffffc0000000000 R14: 1ffff100393c7e45 R15: ffff8801c53c6f98
+[  554.898800] FS:  0000000000000000(0000) GS:ffff8801db300000(0000) knlGS:0000000000000000
+[  554.898804] CS:  0010 DS: 002b ES: 002b CR0: 0000000080050033
+[  554.898807] CR2: 00000000dbc23000 CR3: 00000001c7269000 CR4: 00000000001406e0
+[  554.898813] DR0: 0000000020000000 DR1: 0000000020000000 DR2: 0000000000000000
+[  554.898816] DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000600
+[  554.898818] Call Trace:
+[  554.898828]  unregister_shrinker+0x79/0x300
+[  554.898837]  ? perf_trace_mm_vmscan_writepage+0x750/0x750
+[  554.898844]  ? down_write+0x87/0x120
+[  554.898851]  ? deactivate_super+0x139/0x1b0
+[  554.898857]  ? down_read+0x150/0x150
+[  554.898864]  ? check_same_owner+0x320/0x320
+[  554.898875]  deactivate_locked_super+0x64/0xd0
+[  554.898883]  deactivate_super+0x141/0x1b0
+----------
+
+Since allowing register_shrinker() callers to call unregister_shrinker()
+when register_shrinker() failed can simplify error recovery path, this
+patch makes unregister_shrinker() no-op when register_shrinker() failed.
+Also, reset shrinker->nr_deferred in case unregister_shrinker() was
+by error called twice.
+
+Signed-off-by: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
+Signed-off-by: Aliaksei Karaliou <akaraliou.dev@gmail.com>
+Reported-by: syzbot <syzkaller@googlegroups.com>
+Cc: Glauber Costa <glauber@scylladb.com>
+Cc: Al Viro <viro@zeniv.linux.org.uk>
+Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ mm/vmscan.c |    3 +++
+ 1 file changed, 3 insertions(+)
+
+--- a/mm/vmscan.c
++++ b/mm/vmscan.c
+@@ -220,10 +220,13 @@ EXPORT_SYMBOL(register_shrinker);
+  */
+ void unregister_shrinker(struct shrinker *shrinker)
+ {
++      if (!shrinker->nr_deferred)
++              return;
+       down_write(&shrinker_rwsem);
+       list_del(&shrinker->list);
+       up_write(&shrinker_rwsem);
+       kfree(shrinker->nr_deferred);
++      shrinker->nr_deferred = NULL;
+ }
+ EXPORT_SYMBOL(unregister_shrinker);
diff --git a/queue-3.18/net-avoid-skb_warn_bad_offload-on-is_err.patch b/queue-3.18/net-avoid-skb_warn_bad_offload-on-is_err.patch
new file mode 100644 (file)
index 0000000..b935346
--- /dev/null
@@ -0,0 +1,39 @@
+From 8d74e9f88d65af8bb2e095aff506aa6eac755ada Mon Sep 17 00:00:00 2001
+From: Willem de Bruijn <willemb@google.com>
+Date: Tue, 12 Dec 2017 11:39:04 -0500
+Subject: net: avoid skb_warn_bad_offload on IS_ERR
+
+From: Willem de Bruijn <willemb@google.com>
+
+commit 8d74e9f88d65af8bb2e095aff506aa6eac755ada upstream.
+
+skb_warn_bad_offload warns when packets enter the GSO stack that
+require skb_checksum_help or vice versa. Do not warn on arbitrary
+bad packets. Packet sockets can craft many. Syzkaller was able to
+demonstrate another one with eth_type games.
+
+In particular, suppress the warning when segmentation returns an
+error, which is for reasons other than checksum offload.
+
+See also commit 36c92474498a ("net: WARN if skb_checksum_help() is
+called on skb requiring segmentation") for context on this warning.
+
+Signed-off-by: Willem de Bruijn <willemb@google.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ net/core/dev.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/net/core/dev.c
++++ b/net/core/dev.c
+@@ -2478,7 +2478,7 @@ struct sk_buff *__skb_gso_segment(struct
+       segs = skb_mac_gso_segment(skb, features);
+-      if (unlikely(skb_needs_check(skb, tx_path)))
++      if (unlikely(skb_needs_check(skb, tx_path) && !IS_ERR(segs)))
+               skb_warn_bad_offload(skb);
+       return segs;
diff --git a/queue-3.18/netfilter-ipt_clusterip-fix-out-of-bounds-accesses-in-clusterip_tg_check.patch b/queue-3.18/netfilter-ipt_clusterip-fix-out-of-bounds-accesses-in-clusterip_tg_check.patch
new file mode 100644 (file)
index 0000000..c8fc646
--- /dev/null
@@ -0,0 +1,59 @@
+From 1a38956cce5eabd7b74f94bab70265e4df83165e Mon Sep 17 00:00:00 2001
+From: Dmitry Vyukov <dvyukov@google.com>
+Date: Tue, 30 Jan 2018 15:21:34 +0100
+Subject: netfilter: ipt_CLUSTERIP: fix out-of-bounds accesses in clusterip_tg_check()
+
+From: Dmitry Vyukov <dvyukov@google.com>
+
+commit 1a38956cce5eabd7b74f94bab70265e4df83165e upstream.
+
+Commit 136e92bbec0a switched local_nodes from an array to a bitmask
+but did not add proper bounds checks. As the result
+clusterip_config_init_nodelist() can both over-read
+ipt_clusterip_tgt_info.local_nodes and over-write
+clusterip_config.local_nodes.
+
+Add bounds checks for both.
+
+Fixes: 136e92bbec0a ("[NETFILTER] CLUSTERIP: use a bitmap to store node responsibility data")
+Signed-off-by: Dmitry Vyukov <dvyukov@google.com>
+Reported-by: syzbot <syzkaller@googlegroups.com>
+Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ net/ipv4/netfilter/ipt_CLUSTERIP.c |   16 +++++++++++++---
+ 1 file changed, 13 insertions(+), 3 deletions(-)
+
+--- a/net/ipv4/netfilter/ipt_CLUSTERIP.c
++++ b/net/ipv4/netfilter/ipt_CLUSTERIP.c
+@@ -365,7 +365,7 @@ static int clusterip_tg_check(const stru
+       struct ipt_clusterip_tgt_info *cipinfo = par->targinfo;
+       const struct ipt_entry *e = par->entryinfo;
+       struct clusterip_config *config;
+-      int ret;
++      int ret, i;
+       if (cipinfo->hash_mode != CLUSTERIP_HASHMODE_SIP &&
+           cipinfo->hash_mode != CLUSTERIP_HASHMODE_SIP_SPT &&
+@@ -379,8 +379,18 @@ static int clusterip_tg_check(const stru
+               pr_info("Please specify destination IP\n");
+               return -EINVAL;
+       }
+-
+-      /* FIXME: further sanity checks */
++      if (cipinfo->num_local_nodes > ARRAY_SIZE(cipinfo->local_nodes)) {
++              pr_info("bad num_local_nodes %u\n", cipinfo->num_local_nodes);
++              return -EINVAL;
++      }
++      for (i = 0; i < cipinfo->num_local_nodes; i++) {
++              if (cipinfo->local_nodes[i] - 1 >=
++                  sizeof(config->local_nodes) * 8) {
++                      pr_info("bad local_nodes[%d] %u\n",
++                              i, cipinfo->local_nodes[i]);
++                      return -EINVAL;
++              }
++      }
+       config = clusterip_config_find_get(par->net, e->ip.dst.s_addr, 1);
+       if (!config) {
diff --git a/queue-3.18/netfilter-on-sockopt-acquire-sock-lock-only-in-the-required-scope.patch b/queue-3.18/netfilter-on-sockopt-acquire-sock-lock-only-in-the-required-scope.patch
new file mode 100644 (file)
index 0000000..dbf9ddf
--- /dev/null
@@ -0,0 +1,242 @@
+From 3f34cfae1238848fd53f25e5c8fd59da57901f4b Mon Sep 17 00:00:00 2001
+From: Paolo Abeni <pabeni@redhat.com>
+Date: Tue, 30 Jan 2018 19:01:40 +0100
+Subject: netfilter: on sockopt() acquire sock lock only in the required scope
+
+From: Paolo Abeni <pabeni@redhat.com>
+
+commit 3f34cfae1238848fd53f25e5c8fd59da57901f4b upstream.
+
+Syzbot reported several deadlocks in the netfilter area caused by
+rtnl lock and socket lock being acquired with a different order on
+different code paths, leading to backtraces like the following one:
+
+======================================================
+WARNING: possible circular locking dependency detected
+4.15.0-rc9+ #212 Not tainted
+------------------------------------------------------
+syzkaller041579/3682 is trying to acquire lock:
+  (sk_lock-AF_INET6){+.+.}, at: [<000000008775e4dd>] lock_sock
+include/net/sock.h:1463 [inline]
+  (sk_lock-AF_INET6){+.+.}, at: [<000000008775e4dd>]
+do_ipv6_setsockopt.isra.8+0x3c5/0x39d0 net/ipv6/ipv6_sockglue.c:167
+
+but task is already holding lock:
+  (rtnl_mutex){+.+.}, at: [<000000004342eaa9>] rtnl_lock+0x17/0x20
+net/core/rtnetlink.c:74
+
+which lock already depends on the new lock.
+
+the existing dependency chain (in reverse order) is:
+
+-> #1 (rtnl_mutex){+.+.}:
+        __mutex_lock_common kernel/locking/mutex.c:756 [inline]
+        __mutex_lock+0x16f/0x1a80 kernel/locking/mutex.c:893
+        mutex_lock_nested+0x16/0x20 kernel/locking/mutex.c:908
+        rtnl_lock+0x17/0x20 net/core/rtnetlink.c:74
+        register_netdevice_notifier+0xad/0x860 net/core/dev.c:1607
+        tee_tg_check+0x1a0/0x280 net/netfilter/xt_TEE.c:106
+        xt_check_target+0x22c/0x7d0 net/netfilter/x_tables.c:845
+        check_target net/ipv6/netfilter/ip6_tables.c:538 [inline]
+        find_check_entry.isra.7+0x935/0xcf0
+net/ipv6/netfilter/ip6_tables.c:580
+        translate_table+0xf52/0x1690 net/ipv6/netfilter/ip6_tables.c:749
+        do_replace net/ipv6/netfilter/ip6_tables.c:1165 [inline]
+        do_ip6t_set_ctl+0x370/0x5f0 net/ipv6/netfilter/ip6_tables.c:1691
+        nf_sockopt net/netfilter/nf_sockopt.c:106 [inline]
+        nf_setsockopt+0x67/0xc0 net/netfilter/nf_sockopt.c:115
+        ipv6_setsockopt+0x115/0x150 net/ipv6/ipv6_sockglue.c:928
+        udpv6_setsockopt+0x45/0x80 net/ipv6/udp.c:1422
+        sock_common_setsockopt+0x95/0xd0 net/core/sock.c:2978
+        SYSC_setsockopt net/socket.c:1849 [inline]
+        SyS_setsockopt+0x189/0x360 net/socket.c:1828
+        entry_SYSCALL_64_fastpath+0x29/0xa0
+
+-> #0 (sk_lock-AF_INET6){+.+.}:
+        lock_acquire+0x1d5/0x580 kernel/locking/lockdep.c:3914
+        lock_sock_nested+0xc2/0x110 net/core/sock.c:2780
+        lock_sock include/net/sock.h:1463 [inline]
+        do_ipv6_setsockopt.isra.8+0x3c5/0x39d0 net/ipv6/ipv6_sockglue.c:167
+        ipv6_setsockopt+0xd7/0x150 net/ipv6/ipv6_sockglue.c:922
+        udpv6_setsockopt+0x45/0x80 net/ipv6/udp.c:1422
+        sock_common_setsockopt+0x95/0xd0 net/core/sock.c:2978
+        SYSC_setsockopt net/socket.c:1849 [inline]
+        SyS_setsockopt+0x189/0x360 net/socket.c:1828
+        entry_SYSCALL_64_fastpath+0x29/0xa0
+
+other info that might help us debug this:
+
+  Possible unsafe locking scenario:
+
+        CPU0                    CPU1
+        ----                    ----
+   lock(rtnl_mutex);
+                                lock(sk_lock-AF_INET6);
+                                lock(rtnl_mutex);
+   lock(sk_lock-AF_INET6);
+
+  *** DEADLOCK ***
+
+1 lock held by syzkaller041579/3682:
+  #0:  (rtnl_mutex){+.+.}, at: [<000000004342eaa9>] rtnl_lock+0x17/0x20
+net/core/rtnetlink.c:74
+
+The problem, as Florian noted, is that nf_setsockopt() is always
+called with the socket held, even if the lock itself is required only
+for very tight scopes and only for some operation.
+
+This patch addresses the issues moving the lock_sock() call only
+where really needed, namely in ipv*_getorigdst(), so that nf_setsockopt()
+does not need anymore to acquire both locks.
+
+Fixes: 22265a5c3c10 ("netfilter: xt_TEE: resolve oif using netdevice notifiers")
+Reported-by: syzbot+a4c2dc980ac1af699b36@syzkaller.appspotmail.com
+Suggested-by: Florian Westphal <fw@strlen.de>
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ net/ipv4/ip_sockglue.c                         |   14 ++++----------
+ net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c |    6 +++++-
+ net/ipv6/ipv6_sockglue.c                       |   17 +++++------------
+ net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c |   18 ++++++++++++------
+ 4 files changed, 26 insertions(+), 29 deletions(-)
+
+--- a/net/ipv4/ip_sockglue.c
++++ b/net/ipv4/ip_sockglue.c
+@@ -1090,11 +1090,8 @@ int ip_setsockopt(struct sock *sk, int l
+       if (err == -ENOPROTOOPT && optname != IP_HDRINCL &&
+                       optname != IP_IPSEC_POLICY &&
+                       optname != IP_XFRM_POLICY &&
+-                      !ip_mroute_opt(optname)) {
+-              lock_sock(sk);
++                      !ip_mroute_opt(optname))
+               err = nf_setsockopt(sk, PF_INET, optname, optval, optlen);
+-              release_sock(sk);
+-      }
+ #endif
+       return err;
+ }
+@@ -1119,12 +1116,9 @@ int compat_ip_setsockopt(struct sock *sk
+       if (err == -ENOPROTOOPT && optname != IP_HDRINCL &&
+                       optname != IP_IPSEC_POLICY &&
+                       optname != IP_XFRM_POLICY &&
+-                      !ip_mroute_opt(optname)) {
+-              lock_sock(sk);
+-              err = compat_nf_setsockopt(sk, PF_INET, optname,
+-                                         optval, optlen);
+-              release_sock(sk);
+-      }
++                      !ip_mroute_opt(optname))
++              err = compat_nf_setsockopt(sk, PF_INET, optname, optval,
++                                         optlen);
+ #endif
+       return err;
+ }
+--- a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c
++++ b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c
+@@ -269,15 +269,19 @@ getorigdst(struct sock *sk, int optval,
+       struct nf_conntrack_tuple tuple;
+       memset(&tuple, 0, sizeof(tuple));
++
++      lock_sock(sk);
+       tuple.src.u3.ip = inet->inet_rcv_saddr;
+       tuple.src.u.tcp.port = inet->inet_sport;
+       tuple.dst.u3.ip = inet->inet_daddr;
+       tuple.dst.u.tcp.port = inet->inet_dport;
+       tuple.src.l3num = PF_INET;
+       tuple.dst.protonum = sk->sk_protocol;
++      release_sock(sk);
+       /* We only do TCP and SCTP at the moment: is there a better way? */
+-      if (sk->sk_protocol != IPPROTO_TCP && sk->sk_protocol != IPPROTO_SCTP) {
++      if (tuple.dst.protonum != IPPROTO_TCP &&
++          tuple.dst.protonum != IPPROTO_SCTP) {
+               pr_debug("SO_ORIGINAL_DST: Not a TCP/SCTP socket\n");
+               return -ENOPROTOOPT;
+       }
+--- a/net/ipv6/ipv6_sockglue.c
++++ b/net/ipv6/ipv6_sockglue.c
+@@ -875,12 +875,8 @@ int ipv6_setsockopt(struct sock *sk, int
+ #ifdef CONFIG_NETFILTER
+       /* we need to exclude all possible ENOPROTOOPTs except default case */
+       if (err == -ENOPROTOOPT && optname != IPV6_IPSEC_POLICY &&
+-                      optname != IPV6_XFRM_POLICY) {
+-              lock_sock(sk);
+-              err = nf_setsockopt(sk, PF_INET6, optname, optval,
+-                              optlen);
+-              release_sock(sk);
+-      }
++                      optname != IPV6_XFRM_POLICY)
++              err = nf_setsockopt(sk, PF_INET6, optname, optval, optlen);
+ #endif
+       return err;
+ }
+@@ -910,12 +906,9 @@ int compat_ipv6_setsockopt(struct sock *
+ #ifdef CONFIG_NETFILTER
+       /* we need to exclude all possible ENOPROTOOPTs except default case */
+       if (err == -ENOPROTOOPT && optname != IPV6_IPSEC_POLICY &&
+-          optname != IPV6_XFRM_POLICY) {
+-              lock_sock(sk);
+-              err = compat_nf_setsockopt(sk, PF_INET6, optname,
+-                                         optval, optlen);
+-              release_sock(sk);
+-      }
++          optname != IPV6_XFRM_POLICY)
++              err = compat_nf_setsockopt(sk, PF_INET6, optname, optval,
++                                         optlen);
+ #endif
+       return err;
+ }
+--- a/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
++++ b/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
+@@ -240,20 +240,27 @@ static struct nf_hook_ops ipv6_conntrack
+ static int
+ ipv6_getorigdst(struct sock *sk, int optval, void __user *user, int *len)
+ {
+-      const struct inet_sock *inet = inet_sk(sk);
++      struct nf_conntrack_tuple tuple = { .src.l3num = NFPROTO_IPV6 };
+       const struct ipv6_pinfo *inet6 = inet6_sk(sk);
++      const struct inet_sock *inet = inet_sk(sk);
+       const struct nf_conntrack_tuple_hash *h;
+       struct sockaddr_in6 sin6;
+-      struct nf_conntrack_tuple tuple = { .src.l3num = NFPROTO_IPV6 };
+       struct nf_conn *ct;
++      __be32 flow_label;
++      int bound_dev_if;
++      lock_sock(sk);
+       tuple.src.u3.in6 = sk->sk_v6_rcv_saddr;
+       tuple.src.u.tcp.port = inet->inet_sport;
+       tuple.dst.u3.in6 = sk->sk_v6_daddr;
+       tuple.dst.u.tcp.port = inet->inet_dport;
+       tuple.dst.protonum = sk->sk_protocol;
++      bound_dev_if = sk->sk_bound_dev_if;
++      flow_label = inet6->flow_label;
++      release_sock(sk);
+-      if (sk->sk_protocol != IPPROTO_TCP && sk->sk_protocol != IPPROTO_SCTP)
++      if (tuple.dst.protonum != IPPROTO_TCP &&
++          tuple.dst.protonum != IPPROTO_SCTP)
+               return -ENOPROTOOPT;
+       if (*len < 0 || (unsigned int) *len < sizeof(sin6))
+@@ -271,14 +278,13 @@ ipv6_getorigdst(struct sock *sk, int opt
+       sin6.sin6_family = AF_INET6;
+       sin6.sin6_port = ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.u.tcp.port;
+-      sin6.sin6_flowinfo = inet6->flow_label & IPV6_FLOWINFO_MASK;
++      sin6.sin6_flowinfo = flow_label & IPV6_FLOWINFO_MASK;
+       memcpy(&sin6.sin6_addr,
+               &ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.u3.in6,
+                                       sizeof(sin6.sin6_addr));
+       nf_ct_put(ct);
+-      sin6.sin6_scope_id = ipv6_iface_scope_id(&sin6.sin6_addr,
+-                                               sk->sk_bound_dev_if);
++      sin6.sin6_scope_id = ipv6_iface_scope_id(&sin6.sin6_addr, bound_dev_if);
+       return copy_to_user(user, &sin6, sizeof(sin6)) ? -EFAULT : 0;
+ }
diff --git a/queue-3.18/netfilter-x_tables-avoid-out-of-bounds-reads-in-xt_request_find_-match-target.patch b/queue-3.18/netfilter-x_tables-avoid-out-of-bounds-reads-in-xt_request_find_-match-target.patch
new file mode 100644 (file)
index 0000000..01a99c1
--- /dev/null
@@ -0,0 +1,51 @@
+From da17c73b6eb74aad3c3c0654394635675b623b3e Mon Sep 17 00:00:00 2001
+From: Eric Dumazet <edumazet@google.com>
+Date: Wed, 24 Jan 2018 17:16:09 -0800
+Subject: netfilter: x_tables: avoid out-of-bounds reads in xt_request_find_{match|target}
+
+From: Eric Dumazet <edumazet@google.com>
+
+commit da17c73b6eb74aad3c3c0654394635675b623b3e upstream.
+
+It looks like syzbot found its way into netfilter territory.
+
+Issue here is that @name comes from user space and might
+not be null terminated.
+
+Out-of-bound reads happen, KASAN is not happy.
+
+v2 added similar fix for xt_request_find_target(),
+as Florian advised.
+
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Reported-by: syzbot <syzkaller@googlegroups.com>
+Acked-by: Florian Westphal <fw@strlen.de>
+Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ net/netfilter/x_tables.c |    6 ++++++
+ 1 file changed, 6 insertions(+)
+
+--- a/net/netfilter/x_tables.c
++++ b/net/netfilter/x_tables.c
+@@ -209,6 +209,9 @@ xt_request_find_match(uint8_t nfproto, c
+ {
+       struct xt_match *match;
++      if (strnlen(name, XT_EXTENSION_MAXNAMELEN) == XT_EXTENSION_MAXNAMELEN)
++              return ERR_PTR(-EINVAL);
++
+       match = xt_find_match(nfproto, name, revision);
+       if (IS_ERR(match)) {
+               request_module("%st_%s", xt_prefix[nfproto], name);
+@@ -251,6 +254,9 @@ struct xt_target *xt_request_find_target
+ {
+       struct xt_target *target;
++      if (strnlen(name, XT_EXTENSION_MAXNAMELEN) == XT_EXTENSION_MAXNAMELEN)
++              return ERR_PTR(-EINVAL);
++
+       target = xt_find_target(af, name, revision);
+       if (IS_ERR(target)) {
+               request_module("%st_%s", xt_prefix[af], name);
diff --git a/queue-3.18/netfilter-x_tables-fix-int-overflow-in-xt_alloc_table_info.patch b/queue-3.18/netfilter-x_tables-fix-int-overflow-in-xt_alloc_table_info.patch
new file mode 100644 (file)
index 0000000..f07d526
--- /dev/null
@@ -0,0 +1,45 @@
+From 889c604fd0b5f6d3b8694ade229ee44124de1127 Mon Sep 17 00:00:00 2001
+From: Dmitry Vyukov <dvyukov@google.com>
+Date: Thu, 28 Dec 2017 09:48:54 +0100
+Subject: netfilter: x_tables: fix int overflow in xt_alloc_table_info()
+
+From: Dmitry Vyukov <dvyukov@google.com>
+
+commit 889c604fd0b5f6d3b8694ade229ee44124de1127 upstream.
+
+syzkaller triggered OOM kills by passing ipt_replace.size = -1
+to IPT_SO_SET_REPLACE. The root cause is that SMP_ALIGN() in
+xt_alloc_table_info() causes int overflow and the size check passes
+when it should not. SMP_ALIGN() is no longer needed leftover.
+
+Remove SMP_ALIGN() call in xt_alloc_table_info().
+
+Reported-by: syzbot+4396883fa8c4f64e0175@syzkaller.appspotmail.com
+Signed-off-by: Dmitry Vyukov <dvyukov@google.com>
+Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ net/netfilter/x_tables.c |    4 +---
+ 1 file changed, 1 insertion(+), 3 deletions(-)
+
+--- a/net/netfilter/x_tables.c
++++ b/net/netfilter/x_tables.c
+@@ -38,8 +38,6 @@ MODULE_LICENSE("GPL");
+ MODULE_AUTHOR("Harald Welte <laforge@netfilter.org>");
+ MODULE_DESCRIPTION("{ip,ip6,arp,eb}_tables backend module");
+-#define SMP_ALIGN(x) (((x) + SMP_CACHE_BYTES-1) & ~(SMP_CACHE_BYTES-1))
+-
+ struct compat_delta {
+       unsigned int offset; /* offset in kernel */
+       int delta; /* delta in 32bit user land */
+@@ -951,7 +949,7 @@ struct xt_table_info *xt_alloc_table_inf
+       int cpu;
+       /* Pedantry: prevent them from hitting BUG() in vmalloc.c --RR */
+-      if ((SMP_ALIGN(size) >> PAGE_SHIFT) + 2 > totalram_pages)
++      if ((size >> PAGE_SHIFT) + 2 > totalram_pages)
+               return NULL;
+       newinfo = kzalloc(XT_TABLE_INFO_SZ, GFP_KERNEL);
diff --git a/queue-3.18/netfilter-xt_rateest-acquire-xt_rateest_mutex-for-hash-insert.patch b/queue-3.18/netfilter-xt_rateest-acquire-xt_rateest_mutex-for-hash-insert.patch
new file mode 100644 (file)
index 0000000..3273a19
--- /dev/null
@@ -0,0 +1,92 @@
+From 7dc68e98757a8eccf8ca7a53a29b896f1eef1f76 Mon Sep 17 00:00:00 2001
+From: Cong Wang <xiyou.wangcong@gmail.com>
+Date: Mon, 5 Feb 2018 14:41:45 -0800
+Subject: netfilter: xt_RATEEST: acquire xt_rateest_mutex for hash insert
+
+From: Cong Wang <xiyou.wangcong@gmail.com>
+
+commit 7dc68e98757a8eccf8ca7a53a29b896f1eef1f76 upstream.
+
+rateest_hash is supposed to be protected by xt_rateest_mutex,
+and, as suggested by Eric, lookup and insert should be atomic,
+so we should acquire the xt_rateest_mutex once for both.
+
+So introduce a non-locking helper for internal use and keep the
+locking one for external.
+
+Reported-by: <syzbot+5cb189720978275e4c75@syzkaller.appspotmail.com>
+Fixes: 5859034d7eb8 ("[NETFILTER]: x_tables: add RATEEST target")
+Signed-off-by: Cong Wang <xiyou.wangcong@gmail.com>
+Reviewed-by: Florian Westphal <fw@strlen.de>
+Reviewed-by: Eric Dumazet <edumazet@google.com>
+Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ net/netfilter/xt_RATEEST.c |   22 +++++++++++++++++-----
+ 1 file changed, 17 insertions(+), 5 deletions(-)
+
+--- a/net/netfilter/xt_RATEEST.c
++++ b/net/netfilter/xt_RATEEST.c
+@@ -40,23 +40,31 @@ static void xt_rateest_hash_insert(struc
+       hlist_add_head(&est->list, &rateest_hash[h]);
+ }
+-struct xt_rateest *xt_rateest_lookup(const char *name)
++static struct xt_rateest *__xt_rateest_lookup(const char *name)
+ {
+       struct xt_rateest *est;
+       unsigned int h;
+       h = xt_rateest_hash(name);
+-      mutex_lock(&xt_rateest_mutex);
+       hlist_for_each_entry(est, &rateest_hash[h], list) {
+               if (strcmp(est->name, name) == 0) {
+                       est->refcnt++;
+-                      mutex_unlock(&xt_rateest_mutex);
+                       return est;
+               }
+       }
+-      mutex_unlock(&xt_rateest_mutex);
++
+       return NULL;
+ }
++
++struct xt_rateest *xt_rateest_lookup(const char *name)
++{
++      struct xt_rateest *est;
++
++      mutex_lock(&xt_rateest_mutex);
++      est = __xt_rateest_lookup(name);
++      mutex_unlock(&xt_rateest_mutex);
++      return est;
++}
+ EXPORT_SYMBOL_GPL(xt_rateest_lookup);
+ void xt_rateest_put(struct xt_rateest *est)
+@@ -104,8 +112,10 @@ static int xt_rateest_tg_checkentry(cons
+               rnd_inited = true;
+       }
+-      est = xt_rateest_lookup(info->name);
++      mutex_lock(&xt_rateest_mutex);
++      est = __xt_rateest_lookup(info->name);
+       if (est) {
++              mutex_unlock(&xt_rateest_mutex);
+               /*
+                * If estimator parameters are specified, they must match the
+                * existing estimator.
+@@ -143,11 +153,13 @@ static int xt_rateest_tg_checkentry(cons
+       info->est = est;
+       xt_rateest_hash_insert(est);
++      mutex_unlock(&xt_rateest_mutex);
+       return 0;
+ err2:
+       kfree(est);
+ err1:
++      mutex_unlock(&xt_rateest_mutex);
+       return ret;
+ }
diff --git a/queue-3.18/provide-a-function-to-create-a-nul-terminated-string-from-unterminated-data.patch b/queue-3.18/provide-a-function-to-create-a-nul-terminated-string-from-unterminated-data.patch
new file mode 100644 (file)
index 0000000..3198541
--- /dev/null
@@ -0,0 +1,74 @@
+From f35157417215ec138c920320c746fdb3e04ef1d5 Mon Sep 17 00:00:00 2001
+From: David Howells <dhowells@redhat.com>
+Date: Tue, 4 Jul 2017 17:25:02 +0100
+Subject: Provide a function to create a NUL-terminated string from unterminated data
+
+From: David Howells <dhowells@redhat.com>
+
+commit f35157417215ec138c920320c746fdb3e04ef1d5 upstream.
+
+Provide a function, kmemdup_nul(), that will create a NUL-terminated string
+from an unterminated character array where the length is known in advance.
+
+This is better than kstrndup() in situations where we already know the
+string length as the strnlen() in kstrndup() is superfluous.
+
+Signed-off-by: David Howells <dhowells@redhat.com>
+Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ include/linux/string.h |    1 +
+ mm/util.c              |   24 ++++++++++++++++++++++++
+ 2 files changed, 25 insertions(+)
+
+--- a/include/linux/string.h
++++ b/include/linux/string.h
+@@ -121,6 +121,7 @@ void *memchr_inv(const void *s, int c, s
+ extern char *kstrdup(const char *s, gfp_t gfp);
+ extern char *kstrndup(const char *s, size_t len, gfp_t gfp);
+ extern void *kmemdup(const void *src, size_t len, gfp_t gfp);
++extern char *kmemdup_nul(const char *s, size_t len, gfp_t gfp);
+ extern char **argv_split(gfp_t gfp, const char *str, int *argcp);
+ extern void argv_free(char **argv);
+--- a/mm/util.c
++++ b/mm/util.c
+@@ -42,6 +42,8 @@ EXPORT_SYMBOL(kstrdup);
+  * @s: the string to duplicate
+  * @max: read at most @max chars from @s
+  * @gfp: the GFP mask used in the kmalloc() call when allocating memory
++ *
++ * Note: Use kmemdup_nul() instead if the size is known exactly.
+  */
+ char *kstrndup(const char *s, size_t max, gfp_t gfp)
+ {
+@@ -80,6 +82,28 @@ void *kmemdup(const void *src, size_t le
+ EXPORT_SYMBOL(kmemdup);
+ /**
++ * kmemdup_nul - Create a NUL-terminated string from unterminated data
++ * @s: The data to stringify
++ * @len: The size of the data
++ * @gfp: the GFP mask used in the kmalloc() call when allocating memory
++ */
++char *kmemdup_nul(const char *s, size_t len, gfp_t gfp)
++{
++      char *buf;
++
++      if (!s)
++              return NULL;
++
++      buf = kmalloc_track_caller(len + 1, gfp);
++      if (buf) {
++              memcpy(buf, s, len);
++              buf[len] = '\0';
++      }
++      return buf;
++}
++EXPORT_SYMBOL(kmemdup_nul);
++
++/**
+  * memdup_user - duplicate memory region from user space
+  *
+  * @src: source address in user space
diff --git a/queue-3.18/selinux-ensure-the-context-is-nul-terminated-in-security_context_to_sid_core.patch b/queue-3.18/selinux-ensure-the-context-is-nul-terminated-in-security_context_to_sid_core.patch
new file mode 100644 (file)
index 0000000..e3ca1be
--- /dev/null
@@ -0,0 +1,67 @@
+From ef28df55ac27e1e5cd122e19fa311d886d47a756 Mon Sep 17 00:00:00 2001
+From: Paul Moore <paul@paul-moore.com>
+Date: Tue, 28 Nov 2017 18:51:12 -0500
+Subject: selinux: ensure the context is NUL terminated in security_context_to_sid_core()
+
+From: Paul Moore <paul@paul-moore.com>
+
+commit ef28df55ac27e1e5cd122e19fa311d886d47a756 upstream.
+
+The syzbot/syzkaller automated tests found a problem in
+security_context_to_sid_core() during early boot (before we load the
+SELinux policy) where we could potentially feed context strings without
+NUL terminators into the strcmp() function.
+
+We already guard against this during normal operation (after the SELinux
+policy has been loaded) by making a copy of the context strings and
+explicitly adding a NUL terminator to the end.  The patch extends this
+protection to the early boot case (no loaded policy) by moving the context
+copy earlier in security_context_to_sid_core().
+
+Reported-by: syzbot <syzkaller@googlegroups.com>
+Signed-off-by: Paul Moore <paul@paul-moore.com>
+Reviewed-By: William Roberts <william.c.roberts@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ security/selinux/ss/services.c |   18 ++++++++----------
+ 1 file changed, 8 insertions(+), 10 deletions(-)
+
+--- a/security/selinux/ss/services.c
++++ b/security/selinux/ss/services.c
+@@ -1239,27 +1239,25 @@ static int security_context_to_sid_core(
+       if (!scontext_len)
+               return -EINVAL;
++      /* Copy the string to allow changes and ensure a NUL terminator */
++      scontext2 = kmemdup_nul(scontext, scontext_len, gfp_flags);
++      if (!scontext2)
++              return -ENOMEM;
++
+       if (!ss_initialized) {
+               int i;
+               for (i = 1; i < SECINITSID_NUM; i++) {
+-                      if (!strcmp(initial_sid_to_string[i], scontext)) {
++                      if (!strcmp(initial_sid_to_string[i], scontext2)) {
+                               *sid = i;
+-                              return 0;
++                              goto out;
+                       }
+               }
+               *sid = SECINITSID_KERNEL;
+-              return 0;
++              goto out;
+       }
+       *sid = SECSID_NULL;
+-      /* Copy the string so that we can modify the copy as we parse it. */
+-      scontext2 = kmalloc(scontext_len + 1, gfp_flags);
+-      if (!scontext2)
+-              return -ENOMEM;
+-      memcpy(scontext2, scontext, scontext_len);
+-      scontext2[scontext_len] = 0;
+-
+       if (force) {
+               /* Save another copy for storing in uninterpreted form */
+               rc = -ENOMEM;
diff --git a/queue-3.18/selinux-skip-bounded-transition-processing-if-the-policy-isn-t-loaded.patch b/queue-3.18/selinux-skip-bounded-transition-processing-if-the-policy-isn-t-loaded.patch
new file mode 100644 (file)
index 0000000..77f56ad
--- /dev/null
@@ -0,0 +1,38 @@
+From 4b14752ec4e0d87126e636384cf37c8dd9df157c Mon Sep 17 00:00:00 2001
+From: Paul Moore <paul@paul-moore.com>
+Date: Tue, 5 Dec 2017 17:17:43 -0500
+Subject: selinux: skip bounded transition processing if the policy isn't loaded
+
+From: Paul Moore <paul@paul-moore.com>
+
+commit 4b14752ec4e0d87126e636384cf37c8dd9df157c upstream.
+
+We can't do anything reasonable in security_bounded_transition() if we
+don't have a policy loaded, and in fact we could run into problems
+with some of the code inside expecting a policy.  Fix these problems
+like we do many others in security/selinux/ss/services.c by checking
+to see if the policy is loaded (ss_initialized) and returning quickly
+if it isn't.
+
+Reported-by: syzbot <syzkaller-bugs@googlegroups.com>
+Signed-off-by: Paul Moore <paul@paul-moore.com>
+Acked-by: Stephen Smalley <sds@tycho.nsa.gov>
+Reviewed-by: James Morris <james.l.morris@oracle.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ security/selinux/ss/services.c |    3 +++
+ 1 file changed, 3 insertions(+)
+
+--- a/security/selinux/ss/services.c
++++ b/security/selinux/ss/services.c
+@@ -823,6 +823,9 @@ int security_bounded_transition(u32 old_
+       int index;
+       int rc;
++      if (!ss_initialized)
++              return 0;
++
+       read_lock(&policy_rwlock);
+       rc = -EINVAL;
index ca502ed5623e208e94c3f6a87fe853988aed276a..a691e3f8e28c2294e81d3d538cf03d6f724b70bf 100644 (file)
@@ -15,3 +15,16 @@ btrfs-fix-crash-due-to-not-cleaning-up-tree-log-block-s-dirty-bits.patch
 alsa-seq-fix-racy-pool-initializations.patch
 arm-dts-s5pv210-add-interrupt-parent-for-ohci.patch
 media-r820t-fix-r820t_write_reg-for-kasan.patch
+mm-vmscan-make-unregister_shrinker-no-op-if-register_shrinker-failed.patch
+xfrm-check-id-proto-in-validate_tmpl.patch
+selinux-skip-bounded-transition-processing-if-the-policy-isn-t-loaded.patch
+crypto-x86-twofish-3way-fix-rbp-usage.patch
+staging-android-ion-add-__gfp_nowarn-for-system-contig-heap.patch
+netfilter-x_tables-fix-int-overflow-in-xt_alloc_table_info.patch
+netfilter-x_tables-avoid-out-of-bounds-reads-in-xt_request_find_-match-target.patch
+netfilter-ipt_clusterip-fix-out-of-bounds-accesses-in-clusterip_tg_check.patch
+netfilter-on-sockopt-acquire-sock-lock-only-in-the-required-scope.patch
+netfilter-xt_rateest-acquire-xt_rateest_mutex-for-hash-insert.patch
+net-avoid-skb_warn_bad_offload-on-is_err.patch
+provide-a-function-to-create-a-nul-terminated-string-from-unterminated-data.patch
+selinux-ensure-the-context-is-nul-terminated-in-security_context_to_sid_core.patch
diff --git a/queue-3.18/staging-android-ion-add-__gfp_nowarn-for-system-contig-heap.patch b/queue-3.18/staging-android-ion-add-__gfp_nowarn-for-system-contig-heap.patch
new file mode 100644 (file)
index 0000000..0cbb6eb
--- /dev/null
@@ -0,0 +1,53 @@
+From 0c75f10312a35b149b2cebb1832316b35c2337ca Mon Sep 17 00:00:00 2001
+From: Laura Abbott <labbott@redhat.com>
+Date: Fri, 5 Jan 2018 11:14:08 -0800
+Subject: staging: android: ion: Add __GFP_NOWARN for system contig heap
+
+From: Laura Abbott <labbott@redhat.com>
+
+commit 0c75f10312a35b149b2cebb1832316b35c2337ca upstream.
+
+syzbot reported a warning from Ion:
+
+  WARNING: CPU: 1 PID: 3485 at mm/page_alloc.c:3926
+
+  ...
+   __alloc_pages_nodemask+0x9fb/0xd80 mm/page_alloc.c:4252
+  alloc_pages_current+0xb6/0x1e0 mm/mempolicy.c:2036
+  alloc_pages include/linux/gfp.h:492 [inline]
+  ion_system_contig_heap_allocate+0x40/0x2c0
+  drivers/staging/android/ion/ion_system_heap.c:374
+  ion_buffer_create drivers/staging/android/ion/ion.c:93 [inline]
+  ion_alloc+0x2c1/0x9e0 drivers/staging/android/ion/ion.c:420
+  ion_ioctl+0x26d/0x380 drivers/staging/android/ion/ion-ioctl.c:84
+  vfs_ioctl fs/ioctl.c:46 [inline]
+  do_vfs_ioctl+0x1b1/0x1520 fs/ioctl.c:686
+  SYSC_ioctl fs/ioctl.c:701 [inline]
+  SyS_ioctl+0x8f/0xc0 fs/ioctl.c:692
+
+This is a warning about attempting to allocate order > MAX_ORDER. This
+is coming from a userspace Ion allocation request. Since userspace is
+free to request however much memory it wants (and the kernel is free to
+deny its allocation), silence the allocation attempt with __GFP_NOWARN
+in case it fails.
+
+Reported-by: syzbot+76e7efc4748495855a4d@syzkaller.appspotmail.com
+Reported-by: syzbot <syzkaller@googlegroups.com>
+Signed-off-by: Laura Abbott <labbott@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/staging/android/ion/ion_system_heap.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/staging/android/ion/ion_system_heap.c
++++ b/drivers/staging/android/ion/ion_system_heap.c
+@@ -321,7 +321,7 @@ static int ion_system_contig_heap_alloca
+       if (align > (PAGE_SIZE << order))
+               return -EINVAL;
+-      page = alloc_pages(low_order_gfp_flags, order);
++      page = alloc_pages(low_order_gfp_flags | __GFP_NOWARN, order);
+       if (!page)
+               return -ENOMEM;
diff --git a/queue-3.18/xfrm-check-id-proto-in-validate_tmpl.patch b/queue-3.18/xfrm-check-id-proto-in-validate_tmpl.patch
new file mode 100644 (file)
index 0000000..18a6a02
--- /dev/null
@@ -0,0 +1,57 @@
+From 6a53b7593233ab9e4f96873ebacc0f653a55c3e1 Mon Sep 17 00:00:00 2001
+From: Cong Wang <xiyou.wangcong@gmail.com>
+Date: Mon, 27 Nov 2017 11:15:16 -0800
+Subject: xfrm: check id proto in validate_tmpl()
+
+From: Cong Wang <xiyou.wangcong@gmail.com>
+
+commit 6a53b7593233ab9e4f96873ebacc0f653a55c3e1 upstream.
+
+syzbot reported a kernel warning in xfrm_state_fini(), which
+indicates that we have entries left in the list
+net->xfrm.state_all whose proto is zero. And
+xfrm_id_proto_match() doesn't consider them as a match with
+IPSEC_PROTO_ANY in this case.
+
+Proto with value 0 is probably not a valid value, at least
+verify_newsa_info() doesn't consider it valid either.
+
+This patch fixes it by checking the proto value in
+validate_tmpl() and rejecting invalid ones, like what iproute2
+does in xfrm_xfrmproto_getbyname().
+
+Reported-by: syzbot <syzkaller@googlegroups.com>
+Cc: Steffen Klassert <steffen.klassert@secunet.com>
+Cc: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Cong Wang <xiyou.wangcong@gmail.com>
+Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ net/xfrm/xfrm_user.c |   15 +++++++++++++++
+ 1 file changed, 15 insertions(+)
+
+--- a/net/xfrm/xfrm_user.c
++++ b/net/xfrm/xfrm_user.c
+@@ -1375,6 +1375,21 @@ static int validate_tmpl(int nr, struct
+               default:
+                       return -EINVAL;
+               }
++
++              switch (ut[i].id.proto) {
++              case IPPROTO_AH:
++              case IPPROTO_ESP:
++              case IPPROTO_COMP:
++#if IS_ENABLED(CONFIG_IPV6)
++              case IPPROTO_ROUTING:
++              case IPPROTO_DSTOPTS:
++#endif
++              case IPSEC_PROTO_ANY:
++                      break;
++              default:
++                      return -EINVAL;
++              }
++
+       }
+       return 0;