From: Greg Kroah-Hartman Date: Thu, 10 May 2018 14:04:04 +0000 (+0200) Subject: 4.16-stable patches X-Git-Tag: v3.18.109~36 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=4ac7e283ca5c7dcff938aaf8f16b4e1bb11f9cbb;p=thirdparty%2Fkernel%2Fstable-queue.git 4.16-stable patches added patches: bdi-fix-oops-in-wb_workfn.patch bdi-fix-use-after-free-bug-in-debugfs_remove.patch bdi-wake-up-concurrent-wb_shutdown-callers.patch bpf-tracing-fix-a-deadlock-in-perf_event_detach_bpf_prog.patch crypto-af_alg-fix-possible-uninit-value-in-alg_bind.patch dccp-initialize-ireq-ir_mark.patch i2c-dev-prevent-zero_size_ptr-deref-in-i2cdev_ioctl_rdwr.patch inetpeer-fix-uninit-value-in-inet_getpeer.patch ipv4-fix-uninit-value-in-ip_route_output_key_hash_rcu.patch kcm-call-strp_stop-before-strp_done-in-kcm_attach.patch memcg-fix-per_node_info-cleanup.patch net-fix-rtnh_ok.patch net-fix-uninit-value-in-__hw_addr_add_ex.patch net-initialize-skb-peeked-when-cloning.patch netfilter-x_tables-ensure-last-rule-in-base-chain-matches-underflow-policy.patch netlink-fix-uninit-value-in-netlink_sendmsg.patch perf-remove-superfluous-allocation-error-check.patch rds-tcp-must-use-spin_lock_irq-and-not-spin_lock_bh-with-rds_tcp_conn_lock.patch soreuseport-initialise-timewait-reuseport-field.patch tcp-fix-tcp_repair_queue-bound-checking.patch --- diff --git a/queue-4.16/bdi-fix-oops-in-wb_workfn.patch b/queue-4.16/bdi-fix-oops-in-wb_workfn.patch new file mode 100644 index 00000000000..d4fa0913624 --- /dev/null +++ b/queue-4.16/bdi-fix-oops-in-wb_workfn.patch @@ -0,0 +1,52 @@ +From b8b784958eccbf8f51ebeee65282ca3fd59ea391 Mon Sep 17 00:00:00 2001 +From: Jan Kara +Date: Thu, 3 May 2018 18:26:26 +0200 +Subject: bdi: Fix oops in wb_workfn() + +From: Jan Kara + +commit b8b784958eccbf8f51ebeee65282ca3fd59ea391 upstream. + +Syzbot has reported that it can hit a NULL pointer dereference in +wb_workfn() due to wb->bdi->dev being NULL. This indicates that +wb_workfn() was called for an already unregistered bdi which should not +happen as wb_shutdown() called from bdi_unregister() should make sure +all pending writeback works are completed before bdi is unregistered. +Except that wb_workfn() itself can requeue the work with: + + mod_delayed_work(bdi_wq, &wb->dwork, 0); + +and if this happens while wb_shutdown() is waiting in: + + flush_delayed_work(&wb->dwork); + +the dwork can get executed after wb_shutdown() has finished and +bdi_unregister() has cleared wb->bdi->dev. + +Make wb_workfn() use wakeup_wb() for requeueing the work which takes all +the necessary precautions against racing with bdi unregistration. + +CC: Tetsuo Handa +CC: Tejun Heo +Fixes: 839a8e8660b6777e7fe4e80af1a048aebe2b5977 +Reported-by: syzbot +Reviewed-by: Dave Chinner +Signed-off-by: Jan Kara +Signed-off-by: Jens Axboe +Signed-off-by: Greg Kroah-Hartman + +--- + fs/fs-writeback.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/fs/fs-writeback.c ++++ b/fs/fs-writeback.c +@@ -1961,7 +1961,7 @@ void wb_workfn(struct work_struct *work) + } + + if (!list_empty(&wb->work_list)) +- mod_delayed_work(bdi_wq, &wb->dwork, 0); ++ wb_wakeup(wb); + else if (wb_has_dirty_io(wb) && dirty_writeback_interval) + wb_wakeup_delayed(wb); + diff --git a/queue-4.16/bdi-fix-use-after-free-bug-in-debugfs_remove.patch b/queue-4.16/bdi-fix-use-after-free-bug-in-debugfs_remove.patch new file mode 100644 index 00000000000..afd574c7cb1 --- /dev/null +++ b/queue-4.16/bdi-fix-use-after-free-bug-in-debugfs_remove.patch @@ -0,0 +1,46 @@ +From f53823c18131e755905b4f654196fd2cc3953f6e Mon Sep 17 00:00:00 2001 +From: Tetsuo Handa +Date: Mon, 23 Apr 2018 11:21:03 +0900 +Subject: bdi: Fix use after free bug in debugfs_remove() + +From: Tetsuo Handa + +commit f53823c18131e755905b4f654196fd2cc3953f6e upstream. + +syzbot is reporting use after free bug in debugfs_remove() [1]. + +This is because fault injection made memory allocation for +debugfs_create_file() from bdi_debug_register() from bdi_register_va() +fail and continued with setting WB_registered. But when debugfs_remove() +is called from debugfs_remove(bdi->debug_dir) from bdi_debug_unregister() + from bdi_unregister() from release_bdi() because WB_registered was set +by bdi_register_va(), IS_ERR_OR_NULL(bdi->debug_dir) == false despite +debugfs_remove(bdi->debug_dir) was already called from bdi_register_va(). + +Fix this by making IS_ERR_OR_NULL(bdi->debug_dir) == true. + +[1] https://syzkaller.appspot.com/bug?id=5ab4efd91a96dcea9b68104f159adf4af2a6dfc1 + +Signed-off-by: Tetsuo Handa +Reported-by: syzbot +Fixes: 97f07697932e6faf ("bdi: convert bdi_debug_register to int") +Cc: weiping zhang +Reviewed-by: Greg Kroah-Hartman +Reviewed-by: Jan Kara +Signed-off-by: Jens Axboe +Signed-off-by: Greg Kroah-Hartman + +--- + mm/backing-dev.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/mm/backing-dev.c ++++ b/mm/backing-dev.c +@@ -126,6 +126,7 @@ static int bdi_debug_register(struct bac + bdi, &bdi_debug_stats_fops); + if (!bdi->debug_stats) { + debugfs_remove(bdi->debug_dir); ++ bdi->debug_dir = NULL; + return -ENOMEM; + } + diff --git a/queue-4.16/bdi-wake-up-concurrent-wb_shutdown-callers.patch b/queue-4.16/bdi-wake-up-concurrent-wb_shutdown-callers.patch new file mode 100644 index 00000000000..731264194c5 --- /dev/null +++ b/queue-4.16/bdi-wake-up-concurrent-wb_shutdown-callers.patch @@ -0,0 +1,68 @@ +From 8236b0ae31c837d2b3a2565c5f8d77f637e824cc Mon Sep 17 00:00:00 2001 +From: Tetsuo Handa +Date: Wed, 2 May 2018 07:07:55 +0900 +Subject: bdi: wake up concurrent wb_shutdown() callers. + +From: Tetsuo Handa + +commit 8236b0ae31c837d2b3a2565c5f8d77f637e824cc upstream. + +syzbot is reporting hung tasks at wait_on_bit(WB_shutting_down) in +wb_shutdown() [1]. This seems to be because commit 5318ce7d46866e1d ("bdi: +Shutdown writeback on all cgwbs in cgwb_bdi_destroy()") forgot to call +wake_up_bit(WB_shutting_down) after clear_bit(WB_shutting_down). + +Introduce a helper function clear_and_wake_up_bit() and use it, in order +to avoid similar errors in future. + +[1] https://syzkaller.appspot.com/bug?id=b297474817af98d5796bc544e1bb806fc3da0e5e + +Signed-off-by: Tetsuo Handa +Reported-by: syzbot +Fixes: 5318ce7d46866e1d ("bdi: Shutdown writeback on all cgwbs in cgwb_bdi_destroy()") +Cc: Tejun Heo +Reviewed-by: Jan Kara +Suggested-by: Linus Torvalds +Signed-off-by: Jens Axboe +Signed-off-by: Greg Kroah-Hartman + +--- + include/linux/wait_bit.h | 17 +++++++++++++++++ + mm/backing-dev.c | 2 +- + 2 files changed, 18 insertions(+), 1 deletion(-) + +--- a/include/linux/wait_bit.h ++++ b/include/linux/wait_bit.h +@@ -262,4 +262,21 @@ int wait_on_atomic_t(atomic_t *val, wait + return out_of_line_wait_on_atomic_t(val, action, mode); + } + ++/** ++ * clear_and_wake_up_bit - clear a bit and wake up anyone waiting on that bit ++ * ++ * @bit: the bit of the word being waited on ++ * @word: the word being waited on, a kernel virtual address ++ * ++ * You can use this helper if bitflags are manipulated atomically rather than ++ * non-atomically under a lock. ++ */ ++static inline void clear_and_wake_up_bit(int bit, void *word) ++{ ++ clear_bit_unlock(bit, word); ++ /* See wake_up_bit() for which memory barrier you need to use. */ ++ smp_mb__after_atomic(); ++ wake_up_bit(word, bit); ++} ++ + #endif /* _LINUX_WAIT_BIT_H */ +--- a/mm/backing-dev.c ++++ b/mm/backing-dev.c +@@ -394,7 +394,7 @@ static void wb_shutdown(struct bdi_write + * the barrier provided by test_and_clear_bit() above. + */ + smp_wmb(); +- clear_bit(WB_shutting_down, &wb->state); ++ clear_and_wake_up_bit(WB_shutting_down, &wb->state); + } + + static void wb_exit(struct bdi_writeback *wb) diff --git a/queue-4.16/bpf-tracing-fix-a-deadlock-in-perf_event_detach_bpf_prog.patch b/queue-4.16/bpf-tracing-fix-a-deadlock-in-perf_event_detach_bpf_prog.patch new file mode 100644 index 00000000000..38f6fa8e0bf --- /dev/null +++ b/queue-4.16/bpf-tracing-fix-a-deadlock-in-perf_event_detach_bpf_prog.patch @@ -0,0 +1,245 @@ +From 3a38bb98d9abdc3856f26b5ed4332803065cd7cf Mon Sep 17 00:00:00 2001 +From: Yonghong Song +Date: Tue, 10 Apr 2018 09:37:32 -0700 +Subject: bpf/tracing: fix a deadlock in perf_event_detach_bpf_prog + +From: Yonghong Song + +commit 3a38bb98d9abdc3856f26b5ed4332803065cd7cf upstream. + +syzbot reported a possible deadlock in perf_event_detach_bpf_prog. +The error details: + ====================================================== + WARNING: possible circular locking dependency detected + 4.16.0-rc7+ #3 Not tainted + ------------------------------------------------------ + syz-executor7/24531 is trying to acquire lock: + (bpf_event_mutex){+.+.}, at: [<000000008a849b07>] perf_event_detach_bpf_prog+0x92/0x3d0 kernel/trace/bpf_trace.c:854 + + but task is already holding lock: + (&mm->mmap_sem){++++}, at: [<0000000038768f87>] vm_mmap_pgoff+0x198/0x280 mm/util.c:353 + + which lock already depends on the new lock. + + the existing dependency chain (in reverse order) is: + + -> #1 (&mm->mmap_sem){++++}: + __might_fault+0x13a/0x1d0 mm/memory.c:4571 + _copy_to_user+0x2c/0xc0 lib/usercopy.c:25 + copy_to_user include/linux/uaccess.h:155 [inline] + bpf_prog_array_copy_info+0xf2/0x1c0 kernel/bpf/core.c:1694 + perf_event_query_prog_array+0x1c7/0x2c0 kernel/trace/bpf_trace.c:891 + _perf_ioctl kernel/events/core.c:4750 [inline] + perf_ioctl+0x3e1/0x1480 kernel/events/core.c:4770 + 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 + do_syscall_64+0x281/0x940 arch/x86/entry/common.c:287 + entry_SYSCALL_64_after_hwframe+0x42/0xb7 + + -> #0 (bpf_event_mutex){+.+.}: + lock_acquire+0x1d5/0x580 kernel/locking/lockdep.c:3920 + __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 + perf_event_detach_bpf_prog+0x92/0x3d0 kernel/trace/bpf_trace.c:854 + perf_event_free_bpf_prog kernel/events/core.c:8147 [inline] + _free_event+0xbdb/0x10f0 kernel/events/core.c:4116 + put_event+0x24/0x30 kernel/events/core.c:4204 + perf_mmap_close+0x60d/0x1010 kernel/events/core.c:5172 + remove_vma+0xb4/0x1b0 mm/mmap.c:172 + remove_vma_list mm/mmap.c:2490 [inline] + do_munmap+0x82a/0xdf0 mm/mmap.c:2731 + mmap_region+0x59e/0x15a0 mm/mmap.c:1646 + do_mmap+0x6c0/0xe00 mm/mmap.c:1483 + do_mmap_pgoff include/linux/mm.h:2223 [inline] + vm_mmap_pgoff+0x1de/0x280 mm/util.c:355 + SYSC_mmap_pgoff mm/mmap.c:1533 [inline] + SyS_mmap_pgoff+0x462/0x5f0 mm/mmap.c:1491 + SYSC_mmap arch/x86/kernel/sys_x86_64.c:100 [inline] + SyS_mmap+0x16/0x20 arch/x86/kernel/sys_x86_64.c:91 + do_syscall_64+0x281/0x940 arch/x86/entry/common.c:287 + entry_SYSCALL_64_after_hwframe+0x42/0xb7 + + other info that might help us debug this: + + Possible unsafe locking scenario: + + CPU0 CPU1 + ---- ---- + lock(&mm->mmap_sem); + lock(bpf_event_mutex); + lock(&mm->mmap_sem); + lock(bpf_event_mutex); + + *** DEADLOCK *** + ====================================================== + +The bug is introduced by Commit f371b304f12e ("bpf/tracing: allow +user space to query prog array on the same tp") where copy_to_user, +which requires mm->mmap_sem, is called inside bpf_event_mutex lock. +At the same time, during perf_event file descriptor close, +mm->mmap_sem is held first and then subsequent +perf_event_detach_bpf_prog needs bpf_event_mutex lock. +Such a senario caused a deadlock. + +As suggested by Daniel, moving copy_to_user out of the +bpf_event_mutex lock should fix the problem. + +Fixes: f371b304f12e ("bpf/tracing: allow user space to query prog array on the same tp") +Reported-by: syzbot+dc5ca0e4c9bfafaf2bae@syzkaller.appspotmail.com +Signed-off-by: Yonghong Song +Signed-off-by: Daniel Borkmann +Signed-off-by: Greg Kroah-Hartman + +--- + include/linux/bpf.h | 4 ++-- + kernel/bpf/core.c | 45 +++++++++++++++++++++++++++++---------------- + kernel/trace/bpf_trace.c | 25 +++++++++++++++++++++---- + 3 files changed, 52 insertions(+), 22 deletions(-) + +--- a/include/linux/bpf.h ++++ b/include/linux/bpf.h +@@ -335,8 +335,8 @@ int bpf_prog_array_copy_to_user(struct b + void bpf_prog_array_delete_safe(struct bpf_prog_array __rcu *progs, + struct bpf_prog *old_prog); + int bpf_prog_array_copy_info(struct bpf_prog_array __rcu *array, +- __u32 __user *prog_ids, u32 request_cnt, +- __u32 __user *prog_cnt); ++ u32 *prog_ids, u32 request_cnt, ++ u32 *prog_cnt); + int bpf_prog_array_copy(struct bpf_prog_array __rcu *old_array, + struct bpf_prog *exclude_prog, + struct bpf_prog *include_prog, +--- a/kernel/bpf/core.c ++++ b/kernel/bpf/core.c +@@ -1572,13 +1572,32 @@ int bpf_prog_array_length(struct bpf_pro + return cnt; + } + ++static bool bpf_prog_array_copy_core(struct bpf_prog **prog, ++ u32 *prog_ids, ++ u32 request_cnt) ++{ ++ int i = 0; ++ ++ for (; *prog; prog++) { ++ if (*prog == &dummy_bpf_prog.prog) ++ continue; ++ prog_ids[i] = (*prog)->aux->id; ++ if (++i == request_cnt) { ++ prog++; ++ break; ++ } ++ } ++ ++ return !!(*prog); ++} ++ + int bpf_prog_array_copy_to_user(struct bpf_prog_array __rcu *progs, + __u32 __user *prog_ids, u32 cnt) + { + struct bpf_prog **prog; + unsigned long err = 0; +- u32 i = 0, *ids; + bool nospc; ++ u32 *ids; + + /* users of this function are doing: + * cnt = bpf_prog_array_length(); +@@ -1595,16 +1614,7 @@ int bpf_prog_array_copy_to_user(struct b + return -ENOMEM; + rcu_read_lock(); + prog = rcu_dereference(progs)->progs; +- for (; *prog; prog++) { +- if (*prog == &dummy_bpf_prog.prog) +- continue; +- ids[i] = (*prog)->aux->id; +- if (++i == cnt) { +- prog++; +- break; +- } +- } +- nospc = !!(*prog); ++ nospc = bpf_prog_array_copy_core(prog, ids, cnt); + rcu_read_unlock(); + err = copy_to_user(prog_ids, ids, cnt * sizeof(u32)); + kfree(ids); +@@ -1683,22 +1693,25 @@ int bpf_prog_array_copy(struct bpf_prog_ + } + + int bpf_prog_array_copy_info(struct bpf_prog_array __rcu *array, +- __u32 __user *prog_ids, u32 request_cnt, +- __u32 __user *prog_cnt) ++ u32 *prog_ids, u32 request_cnt, ++ u32 *prog_cnt) + { ++ struct bpf_prog **prog; + u32 cnt = 0; + + if (array) + cnt = bpf_prog_array_length(array); + +- if (copy_to_user(prog_cnt, &cnt, sizeof(cnt))) +- return -EFAULT; ++ *prog_cnt = cnt; + + /* return early if user requested only program count or nothing to copy */ + if (!request_cnt || !cnt) + return 0; + +- return bpf_prog_array_copy_to_user(array, prog_ids, request_cnt); ++ /* this function is called under trace/bpf_trace.c: bpf_event_mutex */ ++ prog = rcu_dereference_check(array, 1)->progs; ++ return bpf_prog_array_copy_core(prog, prog_ids, request_cnt) ? -ENOSPC ++ : 0; + } + + static void bpf_prog_free_deferred(struct work_struct *work) +--- a/kernel/trace/bpf_trace.c ++++ b/kernel/trace/bpf_trace.c +@@ -876,6 +876,7 @@ int perf_event_query_prog_array(struct p + { + struct perf_event_query_bpf __user *uquery = info; + struct perf_event_query_bpf query = {}; ++ u32 *ids, prog_cnt, ids_len; + int ret; + + if (!capable(CAP_SYS_ADMIN)) +@@ -884,15 +885,31 @@ int perf_event_query_prog_array(struct p + return -EINVAL; + if (copy_from_user(&query, uquery, sizeof(query))) + return -EFAULT; +- if (query.ids_len > BPF_TRACE_MAX_PROGS) ++ ++ ids_len = query.ids_len; ++ if (ids_len > BPF_TRACE_MAX_PROGS) + return -E2BIG; ++ ids = kcalloc(ids_len, sizeof(u32), GFP_USER | __GFP_NOWARN); ++ if (!ids) ++ return -ENOMEM; ++ /* ++ * The above kcalloc returns ZERO_SIZE_PTR when ids_len = 0, which ++ * is required when user only wants to check for uquery->prog_cnt. ++ * There is no need to check for it since the case is handled ++ * gracefully in bpf_prog_array_copy_info. ++ */ + + mutex_lock(&bpf_event_mutex); + ret = bpf_prog_array_copy_info(event->tp_event->prog_array, +- uquery->ids, +- query.ids_len, +- &uquery->prog_cnt); ++ ids, ++ ids_len, ++ &prog_cnt); + mutex_unlock(&bpf_event_mutex); + ++ if (copy_to_user(&uquery->prog_cnt, &prog_cnt, sizeof(prog_cnt)) || ++ copy_to_user(uquery->ids, ids, ids_len * sizeof(u32))) ++ ret = -EFAULT; ++ ++ kfree(ids); + return ret; + } diff --git a/queue-4.16/crypto-af_alg-fix-possible-uninit-value-in-alg_bind.patch b/queue-4.16/crypto-af_alg-fix-possible-uninit-value-in-alg_bind.patch new file mode 100644 index 00000000000..22b84d4eafe --- /dev/null +++ b/queue-4.16/crypto-af_alg-fix-possible-uninit-value-in-alg_bind.patch @@ -0,0 +1,50 @@ +From a466856e0b7ab269cdf9461886d007e88ff575b0 Mon Sep 17 00:00:00 2001 +From: Eric Dumazet +Date: Sat, 7 Apr 2018 13:42:36 -0700 +Subject: crypto: af_alg - fix possible uninit-value in alg_bind() + +From: Eric Dumazet + +commit a466856e0b7ab269cdf9461886d007e88ff575b0 upstream. + +syzbot reported : + +BUG: KMSAN: uninit-value in alg_bind+0xe3/0xd90 crypto/af_alg.c:162 + +We need to check addr_len before dereferencing sa (or uaddr) + +Fixes: bb30b8848c85 ("crypto: af_alg - whitelist mask and type") +Signed-off-by: Eric Dumazet +Reported-by: syzbot +Cc: Stephan Mueller +Cc: Herbert Xu +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman + +--- + crypto/af_alg.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +--- a/crypto/af_alg.c ++++ b/crypto/af_alg.c +@@ -158,16 +158,16 @@ static int alg_bind(struct socket *sock, + void *private; + int err; + +- /* If caller uses non-allowed flag, return error. */ +- if ((sa->salg_feat & ~allowed) || (sa->salg_mask & ~allowed)) +- return -EINVAL; +- + if (sock->state == SS_CONNECTED) + return -EINVAL; + + if (addr_len < sizeof(*sa)) + return -EINVAL; + ++ /* If caller uses non-allowed flag, return error. */ ++ if ((sa->salg_feat & ~allowed) || (sa->salg_mask & ~allowed)) ++ return -EINVAL; ++ + sa->salg_type[sizeof(sa->salg_type) - 1] = 0; + sa->salg_name[sizeof(sa->salg_name) + addr_len - sizeof(*sa) - 1] = 0; + diff --git a/queue-4.16/dccp-initialize-ireq-ir_mark.patch b/queue-4.16/dccp-initialize-ireq-ir_mark.patch new file mode 100644 index 00000000000..6a7d0eb551e --- /dev/null +++ b/queue-4.16/dccp-initialize-ireq-ir_mark.patch @@ -0,0 +1,154 @@ +From b855ff827476adbdc2259e9895681d82b7b26065 Mon Sep 17 00:00:00 2001 +From: Eric Dumazet +Date: Sat, 7 Apr 2018 13:42:41 -0700 +Subject: dccp: initialize ireq->ir_mark + +From: Eric Dumazet + +commit b855ff827476adbdc2259e9895681d82b7b26065 upstream. + +syzbot reported an uninit-value read of skb->mark in iptable_mangle_hook() + +Thanks to the nice report, I tracked the problem to dccp not caring +of ireq->ir_mark for passive sessions. + +BUG: KMSAN: uninit-value in ipt_mangle_out net/ipv4/netfilter/iptable_mangle.c:66 [inline] +BUG: KMSAN: uninit-value in iptable_mangle_hook+0x5e5/0x720 net/ipv4/netfilter/iptable_mangle.c:84 +CPU: 0 PID: 5300 Comm: syz-executor3 Not tainted 4.16.0+ #81 +Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/01/2011 +Call Trace: + __dump_stack lib/dump_stack.c:17 [inline] + dump_stack+0x185/0x1d0 lib/dump_stack.c:53 + kmsan_report+0x142/0x240 mm/kmsan/kmsan.c:1067 + __msan_warning_32+0x6c/0xb0 mm/kmsan/kmsan_instr.c:676 + ipt_mangle_out net/ipv4/netfilter/iptable_mangle.c:66 [inline] + iptable_mangle_hook+0x5e5/0x720 net/ipv4/netfilter/iptable_mangle.c:84 + nf_hook_entry_hookfn include/linux/netfilter.h:120 [inline] + nf_hook_slow+0x158/0x3d0 net/netfilter/core.c:483 + nf_hook include/linux/netfilter.h:243 [inline] + __ip_local_out net/ipv4/ip_output.c:113 [inline] + ip_local_out net/ipv4/ip_output.c:122 [inline] + ip_queue_xmit+0x1d21/0x21c0 net/ipv4/ip_output.c:504 + dccp_transmit_skb+0x15eb/0x1900 net/dccp/output.c:142 + dccp_xmit_packet+0x814/0x9e0 net/dccp/output.c:281 + dccp_write_xmit+0x20f/0x480 net/dccp/output.c:363 + dccp_sendmsg+0x12ca/0x12d0 net/dccp/proto.c:818 + inet_sendmsg+0x48d/0x740 net/ipv4/af_inet.c:764 + sock_sendmsg_nosec net/socket.c:630 [inline] + sock_sendmsg net/socket.c:640 [inline] + ___sys_sendmsg+0xec0/0x1310 net/socket.c:2046 + __sys_sendmsg net/socket.c:2080 [inline] + SYSC_sendmsg+0x2a3/0x3d0 net/socket.c:2091 + SyS_sendmsg+0x54/0x80 net/socket.c:2087 + do_syscall_64+0x309/0x430 arch/x86/entry/common.c:287 + entry_SYSCALL_64_after_hwframe+0x3d/0xa2 +RIP: 0033:0x455259 +RSP: 002b:00007f1a4473dc68 EFLAGS: 00000246 ORIG_RAX: 000000000000002e +RAX: ffffffffffffffda RBX: 00007f1a4473e6d4 RCX: 0000000000455259 +RDX: 0000000000000000 RSI: 0000000020b76fc8 RDI: 0000000000000015 +RBP: 000000000072bea0 R08: 0000000000000000 R09: 0000000000000000 +R10: 0000000000000000 R11: 0000000000000246 R12: 00000000ffffffff +R13: 00000000000004f0 R14: 00000000006fa720 R15: 0000000000000000 + +Uninit was stored to memory at: + kmsan_save_stack_with_flags mm/kmsan/kmsan.c:278 [inline] + kmsan_save_stack mm/kmsan/kmsan.c:293 [inline] + kmsan_internal_chain_origin+0x12b/0x210 mm/kmsan/kmsan.c:684 + __msan_chain_origin+0x69/0xc0 mm/kmsan/kmsan_instr.c:521 + ip_queue_xmit+0x1e35/0x21c0 net/ipv4/ip_output.c:502 + dccp_transmit_skb+0x15eb/0x1900 net/dccp/output.c:142 + dccp_xmit_packet+0x814/0x9e0 net/dccp/output.c:281 + dccp_write_xmit+0x20f/0x480 net/dccp/output.c:363 + dccp_sendmsg+0x12ca/0x12d0 net/dccp/proto.c:818 + inet_sendmsg+0x48d/0x740 net/ipv4/af_inet.c:764 + sock_sendmsg_nosec net/socket.c:630 [inline] + sock_sendmsg net/socket.c:640 [inline] + ___sys_sendmsg+0xec0/0x1310 net/socket.c:2046 + __sys_sendmsg net/socket.c:2080 [inline] + SYSC_sendmsg+0x2a3/0x3d0 net/socket.c:2091 + SyS_sendmsg+0x54/0x80 net/socket.c:2087 + do_syscall_64+0x309/0x430 arch/x86/entry/common.c:287 + entry_SYSCALL_64_after_hwframe+0x3d/0xa2 +Uninit was stored to memory at: + kmsan_save_stack_with_flags mm/kmsan/kmsan.c:278 [inline] + kmsan_save_stack mm/kmsan/kmsan.c:293 [inline] + kmsan_internal_chain_origin+0x12b/0x210 mm/kmsan/kmsan.c:684 + __msan_chain_origin+0x69/0xc0 mm/kmsan/kmsan_instr.c:521 + inet_csk_clone_lock+0x503/0x580 net/ipv4/inet_connection_sock.c:797 + dccp_create_openreq_child+0x7f/0x890 net/dccp/minisocks.c:92 + dccp_v4_request_recv_sock+0x22c/0xe90 net/dccp/ipv4.c:408 + dccp_v6_request_recv_sock+0x290/0x2000 net/dccp/ipv6.c:414 + dccp_check_req+0x7b9/0x8f0 net/dccp/minisocks.c:197 + dccp_v4_rcv+0x12e4/0x2630 net/dccp/ipv4.c:840 + ip_local_deliver_finish+0x6ed/0xd40 net/ipv4/ip_input.c:216 + NF_HOOK include/linux/netfilter.h:288 [inline] + ip_local_deliver+0x43c/0x4e0 net/ipv4/ip_input.c:257 + dst_input include/net/dst.h:449 [inline] + ip_rcv_finish+0x1253/0x16d0 net/ipv4/ip_input.c:397 + NF_HOOK include/linux/netfilter.h:288 [inline] + ip_rcv+0x119d/0x16f0 net/ipv4/ip_input.c:493 + __netif_receive_skb_core+0x47cf/0x4a80 net/core/dev.c:4562 + __netif_receive_skb net/core/dev.c:4627 [inline] + process_backlog+0x62d/0xe20 net/core/dev.c:5307 + napi_poll net/core/dev.c:5705 [inline] + net_rx_action+0x7c1/0x1a70 net/core/dev.c:5771 + __do_softirq+0x56d/0x93d kernel/softirq.c:285 +Uninit was created at: + kmsan_save_stack_with_flags mm/kmsan/kmsan.c:278 [inline] + kmsan_internal_poison_shadow+0xb8/0x1b0 mm/kmsan/kmsan.c:188 + kmsan_kmalloc+0x94/0x100 mm/kmsan/kmsan.c:314 + kmem_cache_alloc+0xaab/0xb90 mm/slub.c:2756 + reqsk_alloc include/net/request_sock.h:88 [inline] + inet_reqsk_alloc+0xc4/0x7f0 net/ipv4/tcp_input.c:6145 + dccp_v4_conn_request+0x5cc/0x1770 net/dccp/ipv4.c:600 + dccp_v6_conn_request+0x299/0x1880 net/dccp/ipv6.c:317 + dccp_rcv_state_process+0x2ea/0x2410 net/dccp/input.c:612 + dccp_v4_do_rcv+0x229/0x340 net/dccp/ipv4.c:682 + dccp_v6_do_rcv+0x16d/0x1220 net/dccp/ipv6.c:578 + sk_backlog_rcv include/net/sock.h:908 [inline] + __sk_receive_skb+0x60e/0xf20 net/core/sock.c:513 + dccp_v4_rcv+0x24d4/0x2630 net/dccp/ipv4.c:874 + ip_local_deliver_finish+0x6ed/0xd40 net/ipv4/ip_input.c:216 + NF_HOOK include/linux/netfilter.h:288 [inline] + ip_local_deliver+0x43c/0x4e0 net/ipv4/ip_input.c:257 + dst_input include/net/dst.h:449 [inline] + ip_rcv_finish+0x1253/0x16d0 net/ipv4/ip_input.c:397 + NF_HOOK include/linux/netfilter.h:288 [inline] + ip_rcv+0x119d/0x16f0 net/ipv4/ip_input.c:493 + __netif_receive_skb_core+0x47cf/0x4a80 net/core/dev.c:4562 + __netif_receive_skb net/core/dev.c:4627 [inline] + process_backlog+0x62d/0xe20 net/core/dev.c:5307 + napi_poll net/core/dev.c:5705 [inline] + net_rx_action+0x7c1/0x1a70 net/core/dev.c:5771 + __do_softirq+0x56d/0x93d kernel/softirq.c:285 + +Signed-off-by: Eric Dumazet +Reported-by: syzbot +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman + +--- + net/dccp/ipv4.c | 1 + + net/dccp/ipv6.c | 1 + + 2 files changed, 2 insertions(+) + +--- a/net/dccp/ipv4.c ++++ b/net/dccp/ipv4.c +@@ -614,6 +614,7 @@ int dccp_v4_conn_request(struct sock *sk + ireq = inet_rsk(req); + sk_rcv_saddr_set(req_to_sk(req), ip_hdr(skb)->daddr); + sk_daddr_set(req_to_sk(req), ip_hdr(skb)->saddr); ++ ireq->ir_mark = inet_request_mark(sk, skb); + ireq->ireq_family = AF_INET; + ireq->ir_iif = sk->sk_bound_dev_if; + +--- a/net/dccp/ipv6.c ++++ b/net/dccp/ipv6.c +@@ -351,6 +351,7 @@ static int dccp_v6_conn_request(struct s + ireq->ir_v6_rmt_addr = ipv6_hdr(skb)->saddr; + ireq->ir_v6_loc_addr = ipv6_hdr(skb)->daddr; + ireq->ireq_family = AF_INET6; ++ ireq->ir_mark = inet_request_mark(sk, skb); + + if (ipv6_opt_accepted(sk, skb, IP6CB(skb)) || + np->rxopt.bits.rxinfo || np->rxopt.bits.rxoinfo || diff --git a/queue-4.16/i2c-dev-prevent-zero_size_ptr-deref-in-i2cdev_ioctl_rdwr.patch b/queue-4.16/i2c-dev-prevent-zero_size_ptr-deref-in-i2cdev_ioctl_rdwr.patch new file mode 100644 index 00000000000..fb59afee1f6 --- /dev/null +++ b/queue-4.16/i2c-dev-prevent-zero_size_ptr-deref-in-i2cdev_ioctl_rdwr.patch @@ -0,0 +1,44 @@ +From 23a27722b5292ef0b27403c87a109feea8296a5c Mon Sep 17 00:00:00 2001 +From: Alexander Popov +Date: Thu, 19 Apr 2018 15:29:22 +0300 +Subject: i2c: dev: prevent ZERO_SIZE_PTR deref in i2cdev_ioctl_rdwr() +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Alexander Popov + +commit 23a27722b5292ef0b27403c87a109feea8296a5c upstream. + +i2cdev_ioctl_rdwr() allocates i2c_msg.buf using memdup_user(), which +returns ZERO_SIZE_PTR if i2c_msg.len is zero. + +Currently i2cdev_ioctl_rdwr() always dereferences the buf pointer in case +of I2C_M_RD | I2C_M_RECV_LEN transfer. That causes a kernel oops in +case of zero len. + +Let's check the len against zero before dereferencing buf pointer. + +This issue was triggered by syzkaller. + +Signed-off-by: Alexander Popov +Reviewed-by: Uwe Kleine-König +[wsa: use '< 1' instead of '!' for easier readability] +Signed-off-by: Wolfram Sang +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/i2c/i2c-dev.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/i2c/i2c-dev.c ++++ b/drivers/i2c/i2c-dev.c +@@ -280,7 +280,7 @@ static noinline int i2cdev_ioctl_rdwr(st + */ + if (msgs[i].flags & I2C_M_RECV_LEN) { + if (!(msgs[i].flags & I2C_M_RD) || +- msgs[i].buf[0] < 1 || ++ msgs[i].len < 1 || msgs[i].buf[0] < 1 || + msgs[i].len < msgs[i].buf[0] + + I2C_SMBUS_BLOCK_MAX) { + res = -EINVAL; diff --git a/queue-4.16/inetpeer-fix-uninit-value-in-inet_getpeer.patch b/queue-4.16/inetpeer-fix-uninit-value-in-inet_getpeer.patch new file mode 100644 index 00000000000..4b0db208f8f --- /dev/null +++ b/queue-4.16/inetpeer-fix-uninit-value-in-inet_getpeer.patch @@ -0,0 +1,118 @@ +From b6a37e5e25414df4b8e9140a5c6f5ee0ec6f3b90 Mon Sep 17 00:00:00 2001 +From: Eric Dumazet +Date: Mon, 9 Apr 2018 06:43:27 -0700 +Subject: inetpeer: fix uninit-value in inet_getpeer + +From: Eric Dumazet + +commit b6a37e5e25414df4b8e9140a5c6f5ee0ec6f3b90 upstream. + +syzbot/KMSAN reported that p->dtime was read while it was +not yet initialized in : + + delta = (__u32)jiffies - p->dtime; + if (delta < ttl || !refcount_dec_if_one(&p->refcnt)) + gc_stack[i] = NULL; + +This is a false positive, because the inetpeer wont be erased +from rb-tree if the refcount_dec_if_one(&p->refcnt) does not +succeed. And this wont happen before first inet_putpeer() call +for this inetpeer has been done, and ->dtime field is written +exactly before the refcount_dec_and_test(&p->refcnt). + +The KMSAN report was : + +BUG: KMSAN: uninit-value in inet_peer_gc net/ipv4/inetpeer.c:163 [inline] +BUG: KMSAN: uninit-value in inet_getpeer+0x1567/0x1e70 net/ipv4/inetpeer.c:228 +CPU: 0 PID: 9494 Comm: syz-executor5 Not tainted 4.16.0+ #82 +Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/01/2011 +Call Trace: + __dump_stack lib/dump_stack.c:17 [inline] + dump_stack+0x185/0x1d0 lib/dump_stack.c:53 + kmsan_report+0x142/0x240 mm/kmsan/kmsan.c:1067 + __msan_warning_32+0x6c/0xb0 mm/kmsan/kmsan_instr.c:676 + inet_peer_gc net/ipv4/inetpeer.c:163 [inline] + inet_getpeer+0x1567/0x1e70 net/ipv4/inetpeer.c:228 + inet_getpeer_v4 include/net/inetpeer.h:110 [inline] + icmpv4_xrlim_allow net/ipv4/icmp.c:330 [inline] + icmp_send+0x2b44/0x3050 net/ipv4/icmp.c:725 + ip_options_compile+0x237c/0x29f0 net/ipv4/ip_options.c:472 + ip_rcv_options net/ipv4/ip_input.c:284 [inline] + ip_rcv_finish+0xda8/0x16d0 net/ipv4/ip_input.c:365 + NF_HOOK include/linux/netfilter.h:288 [inline] + ip_rcv+0x119d/0x16f0 net/ipv4/ip_input.c:493 + __netif_receive_skb_core+0x47cf/0x4a80 net/core/dev.c:4562 + __netif_receive_skb net/core/dev.c:4627 [inline] + netif_receive_skb_internal+0x49d/0x630 net/core/dev.c:4701 + netif_receive_skb+0x230/0x240 net/core/dev.c:4725 + tun_rx_batched drivers/net/tun.c:1555 [inline] + tun_get_user+0x6d88/0x7580 drivers/net/tun.c:1962 + tun_chr_write_iter+0x1d4/0x330 drivers/net/tun.c:1990 + do_iter_readv_writev+0x7bb/0x970 include/linux/fs.h:1776 + do_iter_write+0x30d/0xd40 fs/read_write.c:932 + vfs_writev fs/read_write.c:977 [inline] + do_writev+0x3c9/0x830 fs/read_write.c:1012 + SYSC_writev+0x9b/0xb0 fs/read_write.c:1085 + SyS_writev+0x56/0x80 fs/read_write.c:1082 + do_syscall_64+0x309/0x430 arch/x86/entry/common.c:287 + entry_SYSCALL_64_after_hwframe+0x3d/0xa2 +RIP: 0033:0x455111 +RSP: 002b:00007fae0365cba0 EFLAGS: 00000293 ORIG_RAX: 0000000000000014 +RAX: ffffffffffffffda RBX: 000000000000002e RCX: 0000000000455111 +RDX: 0000000000000001 RSI: 00007fae0365cbf0 RDI: 00000000000000fc +RBP: 0000000020000040 R08: 00000000000000fc R09: 0000000000000000 +R10: 000000000000002e R11: 0000000000000293 R12: 00000000ffffffff +R13: 0000000000000658 R14: 00000000006fc8e0 R15: 0000000000000000 + +Uninit was created at: + kmsan_save_stack_with_flags mm/kmsan/kmsan.c:278 [inline] + kmsan_internal_poison_shadow+0xb8/0x1b0 mm/kmsan/kmsan.c:188 + kmsan_kmalloc+0x94/0x100 mm/kmsan/kmsan.c:314 + kmem_cache_alloc+0xaab/0xb90 mm/slub.c:2756 + inet_getpeer+0xed8/0x1e70 net/ipv4/inetpeer.c:210 + inet_getpeer_v4 include/net/inetpeer.h:110 [inline] + ip4_frag_init+0x4d1/0x740 net/ipv4/ip_fragment.c:153 + inet_frag_alloc net/ipv4/inet_fragment.c:369 [inline] + inet_frag_create net/ipv4/inet_fragment.c:385 [inline] + inet_frag_find+0x7da/0x1610 net/ipv4/inet_fragment.c:418 + ip_find net/ipv4/ip_fragment.c:275 [inline] + ip_defrag+0x448/0x67a0 net/ipv4/ip_fragment.c:676 + ip_check_defrag+0x775/0xda0 net/ipv4/ip_fragment.c:724 + packet_rcv_fanout+0x2a8/0x8d0 net/packet/af_packet.c:1447 + deliver_skb net/core/dev.c:1897 [inline] + deliver_ptype_list_skb net/core/dev.c:1912 [inline] + __netif_receive_skb_core+0x314a/0x4a80 net/core/dev.c:4545 + __netif_receive_skb net/core/dev.c:4627 [inline] + netif_receive_skb_internal+0x49d/0x630 net/core/dev.c:4701 + netif_receive_skb+0x230/0x240 net/core/dev.c:4725 + tun_rx_batched drivers/net/tun.c:1555 [inline] + tun_get_user+0x6d88/0x7580 drivers/net/tun.c:1962 + tun_chr_write_iter+0x1d4/0x330 drivers/net/tun.c:1990 + do_iter_readv_writev+0x7bb/0x970 include/linux/fs.h:1776 + do_iter_write+0x30d/0xd40 fs/read_write.c:932 + vfs_writev fs/read_write.c:977 [inline] + do_writev+0x3c9/0x830 fs/read_write.c:1012 + SYSC_writev+0x9b/0xb0 fs/read_write.c:1085 + SyS_writev+0x56/0x80 fs/read_write.c:1082 + do_syscall_64+0x309/0x430 arch/x86/entry/common.c:287 + entry_SYSCALL_64_after_hwframe+0x3d/0xa2 + +Signed-off-by: Eric Dumazet +Reported-by: syzbot +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman + +--- + net/ipv4/inetpeer.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/net/ipv4/inetpeer.c ++++ b/net/ipv4/inetpeer.c +@@ -210,6 +210,7 @@ struct inet_peer *inet_getpeer(struct in + p = kmem_cache_alloc(peer_cachep, GFP_ATOMIC); + if (p) { + p->daddr = *daddr; ++ p->dtime = (__u32)jiffies; + refcount_set(&p->refcnt, 2); + atomic_set(&p->rid, 0); + p->metrics[RTAX_LOCK-1] = INETPEER_METRICS_NEW; diff --git a/queue-4.16/ipv4-fix-uninit-value-in-ip_route_output_key_hash_rcu.patch b/queue-4.16/ipv4-fix-uninit-value-in-ip_route_output_key_hash_rcu.patch new file mode 100644 index 00000000000..1ff5b57b244 --- /dev/null +++ b/queue-4.16/ipv4-fix-uninit-value-in-ip_route_output_key_hash_rcu.patch @@ -0,0 +1,78 @@ +From d0ea2b12500543535be3f54e17920fffc9bb45f6 Mon Sep 17 00:00:00 2001 +From: Eric Dumazet +Date: Sat, 7 Apr 2018 13:42:42 -0700 +Subject: ipv4: fix uninit-value in ip_route_output_key_hash_rcu() + +From: Eric Dumazet + +commit d0ea2b12500543535be3f54e17920fffc9bb45f6 upstream. + +syzbot complained that res.type could be used while not initialized. + +Using RTN_UNSPEC as initial value seems better than using garbage. + +BUG: KMSAN: uninit-value in __mkroute_output net/ipv4/route.c:2200 [inline] +BUG: KMSAN: uninit-value in ip_route_output_key_hash_rcu+0x31f0/0x3940 net/ipv4/route.c:2493 +CPU: 1 PID: 12207 Comm: syz-executor0 Not tainted 4.16.0+ #81 +Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/01/2011 +Call Trace: + __dump_stack lib/dump_stack.c:17 [inline] + dump_stack+0x185/0x1d0 lib/dump_stack.c:53 + kmsan_report+0x142/0x240 mm/kmsan/kmsan.c:1067 + __msan_warning_32+0x6c/0xb0 mm/kmsan/kmsan_instr.c:676 + __mkroute_output net/ipv4/route.c:2200 [inline] + ip_route_output_key_hash_rcu+0x31f0/0x3940 net/ipv4/route.c:2493 + ip_route_output_key_hash net/ipv4/route.c:2322 [inline] + __ip_route_output_key include/net/route.h:126 [inline] + ip_route_output_flow+0x1eb/0x3c0 net/ipv4/route.c:2577 + raw_sendmsg+0x1861/0x3ed0 net/ipv4/raw.c:653 + inet_sendmsg+0x48d/0x740 net/ipv4/af_inet.c:764 + sock_sendmsg_nosec net/socket.c:630 [inline] + sock_sendmsg net/socket.c:640 [inline] + SYSC_sendto+0x6c3/0x7e0 net/socket.c:1747 + SyS_sendto+0x8a/0xb0 net/socket.c:1715 + do_syscall_64+0x309/0x430 arch/x86/entry/common.c:287 + entry_SYSCALL_64_after_hwframe+0x3d/0xa2 +RIP: 0033:0x455259 +RSP: 002b:00007fdc0625dc68 EFLAGS: 00000246 ORIG_RAX: 000000000000002c +RAX: ffffffffffffffda RBX: 00007fdc0625e6d4 RCX: 0000000000455259 +RDX: 0000000000000000 RSI: 0000000020000040 RDI: 0000000000000013 +RBP: 000000000072bea0 R08: 0000000020000080 R09: 0000000000000010 +R10: 0000000000000000 R11: 0000000000000246 R12: 00000000ffffffff +R13: 00000000000004f7 R14: 00000000006fa7c8 R15: 0000000000000000 + +Local variable description: ----res.i.i@ip_route_output_flow +Variable was created at: + ip_route_output_flow+0x75/0x3c0 net/ipv4/route.c:2576 + raw_sendmsg+0x1861/0x3ed0 net/ipv4/raw.c:653 + +Signed-off-by: Eric Dumazet +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman + +--- + net/ipv4/route.c | 11 ++++++----- + 1 file changed, 6 insertions(+), 5 deletions(-) + +--- a/net/ipv4/route.c ++++ b/net/ipv4/route.c +@@ -2306,13 +2306,14 @@ struct rtable *ip_route_output_key_hash( + const struct sk_buff *skb) + { + __u8 tos = RT_FL_TOS(fl4); +- struct fib_result res; ++ struct fib_result res = { ++ .type = RTN_UNSPEC, ++ .fi = NULL, ++ .table = NULL, ++ .tclassid = 0, ++ }; + struct rtable *rth; + +- res.tclassid = 0; +- res.fi = NULL; +- res.table = NULL; +- + fl4->flowi4_iif = LOOPBACK_IFINDEX; + fl4->flowi4_tos = tos & IPTOS_RT_MASK; + fl4->flowi4_scope = ((tos & RTO_ONLINK) ? diff --git a/queue-4.16/kcm-call-strp_stop-before-strp_done-in-kcm_attach.patch b/queue-4.16/kcm-call-strp_stop-before-strp_done-in-kcm_attach.patch new file mode 100644 index 00000000000..71789cf19ee --- /dev/null +++ b/queue-4.16/kcm-call-strp_stop-before-strp_done-in-kcm_attach.patch @@ -0,0 +1,34 @@ +From dff8baa261174de689a44572d0ea182d7aa70598 Mon Sep 17 00:00:00 2001 +From: Tom Herbert +Date: Wed, 14 Feb 2018 09:22:42 -0800 +Subject: kcm: Call strp_stop before strp_done in kcm_attach + +From: Tom Herbert + +commit dff8baa261174de689a44572d0ea182d7aa70598 upstream. + +In kcm_attach strp_done is called when sk_user_data is already +set to fail the attach. strp_done needs the strp to be stopped and +warns if it isn't. Call strp_stop in this case to eliminate the +warning message. + +Reported-by: syzbot+88dfb55e4c8b770d86e3@syzkaller.appspotmail.com +Fixes: e5571240236c5652f ("kcm: Check if sk_user_data already set in kcm_attach" +Signed-off-by: Tom Herbert +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman + +--- + net/kcm/kcmsock.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/net/kcm/kcmsock.c ++++ b/net/kcm/kcmsock.c +@@ -1425,6 +1425,7 @@ static int kcm_attach(struct socket *soc + */ + if (csk->sk_user_data) { + write_unlock_bh(&csk->sk_callback_lock); ++ strp_stop(&psock->strp); + strp_done(&psock->strp); + kmem_cache_free(kcm_psockp, psock); + err = -EALREADY; diff --git a/queue-4.16/memcg-fix-per_node_info-cleanup.patch b/queue-4.16/memcg-fix-per_node_info-cleanup.patch new file mode 100644 index 00000000000..98aee4e31fb --- /dev/null +++ b/queue-4.16/memcg-fix-per_node_info-cleanup.patch @@ -0,0 +1,47 @@ +From 4eaf431f6f71bbed40a4c733ffe93a7e8cedf9d9 Mon Sep 17 00:00:00 2001 +From: Michal Hocko +Date: Tue, 10 Apr 2018 16:29:52 -0700 +Subject: memcg: fix per_node_info cleanup + +From: Michal Hocko + +commit 4eaf431f6f71bbed40a4c733ffe93a7e8cedf9d9 upstream. + +syzbot has triggered a NULL ptr dereference when allocation fault +injection enforces a failure and alloc_mem_cgroup_per_node_info +initializes memcg->nodeinfo only half way through. + +But __mem_cgroup_free still tries to free all per-node data and +dereferences pn->lruvec_stat_cpu unconditioanlly even if the specific +per-node data hasn't been initialized. + +The bug is quite unlikely to hit because small allocations do not fail +and we would need quite some numa nodes to make struct +mem_cgroup_per_node large enough to cross the costly order. + +Link: http://lkml.kernel.org/r/20180406100906.17790-1-mhocko@kernel.org +Reported-by: syzbot+8a5de3cce7cdc70e9ebe@syzkaller.appspotmail.com +Fixes: 00f3ca2c2d66 ("mm: memcontrol: per-lruvec stats infrastructure") +Signed-off-by: Michal Hocko +Reviewed-by: Andrey Ryabinin +Cc: Johannes Weiner +Signed-off-by: Andrew Morton +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- + mm/memcontrol.c | 3 +++ + 1 file changed, 3 insertions(+) + +--- a/mm/memcontrol.c ++++ b/mm/memcontrol.c +@@ -4108,6 +4108,9 @@ static void free_mem_cgroup_per_node_inf + { + struct mem_cgroup_per_node *pn = memcg->nodeinfo[node]; + ++ if (!pn) ++ return; ++ + free_percpu(pn->lruvec_stat_cpu); + kfree(pn); + } diff --git a/queue-4.16/net-fix-rtnh_ok.patch b/queue-4.16/net-fix-rtnh_ok.patch new file mode 100644 index 00000000000..91204613a6c --- /dev/null +++ b/queue-4.16/net-fix-rtnh_ok.patch @@ -0,0 +1,39 @@ +From b1993a2de12c9e75c35729e2ffbc3a92d50c0d31 Mon Sep 17 00:00:00 2001 +From: Eric Dumazet +Date: Sat, 7 Apr 2018 13:42:38 -0700 +Subject: net: fix rtnh_ok() + +From: Eric Dumazet + +commit b1993a2de12c9e75c35729e2ffbc3a92d50c0d31 upstream. + +syzbot reported : + +BUG: KMSAN: uninit-value in rtnh_ok include/net/nexthop.h:11 [inline] +BUG: KMSAN: uninit-value in fib_count_nexthops net/ipv4/fib_semantics.c:469 [inline] +BUG: KMSAN: uninit-value in fib_create_info+0x554/0x8d20 net/ipv4/fib_semantics.c:1091 + +@remaining is an integer, coming from user space. +If it is negative we want rtnh_ok() to return false. + +Fixes: 4e902c57417c ("[IPv4]: FIB configuration using struct fib_config") +Signed-off-by: Eric Dumazet +Reported-by: syzbot +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman + +--- + include/net/nexthop.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/include/net/nexthop.h ++++ b/include/net/nexthop.h +@@ -7,7 +7,7 @@ + + static inline int rtnh_ok(const struct rtnexthop *rtnh, int remaining) + { +- return remaining >= sizeof(*rtnh) && ++ return remaining >= (int)sizeof(*rtnh) && + rtnh->rtnh_len >= sizeof(*rtnh) && + rtnh->rtnh_len <= remaining; + } diff --git a/queue-4.16/net-fix-uninit-value-in-__hw_addr_add_ex.patch b/queue-4.16/net-fix-uninit-value-in-__hw_addr_add_ex.patch new file mode 100644 index 00000000000..ad3e1f3bc84 --- /dev/null +++ b/queue-4.16/net-fix-uninit-value-in-__hw_addr_add_ex.patch @@ -0,0 +1,56 @@ +From 77d36398d99f2565c0a8d43a86fd520a82e64bb8 Mon Sep 17 00:00:00 2001 +From: Eric Dumazet +Date: Sat, 7 Apr 2018 13:42:40 -0700 +Subject: net: fix uninit-value in __hw_addr_add_ex() + +From: Eric Dumazet + +commit 77d36398d99f2565c0a8d43a86fd520a82e64bb8 upstream. + +syzbot complained : + +BUG: KMSAN: uninit-value in memcmp+0x119/0x180 lib/string.c:861 +CPU: 0 PID: 3 Comm: kworker/0:0 Not tainted 4.16.0+ #82 +Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/01/2011 +Workqueue: ipv6_addrconf addrconf_dad_work +Call Trace: + __dump_stack lib/dump_stack.c:17 [inline] + dump_stack+0x185/0x1d0 lib/dump_stack.c:53 + kmsan_report+0x142/0x240 mm/kmsan/kmsan.c:1067 + __msan_warning_32+0x6c/0xb0 mm/kmsan/kmsan_instr.c:676 + memcmp+0x119/0x180 lib/string.c:861 + __hw_addr_add_ex net/core/dev_addr_lists.c:60 [inline] + __dev_mc_add+0x1c2/0x8e0 net/core/dev_addr_lists.c:670 + dev_mc_add+0x6d/0x80 net/core/dev_addr_lists.c:687 + igmp6_group_added+0x2db/0xa00 net/ipv6/mcast.c:662 + ipv6_dev_mc_inc+0xe9e/0x1130 net/ipv6/mcast.c:914 + addrconf_join_solict net/ipv6/addrconf.c:2078 [inline] + addrconf_dad_begin net/ipv6/addrconf.c:3828 [inline] + addrconf_dad_work+0x427/0x2150 net/ipv6/addrconf.c:3954 + process_one_work+0x12c6/0x1f60 kernel/workqueue.c:2113 + worker_thread+0x113c/0x24f0 kernel/workqueue.c:2247 + kthread+0x539/0x720 kernel/kthread.c:239 + +Fixes: f001fde5eadd ("net: introduce a list of device addresses dev_addr_list (v6)") +Signed-off-by: Eric Dumazet +Reported-by: syzbot +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman + +--- + net/core/dev_addr_lists.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/net/core/dev_addr_lists.c ++++ b/net/core/dev_addr_lists.c +@@ -57,8 +57,8 @@ static int __hw_addr_add_ex(struct netde + return -EINVAL; + + list_for_each_entry(ha, &list->list, list) { +- if (!memcmp(ha->addr, addr, addr_len) && +- ha->type == addr_type) { ++ if (ha->type == addr_type && ++ !memcmp(ha->addr, addr, addr_len)) { + if (global) { + /* check if addr is already used as global */ + if (ha->global_use) diff --git a/queue-4.16/net-initialize-skb-peeked-when-cloning.patch b/queue-4.16/net-initialize-skb-peeked-when-cloning.patch new file mode 100644 index 00000000000..aa51d438fe5 --- /dev/null +++ b/queue-4.16/net-initialize-skb-peeked-when-cloning.patch @@ -0,0 +1,34 @@ +From b13dda9f9aa7caceeee61c080c2e544d5f5d85e5 Mon Sep 17 00:00:00 2001 +From: Eric Dumazet +Date: Sat, 7 Apr 2018 13:42:39 -0700 +Subject: net: initialize skb->peeked when cloning + +From: Eric Dumazet + +commit b13dda9f9aa7caceeee61c080c2e544d5f5d85e5 upstream. + +syzbot reported __skb_try_recv_from_queue() was using skb->peeked +while it was potentially unitialized. + +We need to clear it in __skb_clone() + +Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") +Signed-off-by: Eric Dumazet +Reported-by: syzbot +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman + +--- + net/core/skbuff.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/net/core/skbuff.c ++++ b/net/core/skbuff.c +@@ -857,6 +857,7 @@ static struct sk_buff *__skb_clone(struc + n->hdr_len = skb->nohdr ? skb_headroom(skb) : skb->hdr_len; + n->cloned = 1; + n->nohdr = 0; ++ n->peeked = 0; + n->destructor = NULL; + C(tail); + C(end); diff --git a/queue-4.16/netfilter-x_tables-ensure-last-rule-in-base-chain-matches-underflow-policy.patch b/queue-4.16/netfilter-x_tables-ensure-last-rule-in-base-chain-matches-underflow-policy.patch new file mode 100644 index 00000000000..4d50db6fcfe --- /dev/null +++ b/queue-4.16/netfilter-x_tables-ensure-last-rule-in-base-chain-matches-underflow-policy.patch @@ -0,0 +1,192 @@ +From 0d7df906a0e78079a02108b06d32c3ef2238ad25 Mon Sep 17 00:00:00 2001 +From: Florian Westphal +Date: Tue, 27 Feb 2018 19:42:37 +0100 +Subject: netfilter: x_tables: ensure last rule in base chain matches underflow/policy + +From: Florian Westphal + +commit 0d7df906a0e78079a02108b06d32c3ef2238ad25 upstream. + +Harmless from kernel point of view, but again iptables assumes that +this is true when decoding ruleset coming from kernel. + +If a (syzkaller generated) ruleset doesn't have the underflow/policy +stored as the last rule in the base chain, then iptables will abort() +because it doesn't find the chain policy. + +libiptc assumes that the policy is the last rule in the basechain, which +is only true for iptables-generated rulesets. + +Unfortunately this needs code duplication -- the functions need the +struct layout of the rule head, but that is different for +ip/ip6/arptables. + +NB: pr_warn could be pr_debug but in case this break rulesets somehow its +useful to know why blob was rejected. + +Signed-off-by: Florian Westphal +Signed-off-by: Pablo Neira Ayuso +Signed-off-by: Greg Kroah-Hartman + +--- + net/ipv4/netfilter/arp_tables.c | 17 ++++++++++++++++- + net/ipv4/netfilter/ip_tables.c | 17 ++++++++++++++++- + net/ipv6/netfilter/ip6_tables.c | 17 ++++++++++++++++- + 3 files changed, 48 insertions(+), 3 deletions(-) + +--- a/net/ipv4/netfilter/arp_tables.c ++++ b/net/ipv4/netfilter/arp_tables.c +@@ -309,10 +309,13 @@ static int mark_source_chains(const stru + for (hook = 0; hook < NF_ARP_NUMHOOKS; hook++) { + unsigned int pos = newinfo->hook_entry[hook]; + struct arpt_entry *e = entry0 + pos; ++ unsigned int last_pos, depth; + + if (!(valid_hooks & (1 << hook))) + continue; + ++ depth = 0; ++ last_pos = pos; + /* Set initial back pointer. */ + e->counters.pcnt = pos; + +@@ -348,6 +351,8 @@ static int mark_source_chains(const stru + pos = e->counters.pcnt; + e->counters.pcnt = 0; + ++ if (depth) ++ --depth; + /* We're at the start. */ + if (pos == oldpos) + goto next; +@@ -372,6 +377,9 @@ static int mark_source_chains(const stru + if (!xt_find_jump_offset(offsets, newpos, + newinfo->number)) + return 0; ++ ++ if (entry0 + newpos != arpt_next_entry(e)) ++ ++depth; + } else { + /* ... this is a fallthru */ + newpos = pos + e->next_offset; +@@ -382,8 +390,15 @@ static int mark_source_chains(const stru + e->counters.pcnt = pos; + pos = newpos; + } ++ if (depth == 0) ++ last_pos = pos; ++ } ++next: ++ if (last_pos != newinfo->underflow[hook]) { ++ pr_err_ratelimited("last base chain position %u doesn't match underflow %u (hook %u)\n", ++ last_pos, newinfo->underflow[hook], hook); ++ return 0; + } +-next: ; + } + return 1; + } +--- a/net/ipv4/netfilter/ip_tables.c ++++ b/net/ipv4/netfilter/ip_tables.c +@@ -378,10 +378,13 @@ mark_source_chains(const struct xt_table + for (hook = 0; hook < NF_INET_NUMHOOKS; hook++) { + unsigned int pos = newinfo->hook_entry[hook]; + struct ipt_entry *e = entry0 + pos; ++ unsigned int last_pos, depth; + + if (!(valid_hooks & (1 << hook))) + continue; + ++ depth = 0; ++ last_pos = pos; + /* Set initial back pointer. */ + e->counters.pcnt = pos; + +@@ -415,6 +418,8 @@ mark_source_chains(const struct xt_table + pos = e->counters.pcnt; + e->counters.pcnt = 0; + ++ if (depth) ++ --depth; + /* We're at the start. */ + if (pos == oldpos) + goto next; +@@ -439,6 +444,9 @@ mark_source_chains(const struct xt_table + if (!xt_find_jump_offset(offsets, newpos, + newinfo->number)) + return 0; ++ ++ if (entry0 + newpos != ipt_next_entry(e)) ++ ++depth; + } else { + /* ... this is a fallthru */ + newpos = pos + e->next_offset; +@@ -449,8 +457,15 @@ mark_source_chains(const struct xt_table + e->counters.pcnt = pos; + pos = newpos; + } ++ if (depth == 0) ++ last_pos = pos; ++ } ++next: ++ if (last_pos != newinfo->underflow[hook]) { ++ pr_err_ratelimited("last base chain position %u doesn't match underflow %u (hook %u)\n", ++ last_pos, newinfo->underflow[hook], hook); ++ return 0; + } +-next: ; + } + return 1; + } +--- a/net/ipv6/netfilter/ip6_tables.c ++++ b/net/ipv6/netfilter/ip6_tables.c +@@ -396,10 +396,13 @@ mark_source_chains(const struct xt_table + for (hook = 0; hook < NF_INET_NUMHOOKS; hook++) { + unsigned int pos = newinfo->hook_entry[hook]; + struct ip6t_entry *e = entry0 + pos; ++ unsigned int last_pos, depth; + + if (!(valid_hooks & (1 << hook))) + continue; + ++ depth = 0; ++ last_pos = pos; + /* Set initial back pointer. */ + e->counters.pcnt = pos; + +@@ -433,6 +436,8 @@ mark_source_chains(const struct xt_table + pos = e->counters.pcnt; + e->counters.pcnt = 0; + ++ if (depth) ++ --depth; + /* We're at the start. */ + if (pos == oldpos) + goto next; +@@ -457,6 +462,9 @@ mark_source_chains(const struct xt_table + if (!xt_find_jump_offset(offsets, newpos, + newinfo->number)) + return 0; ++ ++ if (entry0 + newpos != ip6t_next_entry(e)) ++ ++depth; + } else { + /* ... this is a fallthru */ + newpos = pos + e->next_offset; +@@ -467,8 +475,15 @@ mark_source_chains(const struct xt_table + e->counters.pcnt = pos; + pos = newpos; + } ++ if (depth == 0) ++ last_pos = pos; ++ } ++next: ++ if (last_pos != newinfo->underflow[hook]) { ++ pr_err_ratelimited("last base chain position %u doesn't match underflow %u (hook %u)\n", ++ last_pos, newinfo->underflow[hook], hook); ++ return 0; + } +-next: ; + } + return 1; + } diff --git a/queue-4.16/netlink-fix-uninit-value-in-netlink_sendmsg.patch b/queue-4.16/netlink-fix-uninit-value-in-netlink_sendmsg.patch new file mode 100644 index 00000000000..cd579b81d03 --- /dev/null +++ b/queue-4.16/netlink-fix-uninit-value-in-netlink_sendmsg.patch @@ -0,0 +1,35 @@ +From 6091f09c2f79730d895149bcfe3d66140288cd0e Mon Sep 17 00:00:00 2001 +From: Eric Dumazet +Date: Sat, 7 Apr 2018 13:42:37 -0700 +Subject: netlink: fix uninit-value in netlink_sendmsg + +From: Eric Dumazet + +commit 6091f09c2f79730d895149bcfe3d66140288cd0e upstream. + +syzbot reported : + +BUG: KMSAN: uninit-value in ffs arch/x86/include/asm/bitops.h:432 [inline] +BUG: KMSAN: uninit-value in netlink_sendmsg+0xb26/0x1310 net/netlink/af_netlink.c:1851 + +Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") +Signed-off-by: Eric Dumazet +Reported-by: syzbot +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman + +--- + net/netlink/af_netlink.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/net/netlink/af_netlink.c ++++ b/net/netlink/af_netlink.c +@@ -1845,6 +1845,8 @@ static int netlink_sendmsg(struct socket + + if (msg->msg_namelen) { + err = -EINVAL; ++ if (msg->msg_namelen < sizeof(struct sockaddr_nl)) ++ goto out; + if (addr->nl_family != AF_NETLINK) + goto out; + dst_portid = addr->nl_pid; diff --git a/queue-4.16/perf-remove-superfluous-allocation-error-check.patch b/queue-4.16/perf-remove-superfluous-allocation-error-check.patch new file mode 100644 index 00000000000..d92742fd856 --- /dev/null +++ b/queue-4.16/perf-remove-superfluous-allocation-error-check.patch @@ -0,0 +1,52 @@ +From bfb3d7b8b906b66551424d7636182126e1d134c8 Mon Sep 17 00:00:00 2001 +From: Jiri Olsa +Date: Sun, 15 Apr 2018 11:23:52 +0200 +Subject: perf: Remove superfluous allocation error check + +From: Jiri Olsa + +commit bfb3d7b8b906b66551424d7636182126e1d134c8 upstream. + +If the get_callchain_buffers fails to allocate the buffer it will +decrease the nr_callchain_events right away. + +There's no point of checking the allocation error for +nr_callchain_events > 1. Removing that check. + +Signed-off-by: Jiri Olsa +Tested-by: Arnaldo Carvalho de Melo +Cc: Alexander Shishkin +Cc: Andi Kleen +Cc: H. Peter Anvin +Cc: Namhyung Kim +Cc: Peter Zijlstra +Cc: Thomas Gleixner +Cc: syzkaller-bugs@googlegroups.com +Cc: x86@kernel.org +Link: http://lkml.kernel.org/r/20180415092352.12403-3-jolsa@kernel.org +Signed-off-by: Arnaldo Carvalho de Melo +Signed-off-by: Greg Kroah-Hartman + +--- + kernel/events/callchain.c | 10 ++-------- + 1 file changed, 2 insertions(+), 8 deletions(-) + +--- a/kernel/events/callchain.c ++++ b/kernel/events/callchain.c +@@ -131,14 +131,8 @@ int get_callchain_buffers(int event_max_ + goto exit; + } + +- if (count > 1) { +- /* If the allocation failed, give up */ +- if (!callchain_cpus_entries) +- err = -ENOMEM; +- goto exit; +- } +- +- err = alloc_callchain_buffers(); ++ if (count == 1) ++ err = alloc_callchain_buffers(); + exit: + if (err) + atomic_dec(&nr_callchain_events); diff --git a/queue-4.16/rds-tcp-must-use-spin_lock_irq-and-not-spin_lock_bh-with-rds_tcp_conn_lock.patch b/queue-4.16/rds-tcp-must-use-spin_lock_irq-and-not-spin_lock_bh-with-rds_tcp_conn_lock.patch new file mode 100644 index 00000000000..f586061232d --- /dev/null +++ b/queue-4.16/rds-tcp-must-use-spin_lock_irq-and-not-spin_lock_bh-with-rds_tcp_conn_lock.patch @@ -0,0 +1,99 @@ +From 53d0e83f9329aa51dcc205b514dbee05cb4df309 Mon Sep 17 00:00:00 2001 +From: Sowmini Varadhan +Date: Thu, 15 Mar 2018 03:54:26 -0700 +Subject: rds: tcp: must use spin_lock_irq* and not spin_lock_bh with rds_tcp_conn_lock + +From: Sowmini Varadhan + +commit 53d0e83f9329aa51dcc205b514dbee05cb4df309 upstream. + +rds_tcp_connection allocation/free management has the potential to be +called from __rds_conn_create after IRQs have been disabled, so +spin_[un]lock_bh cannot be used with rds_tcp_conn_lock. + +Bottom-halves that need to synchronize for critical sections protected +by rds_tcp_conn_lock should instead use rds_destroy_pending() correctly. + +Reported-by: syzbot+c68e51bb5e699d3f8d91@syzkaller.appspotmail.com +Fixes: ebeeb1ad9b8a ("rds: tcp: use rds_destroy_pending() to synchronize + netns/module teardown and rds connection/workq management") +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 | 17 +++++++++-------- + 1 file changed, 9 insertions(+), 8 deletions(-) + +--- a/net/rds/tcp.c ++++ b/net/rds/tcp.c +@@ -275,13 +275,14 @@ static int rds_tcp_laddr_check(struct ne + static void rds_tcp_conn_free(void *arg) + { + struct rds_tcp_connection *tc = arg; ++ unsigned long flags; + + rdsdebug("freeing tc %p\n", tc); + +- spin_lock_bh(&rds_tcp_conn_lock); ++ spin_lock_irqsave(&rds_tcp_conn_lock, flags); + if (!tc->t_tcp_node_detached) + list_del(&tc->t_tcp_node); +- spin_unlock_bh(&rds_tcp_conn_lock); ++ spin_unlock_irqrestore(&rds_tcp_conn_lock, flags); + + kmem_cache_free(rds_tcp_conn_slab, tc); + } +@@ -311,13 +312,13 @@ static int rds_tcp_conn_alloc(struct rds + rdsdebug("rds_conn_path [%d] tc %p\n", i, + conn->c_path[i].cp_transport_data); + } +- spin_lock_bh(&rds_tcp_conn_lock); ++ spin_lock_irq(&rds_tcp_conn_lock); + for (i = 0; i < RDS_MPATH_WORKERS; i++) { + tc = conn->c_path[i].cp_transport_data; + tc->t_tcp_node_detached = false; + list_add_tail(&tc->t_tcp_node, &rds_tcp_conn_list); + } +- spin_unlock_bh(&rds_tcp_conn_lock); ++ spin_unlock_irq(&rds_tcp_conn_lock); + fail: + if (ret) { + for (j = 0; j < i; j++) +@@ -529,7 +530,7 @@ static void rds_tcp_kill_sock(struct net + + rtn->rds_tcp_listen_sock = NULL; + rds_tcp_listen_stop(lsock, &rtn->rds_tcp_accept_w); +- spin_lock_bh(&rds_tcp_conn_lock); ++ 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 = read_pnet(&tc->t_cpath->cp_conn->c_net); + +@@ -542,7 +543,7 @@ static void rds_tcp_kill_sock(struct net + tc->t_tcp_node_detached = true; + } + } +- spin_unlock_bh(&rds_tcp_conn_lock); ++ spin_unlock_irq(&rds_tcp_conn_lock); + list_for_each_entry_safe(tc, _tc, &tmp_list, t_tcp_node) + rds_conn_destroy(tc->t_cpath->cp_conn); + } +@@ -590,7 +591,7 @@ static void rds_tcp_sysctl_reset(struct + { + struct rds_tcp_connection *tc, *_tc; + +- spin_lock_bh(&rds_tcp_conn_lock); ++ 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 = read_pnet(&tc->t_cpath->cp_conn->c_net); + +@@ -600,7 +601,7 @@ static void rds_tcp_sysctl_reset(struct + /* reconnect with new parameters */ + rds_conn_path_drop(tc->t_cpath, false); + } +- spin_unlock_bh(&rds_tcp_conn_lock); ++ spin_unlock_irq(&rds_tcp_conn_lock); + } + + static int rds_tcp_skbuf_handler(struct ctl_table *ctl, int write, diff --git a/queue-4.16/series b/queue-4.16/series index 82641d49033..e8c29e6f7cf 100644 --- a/queue-4.16/series +++ b/queue-4.16/series @@ -1,3 +1,23 @@ ipvs-fix-rtnl_lock-lockups-caused-by-start_sync_thread.patch netfilter-ebtables-don-t-attempt-to-allocate-0-sized-compat-array.patch clk-ti-fix-flag-space-conflict-with-clkctrl-clocks.patch +kcm-call-strp_stop-before-strp_done-in-kcm_attach.patch +netfilter-x_tables-ensure-last-rule-in-base-chain-matches-underflow-policy.patch +rds-tcp-must-use-spin_lock_irq-and-not-spin_lock_bh-with-rds_tcp_conn_lock.patch +crypto-af_alg-fix-possible-uninit-value-in-alg_bind.patch +netlink-fix-uninit-value-in-netlink_sendmsg.patch +net-fix-rtnh_ok.patch +net-initialize-skb-peeked-when-cloning.patch +net-fix-uninit-value-in-__hw_addr_add_ex.patch +dccp-initialize-ireq-ir_mark.patch +ipv4-fix-uninit-value-in-ip_route_output_key_hash_rcu.patch +soreuseport-initialise-timewait-reuseport-field.patch +inetpeer-fix-uninit-value-in-inet_getpeer.patch +bpf-tracing-fix-a-deadlock-in-perf_event_detach_bpf_prog.patch +memcg-fix-per_node_info-cleanup.patch +perf-remove-superfluous-allocation-error-check.patch +i2c-dev-prevent-zero_size_ptr-deref-in-i2cdev_ioctl_rdwr.patch +tcp-fix-tcp_repair_queue-bound-checking.patch +bdi-wake-up-concurrent-wb_shutdown-callers.patch +bdi-fix-use-after-free-bug-in-debugfs_remove.patch +bdi-fix-oops-in-wb_workfn.patch diff --git a/queue-4.16/soreuseport-initialise-timewait-reuseport-field.patch b/queue-4.16/soreuseport-initialise-timewait-reuseport-field.patch new file mode 100644 index 00000000000..79bf01854b7 --- /dev/null +++ b/queue-4.16/soreuseport-initialise-timewait-reuseport-field.patch @@ -0,0 +1,149 @@ +From 3099a52918937ab86ec47038ad80d377ba16c531 Mon Sep 17 00:00:00 2001 +From: Eric Dumazet +Date: Sat, 7 Apr 2018 13:42:43 -0700 +Subject: soreuseport: initialise timewait reuseport field + +From: Eric Dumazet + +commit 3099a52918937ab86ec47038ad80d377ba16c531 upstream. + +syzbot reported an uninit-value in inet_csk_bind_conflict() [1] + +It turns out we never propagated sk->sk_reuseport into timewait socket. + +[1] +BUG: KMSAN: uninit-value in inet_csk_bind_conflict+0x5f9/0x990 net/ipv4/inet_connection_sock.c:151 +CPU: 1 PID: 3589 Comm: syzkaller008242 Not tainted 4.16.0+ #82 +Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/01/2011 +Call Trace: + __dump_stack lib/dump_stack.c:17 [inline] + dump_stack+0x185/0x1d0 lib/dump_stack.c:53 + kmsan_report+0x142/0x240 mm/kmsan/kmsan.c:1067 + __msan_warning_32+0x6c/0xb0 mm/kmsan/kmsan_instr.c:676 + inet_csk_bind_conflict+0x5f9/0x990 net/ipv4/inet_connection_sock.c:151 + inet_csk_get_port+0x1d28/0x1e40 net/ipv4/inet_connection_sock.c:320 + inet6_bind+0x121c/0x1820 net/ipv6/af_inet6.c:399 + SYSC_bind+0x3f2/0x4b0 net/socket.c:1474 + SyS_bind+0x54/0x80 net/socket.c:1460 + do_syscall_64+0x309/0x430 arch/x86/entry/common.c:287 + entry_SYSCALL_64_after_hwframe+0x3d/0xa2 +RIP: 0033:0x4416e9 +RSP: 002b:00007ffce6d15c88 EFLAGS: 00000217 ORIG_RAX: 0000000000000031 +RAX: ffffffffffffffda RBX: 0100000000000000 RCX: 00000000004416e9 +RDX: 000000000000001c RSI: 0000000020402000 RDI: 0000000000000004 +RBP: 0000000000000000 R08: 00000000e6d15e08 R09: 00000000e6d15e08 +R10: 0000000000000004 R11: 0000000000000217 R12: 0000000000009478 +R13: 00000000006cd448 R14: 0000000000000000 R15: 0000000000000000 + +Uninit was stored to memory at: + kmsan_save_stack_with_flags mm/kmsan/kmsan.c:278 [inline] + kmsan_save_stack mm/kmsan/kmsan.c:293 [inline] + kmsan_internal_chain_origin+0x12b/0x210 mm/kmsan/kmsan.c:684 + __msan_chain_origin+0x69/0xc0 mm/kmsan/kmsan_instr.c:521 + tcp_time_wait+0xf17/0xf50 net/ipv4/tcp_minisocks.c:283 + tcp_rcv_state_process+0xebe/0x6490 net/ipv4/tcp_input.c:6003 + tcp_v6_do_rcv+0x11dd/0x1d90 net/ipv6/tcp_ipv6.c:1331 + sk_backlog_rcv include/net/sock.h:908 [inline] + __release_sock+0x2d6/0x680 net/core/sock.c:2271 + release_sock+0x97/0x2a0 net/core/sock.c:2786 + tcp_close+0x277/0x18f0 net/ipv4/tcp.c:2269 + inet_release+0x240/0x2a0 net/ipv4/af_inet.c:427 + inet6_release+0xaf/0x100 net/ipv6/af_inet6.c:435 + sock_release net/socket.c:595 [inline] + sock_close+0xe0/0x300 net/socket.c:1149 + __fput+0x49e/0xa10 fs/file_table.c:209 + ____fput+0x37/0x40 fs/file_table.c:243 + task_work_run+0x243/0x2c0 kernel/task_work.c:113 + exit_task_work include/linux/task_work.h:22 [inline] + do_exit+0x10e1/0x38d0 kernel/exit.c:867 + do_group_exit+0x1a0/0x360 kernel/exit.c:970 + SYSC_exit_group+0x21/0x30 kernel/exit.c:981 + SyS_exit_group+0x25/0x30 kernel/exit.c:979 + do_syscall_64+0x309/0x430 arch/x86/entry/common.c:287 + entry_SYSCALL_64_after_hwframe+0x3d/0xa2 +Uninit was stored to memory at: + kmsan_save_stack_with_flags mm/kmsan/kmsan.c:278 [inline] + kmsan_save_stack mm/kmsan/kmsan.c:293 [inline] + kmsan_internal_chain_origin+0x12b/0x210 mm/kmsan/kmsan.c:684 + __msan_chain_origin+0x69/0xc0 mm/kmsan/kmsan_instr.c:521 + inet_twsk_alloc+0xaef/0xc00 net/ipv4/inet_timewait_sock.c:182 + tcp_time_wait+0xd9/0xf50 net/ipv4/tcp_minisocks.c:258 + tcp_rcv_state_process+0xebe/0x6490 net/ipv4/tcp_input.c:6003 + tcp_v6_do_rcv+0x11dd/0x1d90 net/ipv6/tcp_ipv6.c:1331 + sk_backlog_rcv include/net/sock.h:908 [inline] + __release_sock+0x2d6/0x680 net/core/sock.c:2271 + release_sock+0x97/0x2a0 net/core/sock.c:2786 + tcp_close+0x277/0x18f0 net/ipv4/tcp.c:2269 + inet_release+0x240/0x2a0 net/ipv4/af_inet.c:427 + inet6_release+0xaf/0x100 net/ipv6/af_inet6.c:435 + sock_release net/socket.c:595 [inline] + sock_close+0xe0/0x300 net/socket.c:1149 + __fput+0x49e/0xa10 fs/file_table.c:209 + ____fput+0x37/0x40 fs/file_table.c:243 + task_work_run+0x243/0x2c0 kernel/task_work.c:113 + exit_task_work include/linux/task_work.h:22 [inline] + do_exit+0x10e1/0x38d0 kernel/exit.c:867 + do_group_exit+0x1a0/0x360 kernel/exit.c:970 + SYSC_exit_group+0x21/0x30 kernel/exit.c:981 + SyS_exit_group+0x25/0x30 kernel/exit.c:979 + do_syscall_64+0x309/0x430 arch/x86/entry/common.c:287 + entry_SYSCALL_64_after_hwframe+0x3d/0xa2 +Uninit was created at: + kmsan_save_stack_with_flags mm/kmsan/kmsan.c:278 [inline] + kmsan_internal_poison_shadow+0xb8/0x1b0 mm/kmsan/kmsan.c:188 + kmsan_kmalloc+0x94/0x100 mm/kmsan/kmsan.c:314 + kmem_cache_alloc+0xaab/0xb90 mm/slub.c:2756 + inet_twsk_alloc+0x13b/0xc00 net/ipv4/inet_timewait_sock.c:163 + tcp_time_wait+0xd9/0xf50 net/ipv4/tcp_minisocks.c:258 + tcp_rcv_state_process+0xebe/0x6490 net/ipv4/tcp_input.c:6003 + tcp_v6_do_rcv+0x11dd/0x1d90 net/ipv6/tcp_ipv6.c:1331 + sk_backlog_rcv include/net/sock.h:908 [inline] + __release_sock+0x2d6/0x680 net/core/sock.c:2271 + release_sock+0x97/0x2a0 net/core/sock.c:2786 + tcp_close+0x277/0x18f0 net/ipv4/tcp.c:2269 + inet_release+0x240/0x2a0 net/ipv4/af_inet.c:427 + inet6_release+0xaf/0x100 net/ipv6/af_inet6.c:435 + sock_release net/socket.c:595 [inline] + sock_close+0xe0/0x300 net/socket.c:1149 + __fput+0x49e/0xa10 fs/file_table.c:209 + ____fput+0x37/0x40 fs/file_table.c:243 + task_work_run+0x243/0x2c0 kernel/task_work.c:113 + exit_task_work include/linux/task_work.h:22 [inline] + do_exit+0x10e1/0x38d0 kernel/exit.c:867 + do_group_exit+0x1a0/0x360 kernel/exit.c:970 + SYSC_exit_group+0x21/0x30 kernel/exit.c:981 + SyS_exit_group+0x25/0x30 kernel/exit.c:979 + do_syscall_64+0x309/0x430 arch/x86/entry/common.c:287 + entry_SYSCALL_64_after_hwframe+0x3d/0xa2 + +Fixes: da5e36308d9f ("soreuseport: TCP/IPv4 implementation") +Signed-off-by: Eric Dumazet +Reported-by: syzbot +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman + +--- + include/net/inet_timewait_sock.h | 1 + + net/ipv4/inet_timewait_sock.c | 1 + + 2 files changed, 2 insertions(+) + +--- a/include/net/inet_timewait_sock.h ++++ b/include/net/inet_timewait_sock.h +@@ -43,6 +43,7 @@ struct inet_timewait_sock { + #define tw_family __tw_common.skc_family + #define tw_state __tw_common.skc_state + #define tw_reuse __tw_common.skc_reuse ++#define tw_reuseport __tw_common.skc_reuseport + #define tw_ipv6only __tw_common.skc_ipv6only + #define tw_bound_dev_if __tw_common.skc_bound_dev_if + #define tw_node __tw_common.skc_nulls_node +--- a/net/ipv4/inet_timewait_sock.c ++++ b/net/ipv4/inet_timewait_sock.c +@@ -178,6 +178,7 @@ struct inet_timewait_sock *inet_twsk_all + tw->tw_dport = inet->inet_dport; + tw->tw_family = sk->sk_family; + tw->tw_reuse = sk->sk_reuse; ++ tw->tw_reuseport = sk->sk_reuseport; + tw->tw_hash = sk->sk_hash; + tw->tw_ipv6only = 0; + tw->tw_transparent = inet->transparent; diff --git a/queue-4.16/tcp-fix-tcp_repair_queue-bound-checking.patch b/queue-4.16/tcp-fix-tcp_repair_queue-bound-checking.patch new file mode 100644 index 00000000000..2ec0f5e1f90 --- /dev/null +++ b/queue-4.16/tcp-fix-tcp_repair_queue-bound-checking.patch @@ -0,0 +1,50 @@ +From bf2acc943a45d2b2e8a9f1a5ddff6b6e43cc69d9 Mon Sep 17 00:00:00 2001 +From: Eric Dumazet +Date: Sun, 29 Apr 2018 18:55:20 -0700 +Subject: tcp: fix TCP_REPAIR_QUEUE bound checking + +From: Eric Dumazet + +commit bf2acc943a45d2b2e8a9f1a5ddff6b6e43cc69d9 upstream. + +syzbot is able to produce a nasty WARN_ON() in tcp_verify_left_out() +with following C-repro : + +socket(PF_INET, SOCK_STREAM, IPPROTO_IP) = 3 +setsockopt(3, SOL_TCP, TCP_REPAIR, [1], 4) = 0 +setsockopt(3, SOL_TCP, TCP_REPAIR_QUEUE, [-1], 4) = 0 +bind(3, {sa_family=AF_INET, sin_port=htons(20002), sin_addr=inet_addr("0.0.0.0")}, 16) = 0 +sendto(3, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., + 1242, MSG_FASTOPEN, {sa_family=AF_INET, sin_port=htons(20002), sin_addr=inet_addr("127.0.0.1")}, 16) = 1242 +setsockopt(3, SOL_TCP, TCP_REPAIR_WINDOW, "\4\0\0@+\205\0\0\377\377\0\0\377\377\377\177\0\0\0\0", 20) = 0 +writev(3, [{"\270", 1}], 1) = 1 +setsockopt(3, SOL_TCP, TCP_REPAIR_OPTIONS, "\10\0\0\0\0\0\0\0\0\0\0\0|\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 386) = 0 +writev(3, [{"\210v\r[\226\320t\231qwQ\204\264l\254\t\1\20\245\214p\350H\223\254;\\\37\345\307p$"..., 3144}], 1) = 3144 + +The 3rd system call looks odd : +setsockopt(3, SOL_TCP, TCP_REPAIR_QUEUE, [-1], 4) = 0 + +This patch makes sure bound checking is using an unsigned compare. + +Fixes: ee9952831cfd ("tcp: Initial repair mode") +Signed-off-by: Eric Dumazet +Reported-by: syzbot +Cc: Pavel Emelyanov +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman + +--- + net/ipv4/tcp.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/net/ipv4/tcp.c ++++ b/net/ipv4/tcp.c +@@ -2690,7 +2690,7 @@ static int do_tcp_setsockopt(struct sock + case TCP_REPAIR_QUEUE: + if (!tp->repair) + err = -EPERM; +- else if (val < TCP_QUEUES_NR) ++ else if ((unsigned int)val < TCP_QUEUES_NR) + tp->repair_queue = val; + else + err = -EINVAL;