From 20a749d7ddda2711d542862e93516cfbc7b7c263 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Thu, 22 Feb 2018 21:30:31 +0100 Subject: [PATCH] 4.15-stable patches added patches: blk_rq_map_user_iov-fix-error-override.patch crypto-x86-twofish-3way-fix-rbp-usage.patch kcov-detect-double-association-with-a-single-task.patch kvm-x86-fix-escape-of-guest-dr6-to-the-host.patch media-pvrusb2-properly-check-endpoint-types.patch net-avoid-skb_warn_bad_offload-on-is_err.patch net_sched-gen_estimator-fix-lockdep-splat.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_cgroup-initialize-info-priv-in-cgroup_mt_check_v1.patch netfilter-xt_rateest-acquire-xt_rateest_mutex-for-hash-insert.patch ptr_ring-fail-early-if-queue-occupies-more-than-kmalloc_max_size.patch ptr_ring-try-vmalloc-when-kmalloc-fails.patch rds-tcp-atomically-purge-entries-from-rds_tcp_conn_list-during-netns-delete.patch rds-tcp-correctly-sequence-cleanup-on-netns-deletion.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 staging-android-ion-switch-from-warn-to-pr_warn.patch tun-fix-tun_napi_alloc_frags-frag-allocator.patch --- ...k_rq_map_user_iov-fix-error-override.patch | 46 ++++ ...rypto-x86-twofish-3way-fix-rbp-usage.patch | 260 ++++++++++++++++++ ...ouble-association-with-a-single-task.patch | 51 ++++ ...-fix-escape-of-guest-dr6-to-the-host.patch | 68 +++++ ...vrusb2-properly-check-endpoint-types.patch | 82 ++++++ ...avoid-skb_warn_bad_offload-on-is_err.patch | 39 +++ ...ched-gen_estimator-fix-lockdep-splat.patch | 47 ++++ ...ounds-accesses-in-clusterip_tg_check.patch | 59 ++++ ...sock-lock-only-in-the-required-scope.patch | 242 ++++++++++++++++ ...ads-in-xt_request_find_-match-target.patch | 51 ++++ ...-int-overflow-in-xt_alloc_table_info.patch | 44 +++ ...lize-info-priv-in-cgroup_mt_check_v1.patch | 33 +++ ...ire-xt_rateest_mutex-for-hash-insert.patch | 92 +++++++ ...-occupies-more-than-kmalloc_max_size.patch | 34 +++ ..._ring-try-vmalloc-when-kmalloc-fails.patch | 77 ++++++ ...ds_tcp_conn_list-during-netns-delete.patch | 71 +++++ ...y-sequence-cleanup-on-netns-deletion.patch | 122 ++++++++ ...ated-in-security_context_to_sid_core.patch | 67 +++++ ...rocessing-if-the-policy-isn-t-loaded.patch | 38 +++ queue-4.15/series | 22 ++ ...-__gfp_nowarn-for-system-contig-heap.patch | 53 ++++ ...roid-ion-switch-from-warn-to-pr_warn.patch | 42 +++ ...-tun_napi_alloc_frags-frag-allocator.patch | 85 ++++++ 23 files changed, 1725 insertions(+) create mode 100644 queue-4.15/blk_rq_map_user_iov-fix-error-override.patch create mode 100644 queue-4.15/crypto-x86-twofish-3way-fix-rbp-usage.patch create mode 100644 queue-4.15/kcov-detect-double-association-with-a-single-task.patch create mode 100644 queue-4.15/kvm-x86-fix-escape-of-guest-dr6-to-the-host.patch create mode 100644 queue-4.15/media-pvrusb2-properly-check-endpoint-types.patch create mode 100644 queue-4.15/net-avoid-skb_warn_bad_offload-on-is_err.patch create mode 100644 queue-4.15/net_sched-gen_estimator-fix-lockdep-splat.patch create mode 100644 queue-4.15/netfilter-ipt_clusterip-fix-out-of-bounds-accesses-in-clusterip_tg_check.patch create mode 100644 queue-4.15/netfilter-on-sockopt-acquire-sock-lock-only-in-the-required-scope.patch create mode 100644 queue-4.15/netfilter-x_tables-avoid-out-of-bounds-reads-in-xt_request_find_-match-target.patch create mode 100644 queue-4.15/netfilter-x_tables-fix-int-overflow-in-xt_alloc_table_info.patch create mode 100644 queue-4.15/netfilter-xt_cgroup-initialize-info-priv-in-cgroup_mt_check_v1.patch create mode 100644 queue-4.15/netfilter-xt_rateest-acquire-xt_rateest_mutex-for-hash-insert.patch create mode 100644 queue-4.15/ptr_ring-fail-early-if-queue-occupies-more-than-kmalloc_max_size.patch create mode 100644 queue-4.15/ptr_ring-try-vmalloc-when-kmalloc-fails.patch create mode 100644 queue-4.15/rds-tcp-atomically-purge-entries-from-rds_tcp_conn_list-during-netns-delete.patch create mode 100644 queue-4.15/rds-tcp-correctly-sequence-cleanup-on-netns-deletion.patch create mode 100644 queue-4.15/selinux-ensure-the-context-is-nul-terminated-in-security_context_to_sid_core.patch create mode 100644 queue-4.15/selinux-skip-bounded-transition-processing-if-the-policy-isn-t-loaded.patch create mode 100644 queue-4.15/series create mode 100644 queue-4.15/staging-android-ion-add-__gfp_nowarn-for-system-contig-heap.patch create mode 100644 queue-4.15/staging-android-ion-switch-from-warn-to-pr_warn.patch create mode 100644 queue-4.15/tun-fix-tun_napi_alloc_frags-frag-allocator.patch diff --git a/queue-4.15/blk_rq_map_user_iov-fix-error-override.patch b/queue-4.15/blk_rq_map_user_iov-fix-error-override.patch new file mode 100644 index 00000000000..9072daa21e0 --- /dev/null +++ b/queue-4.15/blk_rq_map_user_iov-fix-error-override.patch @@ -0,0 +1,46 @@ +From 69e0927b3774563c19b5fb32e91d75edc147fb62 Mon Sep 17 00:00:00 2001 +From: Douglas Gilbert +Date: Sun, 14 Jan 2018 17:00:48 -0500 +Subject: blk_rq_map_user_iov: fix error override + +From: Douglas Gilbert + +commit 69e0927b3774563c19b5fb32e91d75edc147fb62 upstream. + +During stress tests by syzkaller on the sg driver the block layer +infrequently returns EINVAL. Closer inspection shows the block +layer was trying to return ENOMEM (which is much more +understandable) but for some reason overroad that useful error. + +Patch below does not show this (unchanged) line: + ret =__blk_rq_map_user_iov(rq, map_data, &i, gfp_mask, copy); +That 'ret' was being overridden when that function failed. + +Signed-off-by: Douglas Gilbert +Signed-off-by: Jens Axboe +Signed-off-by: Greg Kroah-Hartman + +--- + block/blk-map.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/block/blk-map.c ++++ b/block/blk-map.c +@@ -119,7 +119,7 @@ int blk_rq_map_user_iov(struct request_q + unsigned long align = q->dma_pad_mask | queue_dma_alignment(q); + struct bio *bio = NULL; + struct iov_iter i; +- int ret; ++ int ret = -EINVAL; + + if (!iter_is_iovec(iter)) + goto fail; +@@ -148,7 +148,7 @@ unmap_rq: + __blk_rq_unmap_user(bio); + fail: + rq->bio = NULL; +- return -EINVAL; ++ return ret; + } + EXPORT_SYMBOL(blk_rq_map_user_iov); + diff --git a/queue-4.15/crypto-x86-twofish-3way-fix-rbp-usage.patch b/queue-4.15/crypto-x86-twofish-3way-fix-rbp-usage.patch new file mode 100644 index 00000000000..f8b333a831e --- /dev/null +++ b/queue-4.15/crypto-x86-twofish-3way-fix-rbp-usage.patch @@ -0,0 +1,260 @@ +From d8c7fe9f2a486a6e5f0d5229ca43807af5ab22c6 Mon Sep 17 00:00:00 2001 +From: Eric Biggers +Date: Mon, 18 Dec 2017 16:40:26 -0800 +Subject: crypto: x86/twofish-3way - Fix %rbp usage + +From: Eric Biggers + +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 +Signed-off-by: Eric Biggers +Reviewed-by: Josh Poimboeuf +Signed-off-by: Herbert Xu +Signed-off-by: Greg Kroah-Hartman + +--- + 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-4.15/kcov-detect-double-association-with-a-single-task.patch b/queue-4.15/kcov-detect-double-association-with-a-single-task.patch new file mode 100644 index 00000000000..6f4cc549b79 --- /dev/null +++ b/queue-4.15/kcov-detect-double-association-with-a-single-task.patch @@ -0,0 +1,51 @@ +From a77660d231f8b3d84fd23ed482e0964f7aa546d6 Mon Sep 17 00:00:00 2001 +From: Dmitry Vyukov +Date: Tue, 6 Feb 2018 15:40:28 -0800 +Subject: kcov: detect double association with a single task + +From: Dmitry Vyukov + +commit a77660d231f8b3d84fd23ed482e0964f7aa546d6 upstream. + +Currently KCOV_ENABLE does not check if the current task is already +associated with another kcov descriptor. As the result it is possible +to associate a single task with more than one kcov descriptor, which +later leads to a memory leak of the old descriptor. This relation is +really meant to be one-to-one (task has only one back link). + +Extend validation to detect such misuse. + +Link: http://lkml.kernel.org/r/20180122082520.15716-1-dvyukov@google.com +Fixes: 5c9a8750a640 ("kernel: add kcov code coverage") +Signed-off-by: Dmitry Vyukov +Reported-by: Shankara Pailoor +Cc: Dmitry Vyukov +Cc: syzbot +Signed-off-by: Andrew Morton +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- + kernel/kcov.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/kernel/kcov.c ++++ b/kernel/kcov.c +@@ -358,7 +358,8 @@ static int kcov_ioctl_locked(struct kcov + */ + if (kcov->mode != KCOV_MODE_INIT || !kcov->area) + return -EINVAL; +- if (kcov->t != NULL) ++ t = current; ++ if (kcov->t != NULL || t->kcov != NULL) + return -EBUSY; + if (arg == KCOV_TRACE_PC) + kcov->mode = KCOV_MODE_TRACE_PC; +@@ -370,7 +371,6 @@ static int kcov_ioctl_locked(struct kcov + #endif + else + return -EINVAL; +- t = current; + /* Cache in task struct for performance. */ + t->kcov_size = kcov->size; + t->kcov_area = kcov->area; diff --git a/queue-4.15/kvm-x86-fix-escape-of-guest-dr6-to-the-host.patch b/queue-4.15/kvm-x86-fix-escape-of-guest-dr6-to-the-host.patch new file mode 100644 index 00000000000..208ff94a6ae --- /dev/null +++ b/queue-4.15/kvm-x86-fix-escape-of-guest-dr6-to-the-host.patch @@ -0,0 +1,68 @@ +From efdab992813fb2ed825745625b83c05032e9cda2 Mon Sep 17 00:00:00 2001 +From: Wanpeng Li +Date: Wed, 13 Dec 2017 10:46:40 +0100 +Subject: KVM: x86: fix escape of guest dr6 to the host +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Wanpeng Li + +commit efdab992813fb2ed825745625b83c05032e9cda2 upstream. + +syzkaller reported: + + WARNING: CPU: 0 PID: 12927 at arch/x86/kernel/traps.c:780 do_debug+0x222/0x250 + CPU: 0 PID: 12927 Comm: syz-executor Tainted: G OE 4.15.0-rc2+ #16 + RIP: 0010:do_debug+0x222/0x250 + Call Trace: + <#DB> + debug+0x3e/0x70 + RIP: 0010:copy_user_enhanced_fast_string+0x10/0x20 + + _copy_from_user+0x5b/0x90 + SyS_timer_create+0x33/0x80 + entry_SYSCALL_64_fastpath+0x23/0x9a + +The testcase sets a watchpoint (with perf_event_open) on a buffer that is +passed to timer_create() as the struct sigevent argument. In timer_create(), +copy_from_user()'s rep movsb triggers the BP. The testcase also sets +the debug registers for the guest. + +However, KVM only restores host debug registers when the host has active +watchpoints, which triggers a race condition when running the testcase with +multiple threads. The guest's DR6.BS bit can escape to the host before +another thread invokes timer_create(), and do_debug() complains. + +The fix is to respect do_debug()'s dr6 invariant when leaving KVM. + +Reported-by: Dmitry Vyukov +Cc: Paolo Bonzini +Cc: Radim Krčmář +Cc: David Hildenbrand +Cc: Dmitry Vyukov +Reviewed-by: David Hildenbrand +Signed-off-by: Wanpeng Li +Signed-off-by: Paolo Bonzini +Signed-off-by: Radim Krčmář +Signed-off-by: Greg Kroah-Hartman + +--- + arch/x86/kvm/x86.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +--- a/arch/x86/kvm/x86.c ++++ b/arch/x86/kvm/x86.c +@@ -2939,6 +2939,12 @@ void kvm_arch_vcpu_put(struct kvm_vcpu * + pagefault_enable(); + kvm_x86_ops->vcpu_put(vcpu); + vcpu->arch.last_host_tsc = rdtsc(); ++ /* ++ * If userspace has set any breakpoints or watchpoints, dr6 is restored ++ * on every vmexit, but if not, we might have a stale dr6 from the ++ * guest. do_debug expects dr6 to be cleared after it runs, do the same. ++ */ ++ set_debugreg(0, 6); + } + + static int kvm_vcpu_ioctl_get_lapic(struct kvm_vcpu *vcpu, diff --git a/queue-4.15/media-pvrusb2-properly-check-endpoint-types.patch b/queue-4.15/media-pvrusb2-properly-check-endpoint-types.patch new file mode 100644 index 00000000000..d1a78bdb23c --- /dev/null +++ b/queue-4.15/media-pvrusb2-properly-check-endpoint-types.patch @@ -0,0 +1,82 @@ +From 72c27a68a2a3f650f0dc7891ee98f02283fc11af Mon Sep 17 00:00:00 2001 +From: Andrey Konovalov +Date: Thu, 2 Nov 2017 09:52:27 -0400 +Subject: media: pvrusb2: properly check endpoint types + +From: Andrey Konovalov + +commit 72c27a68a2a3f650f0dc7891ee98f02283fc11af upstream. + +As syzkaller detected, pvrusb2 driver submits bulk urb withount checking +the the endpoint type is actually blunk. Add a check. + +usb 1-1: BOGUS urb xfer, pipe 3 != type 1 +------------[ cut here ]------------ +WARNING: CPU: 1 PID: 2713 at drivers/usb/core/urb.c:449 usb_submit_urb+0xf8a/0x11d0 +Modules linked in: +CPU: 1 PID: 2713 Comm: pvrusb2-context Not tainted +4.14.0-rc1-42251-gebb2c2437d80 #210 +Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS Bochs 01/01/2011 +task: ffff88006b7a18c0 task.stack: ffff880069978000 +RIP: 0010:usb_submit_urb+0xf8a/0x11d0 drivers/usb/core/urb.c:448 +RSP: 0018:ffff88006997f990 EFLAGS: 00010286 +RAX: 0000000000000029 RBX: ffff880063661900 RCX: 0000000000000000 +RDX: 0000000000000029 RSI: ffffffff86876d60 RDI: ffffed000d32ff24 +RBP: ffff88006997fa90 R08: 1ffff1000d32fdca R09: 0000000000000000 +R10: 0000000000000000 R11: 0000000000000000 R12: 1ffff1000d32ff39 +R13: 0000000000000001 R14: 0000000000000003 R15: ffff880068bbed68 +FS: 0000000000000000(0000) GS:ffff88006c600000(0000) knlGS:0000000000000000 +CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 +CR2: 0000000001032000 CR3: 000000006a0ff000 CR4: 00000000000006f0 +Call Trace: + pvr2_send_request_ex+0xa57/0x1d80 drivers/media/usb/pvrusb2/pvrusb2-hdw.c:3645 + pvr2_hdw_check_firmware drivers/media/usb/pvrusb2/pvrusb2-hdw.c:1812 + pvr2_hdw_setup_low drivers/media/usb/pvrusb2/pvrusb2-hdw.c:2107 + pvr2_hdw_setup drivers/media/usb/pvrusb2/pvrusb2-hdw.c:2250 + pvr2_hdw_initialize+0x548/0x3c10 drivers/media/usb/pvrusb2/pvrusb2-hdw.c:2327 + pvr2_context_check drivers/media/usb/pvrusb2/pvrusb2-context.c:118 + pvr2_context_thread_func+0x361/0x8c0 drivers/media/usb/pvrusb2/pvrusb2-context.c:167 + kthread+0x3a1/0x470 kernel/kthread.c:231 + ret_from_fork+0x2a/0x40 arch/x86/entry/entry_64.S:431 +Code: 48 8b 85 30 ff ff ff 48 8d b8 98 00 00 00 e8 ee 82 89 fe 45 89 +e8 44 89 f1 4c 89 fa 48 89 c6 48 c7 c7 40 c0 ea 86 e8 30 1b dc fc <0f> +ff e9 9b f7 ff ff e8 aa 95 25 fd e9 80 f7 ff ff e8 50 74 f3 +---[ end trace 6919030503719da6 ]--- + +Signed-off-by: Andrey Konovalov +Signed-off-by: Greg Kroah-Hartman + +Signed-off-by: Mauro Carvalho Chehab + +--- + drivers/media/usb/pvrusb2/pvrusb2-hdw.c | 12 ++++++++++++ + 1 file changed, 12 insertions(+) + +--- a/drivers/media/usb/pvrusb2/pvrusb2-hdw.c ++++ b/drivers/media/usb/pvrusb2/pvrusb2-hdw.c +@@ -3648,6 +3648,12 @@ static int pvr2_send_request_ex(struct p + hdw); + hdw->ctl_write_urb->actual_length = 0; + hdw->ctl_write_pend_flag = !0; ++ if (usb_urb_ep_type_check(hdw->ctl_write_urb)) { ++ pvr2_trace( ++ PVR2_TRACE_ERROR_LEGS, ++ "Invalid write control endpoint"); ++ return -EINVAL; ++ } + status = usb_submit_urb(hdw->ctl_write_urb,GFP_KERNEL); + if (status < 0) { + pvr2_trace(PVR2_TRACE_ERROR_LEGS, +@@ -3672,6 +3678,12 @@ status); + hdw); + hdw->ctl_read_urb->actual_length = 0; + hdw->ctl_read_pend_flag = !0; ++ if (usb_urb_ep_type_check(hdw->ctl_read_urb)) { ++ pvr2_trace( ++ PVR2_TRACE_ERROR_LEGS, ++ "Invalid read control endpoint"); ++ return -EINVAL; ++ } + status = usb_submit_urb(hdw->ctl_read_urb,GFP_KERNEL); + if (status < 0) { + pvr2_trace(PVR2_TRACE_ERROR_LEGS, diff --git a/queue-4.15/net-avoid-skb_warn_bad_offload-on-is_err.patch b/queue-4.15/net-avoid-skb_warn_bad_offload-on-is_err.patch new file mode 100644 index 00000000000..90f9de291f8 --- /dev/null +++ b/queue-4.15/net-avoid-skb_warn_bad_offload-on-is_err.patch @@ -0,0 +1,39 @@ +From 8d74e9f88d65af8bb2e095aff506aa6eac755ada Mon Sep 17 00:00:00 2001 +From: Willem de Bruijn +Date: Tue, 12 Dec 2017 11:39:04 -0500 +Subject: net: avoid skb_warn_bad_offload on IS_ERR + +From: Willem de Bruijn + +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 +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman + +--- + net/core/dev.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/net/core/dev.c ++++ b/net/core/dev.c +@@ -2815,7 +2815,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-4.15/net_sched-gen_estimator-fix-lockdep-splat.patch b/queue-4.15/net_sched-gen_estimator-fix-lockdep-splat.patch new file mode 100644 index 00000000000..9124cf1ee0c --- /dev/null +++ b/queue-4.15/net_sched-gen_estimator-fix-lockdep-splat.patch @@ -0,0 +1,47 @@ +From 40ca54e3a686f13117f3de0c443f8026dadf7c44 Mon Sep 17 00:00:00 2001 +From: Eric Dumazet +Date: Sat, 27 Jan 2018 10:58:43 -0800 +Subject: net_sched: gen_estimator: fix lockdep splat + +From: Eric Dumazet + +commit 40ca54e3a686f13117f3de0c443f8026dadf7c44 upstream. + +syzbot reported a lockdep splat in gen_new_estimator() / +est_fetch_counters() when attempting to lock est->stats_lock. + +Since est_fetch_counters() is called from BH context from timer +interrupt, we need to block BH as well when calling it from process +context. + +Most qdiscs use per cpu counters and are immune to the problem, +but net/sched/act_api.c and net/netfilter/xt_RATEEST.c are using +a spinlock to protect their data. They both call gen_new_estimator() +while object is created and not yet alive, so this bug could +not trigger a deadlock, only a lockdep splat. + +Fixes: 1c0d32fde5bd ("net_sched: gen_estimator: complete rewrite of rate estimators") +Signed-off-by: Eric Dumazet +Reported-by: syzbot +Acked-by: Cong Wang +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman + +--- + net/core/gen_estimator.c | 4 ++++ + 1 file changed, 4 insertions(+) + +--- a/net/core/gen_estimator.c ++++ b/net/core/gen_estimator.c +@@ -159,7 +159,11 @@ int gen_new_estimator(struct gnet_stats_ + est->intvl_log = intvl_log; + est->cpu_bstats = cpu_bstats; + ++ if (stats_lock) ++ local_bh_disable(); + est_fetch_counters(est, &b); ++ if (stats_lock) ++ local_bh_enable(); + est->last_bytes = b.bytes; + est->last_packets = b.packets; + old = rcu_dereference_protected(*rate_est, 1); diff --git a/queue-4.15/netfilter-ipt_clusterip-fix-out-of-bounds-accesses-in-clusterip_tg_check.patch b/queue-4.15/netfilter-ipt_clusterip-fix-out-of-bounds-accesses-in-clusterip_tg_check.patch new file mode 100644 index 00000000000..e50939c478a --- /dev/null +++ b/queue-4.15/netfilter-ipt_clusterip-fix-out-of-bounds-accesses-in-clusterip_tg_check.patch @@ -0,0 +1,59 @@ +From 1a38956cce5eabd7b74f94bab70265e4df83165e Mon Sep 17 00:00:00 2001 +From: Dmitry Vyukov +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 + +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 +Reported-by: syzbot +Signed-off-by: Pablo Neira Ayuso +Signed-off-by: Greg Kroah-Hartman + +--- + 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 +@@ -431,7 +431,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 (par->nft_compat) { + pr_err("cannot use CLUSTERIP target from nftables compat\n"); +@@ -450,8 +450,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-4.15/netfilter-on-sockopt-acquire-sock-lock-only-in-the-required-scope.patch b/queue-4.15/netfilter-on-sockopt-acquire-sock-lock-only-in-the-required-scope.patch new file mode 100644 index 00000000000..9b278f2aa6a --- /dev/null +++ b/queue-4.15/netfilter-on-sockopt-acquire-sock-lock-only-in-the-required-scope.patch @@ -0,0 +1,242 @@ +From 3f34cfae1238848fd53f25e5c8fd59da57901f4b Mon Sep 17 00:00:00 2001 +From: Paolo Abeni +Date: Tue, 30 Jan 2018 19:01:40 +0100 +Subject: netfilter: on sockopt() acquire sock lock only in the required scope + +From: Paolo Abeni + +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 +Signed-off-by: Paolo Abeni +Signed-off-by: Pablo Neira Ayuso +Signed-off-by: Greg Kroah-Hartman + +--- + 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 +@@ -1251,11 +1251,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; + } +@@ -1280,12 +1277,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 +@@ -218,15 +218,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 +@@ -923,12 +923,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; + } +@@ -958,12 +954,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 +@@ -226,20 +226,27 @@ static const struct nf_hook_ops ipv6_con + 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)) +@@ -257,14 +264,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-4.15/netfilter-x_tables-avoid-out-of-bounds-reads-in-xt_request_find_-match-target.patch b/queue-4.15/netfilter-x_tables-avoid-out-of-bounds-reads-in-xt_request_find_-match-target.patch new file mode 100644 index 00000000000..01a99c12247 --- /dev/null +++ b/queue-4.15/netfilter-x_tables-avoid-out-of-bounds-reads-in-xt_request_find_-match-target.patch @@ -0,0 +1,51 @@ +From da17c73b6eb74aad3c3c0654394635675b623b3e Mon Sep 17 00:00:00 2001 +From: Eric Dumazet +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 + +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 +Reported-by: syzbot +Acked-by: Florian Westphal +Signed-off-by: Pablo Neira Ayuso +Signed-off-by: Greg Kroah-Hartman + +--- + 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-4.15/netfilter-x_tables-fix-int-overflow-in-xt_alloc_table_info.patch b/queue-4.15/netfilter-x_tables-fix-int-overflow-in-xt_alloc_table_info.patch new file mode 100644 index 00000000000..89683e2b16a --- /dev/null +++ b/queue-4.15/netfilter-x_tables-fix-int-overflow-in-xt_alloc_table_info.patch @@ -0,0 +1,44 @@ +From 889c604fd0b5f6d3b8694ade229ee44124de1127 Mon Sep 17 00:00:00 2001 +From: Dmitry Vyukov +Date: Thu, 28 Dec 2017 09:48:54 +0100 +Subject: netfilter: x_tables: fix int overflow in xt_alloc_table_info() + +From: Dmitry Vyukov + +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 +Signed-off-by: Pablo Neira Ayuso +Signed-off-by: Greg Kroah-Hartman + +--- + net/netfilter/x_tables.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +--- a/net/netfilter/x_tables.c ++++ b/net/netfilter/x_tables.c +@@ -39,7 +39,6 @@ MODULE_LICENSE("GPL"); + MODULE_AUTHOR("Harald Welte "); + MODULE_DESCRIPTION("{ip,ip6,arp,eb}_tables backend module"); + +-#define SMP_ALIGN(x) (((x) + SMP_CACHE_BYTES-1) & ~(SMP_CACHE_BYTES-1)) + #define XT_PCPU_BLOCK_SIZE 4096 + + struct compat_delta { +@@ -1000,7 +999,7 @@ struct xt_table_info *xt_alloc_table_inf + return NULL; + + /* 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; + + info = kvmalloc(sz, GFP_KERNEL); diff --git a/queue-4.15/netfilter-xt_cgroup-initialize-info-priv-in-cgroup_mt_check_v1.patch b/queue-4.15/netfilter-xt_cgroup-initialize-info-priv-in-cgroup_mt_check_v1.patch new file mode 100644 index 00000000000..c698ca55cf6 --- /dev/null +++ b/queue-4.15/netfilter-xt_cgroup-initialize-info-priv-in-cgroup_mt_check_v1.patch @@ -0,0 +1,33 @@ +From ba7cd5d95f25cc6005f687dabdb4e7a6063adda9 Mon Sep 17 00:00:00 2001 +From: Cong Wang +Date: Wed, 31 Jan 2018 15:02:47 -0800 +Subject: netfilter: xt_cgroup: initialize info->priv in cgroup_mt_check_v1() + +From: Cong Wang + +commit ba7cd5d95f25cc6005f687dabdb4e7a6063adda9 upstream. + +xt_cgroup_info_v1->priv is an internal pointer only used for kernel, +we should not trust what user-space provides. + +Reported-by: +Fixes: c38c4597e4bf ("netfilter: implement xt_cgroup cgroup2 path match") +Cc: Pablo Neira Ayuso +Signed-off-by: Cong Wang +Signed-off-by: Pablo Neira Ayuso +Signed-off-by: Greg Kroah-Hartman + +--- + net/netfilter/xt_cgroup.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/net/netfilter/xt_cgroup.c ++++ b/net/netfilter/xt_cgroup.c +@@ -52,6 +52,7 @@ static int cgroup_mt_check_v1(const stru + return -EINVAL; + } + ++ info->priv = NULL; + if (info->has_path) { + cgrp = cgroup_get_from_path(info->path); + if (IS_ERR(cgrp)) { diff --git a/queue-4.15/netfilter-xt_rateest-acquire-xt_rateest_mutex-for-hash-insert.patch b/queue-4.15/netfilter-xt_rateest-acquire-xt_rateest_mutex-for-hash-insert.patch new file mode 100644 index 00000000000..3c8e2dacf45 --- /dev/null +++ b/queue-4.15/netfilter-xt_rateest-acquire-xt_rateest_mutex-for-hash-insert.patch @@ -0,0 +1,92 @@ +From 7dc68e98757a8eccf8ca7a53a29b896f1eef1f76 Mon Sep 17 00:00:00 2001 +From: Cong Wang +Date: Mon, 5 Feb 2018 14:41:45 -0800 +Subject: netfilter: xt_RATEEST: acquire xt_rateest_mutex for hash insert + +From: Cong Wang + +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: +Fixes: 5859034d7eb8 ("[NETFILTER]: x_tables: add RATEEST target") +Signed-off-by: Cong Wang +Reviewed-by: Florian Westphal +Reviewed-by: Eric Dumazet +Signed-off-by: Pablo Neira Ayuso +Signed-off-by: Greg Kroah-Hartman + +--- + 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 +@@ -39,23 +39,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) +@@ -100,8 +108,10 @@ static int xt_rateest_tg_checkentry(cons + + net_get_random_once(&jhash_rnd, sizeof(jhash_rnd)); + +- 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. +@@ -139,11 +149,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-4.15/ptr_ring-fail-early-if-queue-occupies-more-than-kmalloc_max_size.patch b/queue-4.15/ptr_ring-fail-early-if-queue-occupies-more-than-kmalloc_max_size.patch new file mode 100644 index 00000000000..acf0e7b8691 --- /dev/null +++ b/queue-4.15/ptr_ring-fail-early-if-queue-occupies-more-than-kmalloc_max_size.patch @@ -0,0 +1,34 @@ +From 6e6e41c3112276288ccaf80c70916779b84bb276 Mon Sep 17 00:00:00 2001 +From: Jason Wang +Date: Fri, 9 Feb 2018 17:45:49 +0800 +Subject: ptr_ring: fail early if queue occupies more than KMALLOC_MAX_SIZE + +From: Jason Wang + +commit 6e6e41c3112276288ccaf80c70916779b84bb276 upstream. + +To avoid slab to warn about exceeded size, fail early if queue +occupies more than KMALLOC_MAX_SIZE. + +Reported-by: syzbot+e4d4f9ddd4295539735d@syzkaller.appspotmail.com +Fixes: 2e0ab8ca83c12 ("ptr_ring: array based FIFO for pointers") +Signed-off-by: Jason Wang +Acked-by: Michael S. Tsirkin +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman + +--- + include/linux/ptr_ring.h | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/include/linux/ptr_ring.h ++++ b/include/linux/ptr_ring.h +@@ -453,6 +453,8 @@ static inline int ptr_ring_consume_batch + + static inline void **__ptr_ring_init_queue_alloc(unsigned int size, gfp_t gfp) + { ++ if (size * sizeof(void *) > KMALLOC_MAX_SIZE) ++ return NULL; + return kcalloc(size, sizeof(void *), gfp); + } + diff --git a/queue-4.15/ptr_ring-try-vmalloc-when-kmalloc-fails.patch b/queue-4.15/ptr_ring-try-vmalloc-when-kmalloc-fails.patch new file mode 100644 index 00000000000..898393b6dd5 --- /dev/null +++ b/queue-4.15/ptr_ring-try-vmalloc-when-kmalloc-fails.patch @@ -0,0 +1,77 @@ +From 0bf7800f1799b5b1fd7d4f024e9ece53ac489011 Mon Sep 17 00:00:00 2001 +From: Jason Wang +Date: Fri, 9 Feb 2018 17:45:50 +0800 +Subject: ptr_ring: try vmalloc() when kmalloc() fails + +From: Jason Wang + +commit 0bf7800f1799b5b1fd7d4f024e9ece53ac489011 upstream. + +This patch switch to use kvmalloc_array() for using a vmalloc() +fallback to help in case kmalloc() fails. + +Reported-by: syzbot+e4d4f9ddd4295539735d@syzkaller.appspotmail.com +Fixes: 2e0ab8ca83c12 ("ptr_ring: array based FIFO for pointers") +Signed-off-by: Jason Wang +Acked-by: Michael S. Tsirkin +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman + +--- + include/linux/ptr_ring.h | 13 ++++++++----- + 1 file changed, 8 insertions(+), 5 deletions(-) + +--- a/include/linux/ptr_ring.h ++++ b/include/linux/ptr_ring.h +@@ -451,11 +451,14 @@ static inline int ptr_ring_consume_batch + __PTR_RING_PEEK_CALL_v; \ + }) + ++/* Not all gfp_t flags (besides GFP_KERNEL) are allowed. See ++ * documentation for vmalloc for which of them are legal. ++ */ + static inline void **__ptr_ring_init_queue_alloc(unsigned int size, gfp_t gfp) + { + if (size * sizeof(void *) > KMALLOC_MAX_SIZE) + return NULL; +- return kcalloc(size, sizeof(void *), gfp); ++ return kvmalloc_array(size, sizeof(void *), gfp | __GFP_ZERO); + } + + static inline void __ptr_ring_set_size(struct ptr_ring *r, int size) +@@ -588,7 +591,7 @@ static inline int ptr_ring_resize(struct + spin_unlock(&(r)->producer_lock); + spin_unlock_irqrestore(&(r)->consumer_lock, flags); + +- kfree(old); ++ kvfree(old); + + return 0; + } +@@ -628,7 +631,7 @@ static inline int ptr_ring_resize_multip + } + + for (i = 0; i < nrings; ++i) +- kfree(queues[i]); ++ kvfree(queues[i]); + + kfree(queues); + +@@ -636,7 +639,7 @@ static inline int ptr_ring_resize_multip + + nomem: + while (--i >= 0) +- kfree(queues[i]); ++ kvfree(queues[i]); + + kfree(queues); + +@@ -651,7 +654,7 @@ static inline void ptr_ring_cleanup(stru + if (destroy) + while ((ptr = ptr_ring_consume(r))) + destroy(ptr); +- kfree(r->queue); ++ kvfree(r->queue); + } + + #endif /* _LINUX_PTR_RING_H */ diff --git a/queue-4.15/rds-tcp-atomically-purge-entries-from-rds_tcp_conn_list-during-netns-delete.patch b/queue-4.15/rds-tcp-atomically-purge-entries-from-rds_tcp_conn_list-during-netns-delete.patch new file mode 100644 index 00000000000..2031770bd52 --- /dev/null +++ b/queue-4.15/rds-tcp-atomically-purge-entries-from-rds_tcp_conn_list-during-netns-delete.patch @@ -0,0 +1,71 @@ +From f10b4cff98c6977668434fbf5dd58695eeca2897 Mon Sep 17 00:00:00 2001 +From: Sowmini Varadhan +Date: Thu, 30 Nov 2017 11:11:29 -0800 +Subject: rds: tcp: atomically purge entries from rds_tcp_conn_list during netns delete + +From: Sowmini Varadhan + +commit f10b4cff98c6977668434fbf5dd58695eeca2897 upstream. + +The rds_tcp_kill_sock() function parses the rds_tcp_conn_list +to find the rds_connection entries marked for deletion as part +of the netns deletion under the protection of the rds_tcp_conn_lock. +Since the rds_tcp_conn_list tracks rds_tcp_connections (which +have a 1:1 mapping with rds_conn_path), multiple tc entries in +the rds_tcp_conn_list will map to a single rds_connection, and will +be deleted as part of the rds_conn_destroy() operation that is +done outside the rds_tcp_conn_lock. + +The rds_tcp_conn_list traversal done under the protection of +rds_tcp_conn_lock should not leave any doomed tc entries in +the list after the rds_tcp_conn_lock is released, else another +concurrently executiong netns delete (for a differnt netns) thread +may trip on these entries. + +Reported-by: syzbot +Signed-off-by: Sowmini Varadhan +Acked-by: Santosh Shilimkar +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman + +--- + net/rds/tcp.c | 9 +++++++-- + net/rds/tcp.h | 1 + + 2 files changed, 8 insertions(+), 2 deletions(-) + +--- a/net/rds/tcp.c ++++ b/net/rds/tcp.c +@@ -307,7 +307,8 @@ static void rds_tcp_conn_free(void *arg) + rdsdebug("freeing tc %p\n", tc); + + spin_lock_irqsave(&rds_tcp_conn_lock, flags); +- list_del(&tc->t_tcp_node); ++ if (!tc->t_tcp_node_detached) ++ list_del(&tc->t_tcp_node); + spin_unlock_irqrestore(&rds_tcp_conn_lock, flags); + + kmem_cache_free(rds_tcp_conn_slab, tc); +@@ -532,8 +533,12 @@ static void rds_tcp_kill_sock(struct net + + if (net != c_net || !tc->t_sock) + continue; +- if (!list_has_conn(&tmp_list, tc->t_cpath->cp_conn)) ++ if (!list_has_conn(&tmp_list, tc->t_cpath->cp_conn)) { + list_move_tail(&tc->t_tcp_node, &tmp_list); ++ } else { ++ list_del(&tc->t_tcp_node); ++ tc->t_tcp_node_detached = true; ++ } + } + spin_unlock_irq(&rds_tcp_conn_lock); + list_for_each_entry_safe(tc, _tc, &tmp_list, t_tcp_node) { +--- a/net/rds/tcp.h ++++ b/net/rds/tcp.h +@@ -12,6 +12,7 @@ struct rds_tcp_incoming { + struct rds_tcp_connection { + + struct list_head t_tcp_node; ++ bool t_tcp_node_detached; + struct rds_conn_path *t_cpath; + /* t_conn_path_lock synchronizes the connection establishment between + * rds_tcp_accept_one and rds_tcp_conn_path_connect diff --git a/queue-4.15/rds-tcp-correctly-sequence-cleanup-on-netns-deletion.patch b/queue-4.15/rds-tcp-correctly-sequence-cleanup-on-netns-deletion.patch new file mode 100644 index 00000000000..be99bf46b8f --- /dev/null +++ b/queue-4.15/rds-tcp-correctly-sequence-cleanup-on-netns-deletion.patch @@ -0,0 +1,122 @@ +From 681648e67d43cf269c5590ecf021ed481f4551fc Mon Sep 17 00:00:00 2001 +From: Sowmini Varadhan +Date: Thu, 30 Nov 2017 11:11:28 -0800 +Subject: rds: tcp: correctly sequence cleanup on netns deletion. + +From: Sowmini Varadhan + +commit 681648e67d43cf269c5590ecf021ed481f4551fc upstream. + +Commit 8edc3affc077 ("rds: tcp: Take explicit refcounts on struct net") +introduces a regression in rds-tcp netns cleanup. The cleanup_net(), +(and thus rds_tcp_dev_event notification) is only called from put_net() +when all netns refcounts go to 0, but this cannot happen if the +rds_connection itself is holding a c_net ref that it expects to +release in rds_tcp_kill_sock. + +Instead, the rds_tcp_kill_sock callback should make sure to +tear down state carefully, ensuring that the socket teardown +is only done after all data-structures and workqs that depend +on it are quiesced. + +The original motivation for commit 8edc3affc077 ("rds: tcp: Take explicit +refcounts on struct net") was to resolve a race condition reported by +syzkaller where workqs for tx/rx/connect were triggered after the +namespace was deleted. Those worker threads should have been +cancelled/flushed before socket tear-down and indeed, +rds_conn_path_destroy() does try to sequence this by doing + /* cancel cp_send_w */ + /* cancel cp_recv_w */ + /* flush cp_down_w */ + /* free data structures */ +Here the "flush cp_down_w" will trigger rds_conn_shutdown and thus +invoke rds_tcp_conn_path_shutdown() to close the tcp socket, so that +we ought to have satisfied the requirement that "socket-close is +done after all other dependent state is quiesced". However, +rds_conn_shutdown has a bug in that it *always* triggers the reconnect +workq (and if connection is successful, we always restart tx/rx +workqs so with the right timing, we risk the race conditions reported +by syzkaller). + +Netns deletion is like module teardown- no need to restart a +reconnect in this case. We can use the c_destroy_in_prog bit +to avoid restarting the reconnect. + +Fixes: 8edc3affc077 ("rds: tcp: Take explicit refcounts on struct net") +Signed-off-by: Sowmini Varadhan +Acked-by: Santosh Shilimkar +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman + +--- + net/rds/connection.c | 3 ++- + net/rds/rds.h | 6 +++--- + net/rds/tcp.c | 4 ++-- + 3 files changed, 7 insertions(+), 6 deletions(-) + +--- a/net/rds/connection.c ++++ b/net/rds/connection.c +@@ -366,6 +366,8 @@ void rds_conn_shutdown(struct rds_conn_p + * to the conn hash, so we never trigger a reconnect on this + * conn - the reconnect is always triggered by the active peer. */ + cancel_delayed_work_sync(&cp->cp_conn_w); ++ if (conn->c_destroy_in_prog) ++ return; + rcu_read_lock(); + if (!hlist_unhashed(&conn->c_hash_node)) { + rcu_read_unlock(); +@@ -445,7 +447,6 @@ void rds_conn_destroy(struct rds_connect + */ + rds_cong_remove_conn(conn); + +- put_net(conn->c_net); + kfree(conn->c_path); + kmem_cache_free(rds_conn_slab, conn); + +--- a/net/rds/rds.h ++++ b/net/rds/rds.h +@@ -150,7 +150,7 @@ struct rds_connection { + + /* Protocol version */ + unsigned int c_version; +- struct net *c_net; ++ possible_net_t c_net; + + struct list_head c_map_item; + unsigned long c_map_queued; +@@ -165,13 +165,13 @@ struct rds_connection { + static inline + struct net *rds_conn_net(struct rds_connection *conn) + { +- return conn->c_net; ++ return read_pnet(&conn->c_net); + } + + static inline + void rds_conn_net_set(struct rds_connection *conn, struct net *net) + { +- conn->c_net = get_net(net); ++ write_pnet(&conn->c_net, net); + } + + #define RDS_FLAG_CONG_BITMAP 0x01 +--- a/net/rds/tcp.c ++++ b/net/rds/tcp.c +@@ -528,7 +528,7 @@ static void rds_tcp_kill_sock(struct net + rds_tcp_listen_stop(lsock, &rtn->rds_tcp_accept_w); + spin_lock_irq(&rds_tcp_conn_lock); + list_for_each_entry_safe(tc, _tc, &rds_tcp_conn_list, t_tcp_node) { +- struct net *c_net = tc->t_cpath->cp_conn->c_net; ++ struct net *c_net = read_pnet(&tc->t_cpath->cp_conn->c_net); + + if (net != c_net || !tc->t_sock) + continue; +@@ -587,7 +587,7 @@ static void rds_tcp_sysctl_reset(struct + + spin_lock_irq(&rds_tcp_conn_lock); + list_for_each_entry_safe(tc, _tc, &rds_tcp_conn_list, t_tcp_node) { +- struct net *c_net = tc->t_cpath->cp_conn->c_net; ++ struct net *c_net = read_pnet(&tc->t_cpath->cp_conn->c_net); + + if (net != c_net || !tc->t_sock) + continue; diff --git a/queue-4.15/selinux-ensure-the-context-is-nul-terminated-in-security_context_to_sid_core.patch b/queue-4.15/selinux-ensure-the-context-is-nul-terminated-in-security_context_to_sid_core.patch new file mode 100644 index 00000000000..76a8a31c510 --- /dev/null +++ b/queue-4.15/selinux-ensure-the-context-is-nul-terminated-in-security_context_to_sid_core.patch @@ -0,0 +1,67 @@ +From ef28df55ac27e1e5cd122e19fa311d886d47a756 Mon Sep 17 00:00:00 2001 +From: Paul Moore +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 + +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 +Signed-off-by: Paul Moore +Reviewed-By: William Roberts +Signed-off-by: Greg Kroah-Hartman + +--- + 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 +@@ -1413,27 +1413,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-4.15/selinux-skip-bounded-transition-processing-if-the-policy-isn-t-loaded.patch b/queue-4.15/selinux-skip-bounded-transition-processing-if-the-policy-isn-t-loaded.patch new file mode 100644 index 00000000000..a10c5a97989 --- /dev/null +++ b/queue-4.15/selinux-skip-bounded-transition-processing-if-the-policy-isn-t-loaded.patch @@ -0,0 +1,38 @@ +From 4b14752ec4e0d87126e636384cf37c8dd9df157c Mon Sep 17 00:00:00 2001 +From: Paul Moore +Date: Tue, 5 Dec 2017 17:17:43 -0500 +Subject: selinux: skip bounded transition processing if the policy isn't loaded + +From: Paul Moore + +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 +Signed-off-by: Paul Moore +Acked-by: Stephen Smalley +Reviewed-by: James Morris +Signed-off-by: Greg Kroah-Hartman + +--- + security/selinux/ss/services.c | 3 +++ + 1 file changed, 3 insertions(+) + +--- a/security/selinux/ss/services.c ++++ b/security/selinux/ss/services.c +@@ -867,6 +867,9 @@ int security_bounded_transition(u32 old_ + int index; + int rc; + ++ if (!ss_initialized) ++ return 0; ++ + read_lock(&policy_rwlock); + + rc = -EINVAL; diff --git a/queue-4.15/series b/queue-4.15/series new file mode 100644 index 00000000000..d4d69743ba1 --- /dev/null +++ b/queue-4.15/series @@ -0,0 +1,22 @@ +tun-fix-tun_napi_alloc_frags-frag-allocator.patch +ptr_ring-fail-early-if-queue-occupies-more-than-kmalloc_max_size.patch +ptr_ring-try-vmalloc-when-kmalloc-fails.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 +media-pvrusb2-properly-check-endpoint-types.patch +crypto-x86-twofish-3way-fix-rbp-usage.patch +staging-android-ion-add-__gfp_nowarn-for-system-contig-heap.patch +staging-android-ion-switch-from-warn-to-pr_warn.patch +blk_rq_map_user_iov-fix-error-override.patch +kvm-x86-fix-escape-of-guest-dr6-to-the-host.patch +kcov-detect-double-association-with-a-single-task.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_cgroup-initialize-info-priv-in-cgroup_mt_check_v1.patch +netfilter-xt_rateest-acquire-xt_rateest_mutex-for-hash-insert.patch +rds-tcp-correctly-sequence-cleanup-on-netns-deletion.patch +rds-tcp-atomically-purge-entries-from-rds_tcp_conn_list-during-netns-delete.patch +net-avoid-skb_warn_bad_offload-on-is_err.patch +net_sched-gen_estimator-fix-lockdep-splat.patch diff --git a/queue-4.15/staging-android-ion-add-__gfp_nowarn-for-system-contig-heap.patch b/queue-4.15/staging-android-ion-add-__gfp_nowarn-for-system-contig-heap.patch new file mode 100644 index 00000000000..a37ecf0af4e --- /dev/null +++ b/queue-4.15/staging-android-ion-add-__gfp_nowarn-for-system-contig-heap.patch @@ -0,0 +1,53 @@ +From 0c75f10312a35b149b2cebb1832316b35c2337ca Mon Sep 17 00:00:00 2001 +From: Laura Abbott +Date: Fri, 5 Jan 2018 11:14:08 -0800 +Subject: staging: android: ion: Add __GFP_NOWARN for system contig heap + +From: Laura Abbott + +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 +Signed-off-by: Laura Abbott +Signed-off-by: Greg Kroah-Hartman + +--- + 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 +@@ -371,7 +371,7 @@ static int ion_system_contig_heap_alloca + unsigned long i; + int ret; + +- 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-4.15/staging-android-ion-switch-from-warn-to-pr_warn.patch b/queue-4.15/staging-android-ion-switch-from-warn-to-pr_warn.patch new file mode 100644 index 00000000000..094fff36d07 --- /dev/null +++ b/queue-4.15/staging-android-ion-switch-from-warn-to-pr_warn.patch @@ -0,0 +1,42 @@ +From e4e179a844f52e907e550f887d0a2171f1508af1 Mon Sep 17 00:00:00 2001 +From: Laura Abbott +Date: Fri, 5 Jan 2018 11:14:09 -0800 +Subject: staging: android: ion: Switch from WARN to pr_warn + +From: Laura Abbott + +commit e4e179a844f52e907e550f887d0a2171f1508af1 upstream. + +Syzbot reported a warning with Ion: + +WARNING: CPU: 0 PID: 3502 at drivers/staging/android/ion/ion-ioctl.c:73 ion_ioctl+0x2db/0x380 drivers/staging/android/ion/ion-ioctl.c:73 +Kernel panic - not syncing: panic_on_warn set ... + +This is a warning that validation of the ioctl fields failed. This was +deliberately added as a warning to make it very obvious to developers that +something needed to be fixed. In reality, this is overkill and disturbs +fuzzing. Switch to pr_warn for a message instead. + +Reported-by: syzbot+fa2d5f63ee5904a0115a@syzkaller.appspotmail.com +Reported-by: syzbot +Signed-off-by: Laura Abbott +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/staging/android/ion/ion-ioctl.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +--- a/drivers/staging/android/ion/ion-ioctl.c ++++ b/drivers/staging/android/ion/ion-ioctl.c +@@ -70,8 +70,10 @@ long ion_ioctl(struct file *filp, unsign + return -EFAULT; + + ret = validate_ioctl_arg(cmd, &data); +- if (WARN_ON_ONCE(ret)) ++ if (ret) { ++ pr_warn_once("%s: ioctl validate failed\n", __func__); + return ret; ++ } + + if (!(dir & _IOC_WRITE)) + memset(&data, 0, sizeof(data)); diff --git a/queue-4.15/tun-fix-tun_napi_alloc_frags-frag-allocator.patch b/queue-4.15/tun-fix-tun_napi_alloc_frags-frag-allocator.patch new file mode 100644 index 00000000000..7cdcf0a8d39 --- /dev/null +++ b/queue-4.15/tun-fix-tun_napi_alloc_frags-frag-allocator.patch @@ -0,0 +1,85 @@ +From 43a08e0f58b3f236165029710a4e3b303815253b Mon Sep 17 00:00:00 2001 +From: Eric Dumazet +Date: Thu, 15 Feb 2018 14:47:15 -0800 +Subject: tun: fix tun_napi_alloc_frags() frag allocator +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Eric Dumazet + +commit 43a08e0f58b3f236165029710a4e3b303815253b upstream. + + + While fuzzing arm64 v4.16-rc1 with Syzkaller, I've been hitting a + misaligned atomic in __skb_clone: + +        atomic_inc(&(skb_shinfo(skb)->dataref)); + + where dataref doesn't have the required natural alignment, and the + atomic operation faults. e.g. i often see it aligned to a single + byte boundary rather than a four byte boundary. + + AFAICT, the skb_shared_info is misaligned at the instant it's + allocated in __napi_alloc_skb() __napi_alloc_skb() + + +Problem is caused by tun_napi_alloc_frags() using +napi_alloc_frag() with user provided seg sizes, +leading to other users of this API getting unaligned +page fragments. + +Since we would like to not necessarily add paddings or alignments to +the frags that tun_napi_alloc_frags() attaches to the skb, switch to +another page frag allocator. + +As a bonus skb_page_frag_refill() can use GFP_KERNEL allocations, +meaning that we can not deplete memory reserves as easily. + +Fixes: 90e33d459407 ("tun: enable napi_gro_frags() for TUN/TAP driver") +Signed-off-by: Eric Dumazet +Reported-by: Mark Rutland +Tested-by: Mark Rutland +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/net/tun.c | 16 ++++++---------- + 1 file changed, 6 insertions(+), 10 deletions(-) + +--- a/drivers/net/tun.c ++++ b/drivers/net/tun.c +@@ -1317,27 +1317,23 @@ static struct sk_buff *tun_napi_alloc_fr + skb->truesize += skb->data_len; + + for (i = 1; i < it->nr_segs; i++) { ++ struct page_frag *pfrag = ¤t->task_frag; + size_t fragsz = it->iov[i].iov_len; +- unsigned long offset; +- struct page *page; +- void *data; + + if (fragsz == 0 || fragsz > PAGE_SIZE) { + err = -EINVAL; + goto free; + } + +- local_bh_disable(); +- data = napi_alloc_frag(fragsz); +- local_bh_enable(); +- if (!data) { ++ if (!skb_page_frag_refill(fragsz, pfrag, GFP_KERNEL)) { + err = -ENOMEM; + goto free; + } + +- page = virt_to_head_page(data); +- offset = data - page_address(page); +- skb_fill_page_desc(skb, i - 1, page, offset, fragsz); ++ skb_fill_page_desc(skb, i - 1, pfrag->page, ++ pfrag->offset, fragsz); ++ page_ref_inc(pfrag->page); ++ pfrag->offset += fragsz; + } + + return skb; -- 2.47.3