From: Greg Kroah-Hartman Date: Mon, 25 Mar 2019 20:35:36 +0000 (+0900) Subject: 4.14-stable patches X-Git-Tag: v4.9.166~23 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=d2b4c3459176753ca1b5776fce491975783768ad;p=thirdparty%2Fkernel%2Fstable-queue.git 4.14-stable patches added patches: bluetooth-fix-decrementing-reference-count-twice-in-releasing-socket.patch bluetooth-hci_ldisc-initialize-hci_dev-before-open.patch bluetooth-hci_ldisc-postpone-hci_uart_proto_ready-bit-set-in-hci_uart_set_proto.patch bluetooth-hci_uart-check-if-socket-buffer-is-err_ptr-in-h4_recv_buf.patch drm-reorder-set_property_atomic-to-avoid-returning-with-an-active-ww_ctx.patch locking-lockdep-add-debug_locks-check-in-__lock_downgrade.patch media-v4l2-ctrls.c-uvc-zero-v4l2_event.patch mm-mempolicy-fix-uninit-memory-access.patch netfilter-ebtables-remove-bugprint-messages.patch x86-unwind-add-hardcoded-orc-entry-for-null.patch x86-unwind-handle-null-pointer-calls-better-in-frame-unwinder.patch --- diff --git a/queue-4.14/bluetooth-fix-decrementing-reference-count-twice-in-releasing-socket.patch b/queue-4.14/bluetooth-fix-decrementing-reference-count-twice-in-releasing-socket.patch new file mode 100644 index 00000000000..97578276672 --- /dev/null +++ b/queue-4.14/bluetooth-fix-decrementing-reference-count-twice-in-releasing-socket.patch @@ -0,0 +1,46 @@ +From e20a2e9c42c9e4002d9e338d74e7819e88d77162 Mon Sep 17 00:00:00 2001 +From: Myungho Jung +Date: Sat, 2 Feb 2019 16:56:36 -0800 +Subject: Bluetooth: Fix decrementing reference count twice in releasing socket + +From: Myungho Jung + +commit e20a2e9c42c9e4002d9e338d74e7819e88d77162 upstream. + +When releasing socket, it is possible to enter hci_sock_release() and +hci_sock_dev_event(HCI_DEV_UNREG) at the same time in different thread. +The reference count of hdev should be decremented only once from one of +them but if storing hdev to local variable in hci_sock_release() before +detached from socket and setting to NULL in hci_sock_dev_event(), +hci_dev_put(hdev) is unexpectedly called twice. This is resolved by +referencing hdev from socket after bt_sock_unlink() in +hci_sock_release(). + +Reported-by: syzbot+fdc00003f4efff43bc5b@syzkaller.appspotmail.com +Signed-off-by: Myungho Jung +Signed-off-by: Marcel Holtmann +Signed-off-by: Greg Kroah-Hartman + +--- + net/bluetooth/hci_sock.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +--- a/net/bluetooth/hci_sock.c ++++ b/net/bluetooth/hci_sock.c +@@ -826,8 +826,6 @@ static int hci_sock_release(struct socke + if (!sk) + return 0; + +- hdev = hci_pi(sk)->hdev; +- + switch (hci_pi(sk)->channel) { + case HCI_CHANNEL_MONITOR: + atomic_dec(&monitor_promisc); +@@ -849,6 +847,7 @@ static int hci_sock_release(struct socke + + bt_sock_unlink(&hci_sk_list, sk); + ++ hdev = hci_pi(sk)->hdev; + if (hdev) { + if (hci_pi(sk)->channel == HCI_CHANNEL_USER) { + /* When releasing a user channel exclusive access, diff --git a/queue-4.14/bluetooth-hci_ldisc-initialize-hci_dev-before-open.patch b/queue-4.14/bluetooth-hci_ldisc-initialize-hci_dev-before-open.patch new file mode 100644 index 00000000000..2ccacbfb0ba --- /dev/null +++ b/queue-4.14/bluetooth-hci_ldisc-initialize-hci_dev-before-open.patch @@ -0,0 +1,95 @@ +From 32a7b4cbe93b0a0ef7e63d31ca69ce54736c4412 Mon Sep 17 00:00:00 2001 +From: Jeremy Cline +Date: Wed, 6 Feb 2019 12:54:16 -0500 +Subject: Bluetooth: hci_ldisc: Initialize hci_dev before open() + +From: Jeremy Cline + +commit 32a7b4cbe93b0a0ef7e63d31ca69ce54736c4412 upstream. + +The hci_dev struct hdev is referenced in work queues and timers started +by open() in some protocols. This creates a race between the +initialization function and the work or timer which can result hdev +being dereferenced while it is still null. + +The syzbot report contains a reliable reproducer which causes a null +pointer dereference of hdev in hci_uart_write_work() by making the +memory allocation for hdev fail. + +To fix this, ensure hdev is valid from before calling a protocol's +open() until after calling a protocol's close(). + +Reported-by: syzbot+257790c15bcdef6fe00c@syzkaller.appspotmail.com +Signed-off-by: Jeremy Cline +Signed-off-by: Marcel Holtmann +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/bluetooth/hci_ldisc.c | 21 ++++++++++++++------- + 1 file changed, 14 insertions(+), 7 deletions(-) + +--- a/drivers/bluetooth/hci_ldisc.c ++++ b/drivers/bluetooth/hci_ldisc.c +@@ -207,11 +207,11 @@ static void hci_uart_init_work(struct wo + err = hci_register_dev(hu->hdev); + if (err < 0) { + BT_ERR("Can't register HCI device"); ++ clear_bit(HCI_UART_PROTO_READY, &hu->flags); ++ hu->proto->close(hu); + hdev = hu->hdev; + hu->hdev = NULL; + hci_free_dev(hdev); +- clear_bit(HCI_UART_PROTO_READY, &hu->flags); +- hu->proto->close(hu); + return; + } + +@@ -612,6 +612,7 @@ static void hci_uart_tty_receive(struct + static int hci_uart_register_dev(struct hci_uart *hu) + { + struct hci_dev *hdev; ++ int err; + + BT_DBG(""); + +@@ -655,11 +656,22 @@ static int hci_uart_register_dev(struct + else + hdev->dev_type = HCI_PRIMARY; + ++ /* Only call open() for the protocol after hdev is fully initialized as ++ * open() (or a timer/workqueue it starts) may attempt to reference it. ++ */ ++ err = hu->proto->open(hu); ++ if (err) { ++ hu->hdev = NULL; ++ hci_free_dev(hdev); ++ return err; ++ } ++ + if (test_bit(HCI_UART_INIT_PENDING, &hu->hdev_flags)) + return 0; + + if (hci_register_dev(hdev) < 0) { + BT_ERR("Can't register HCI device"); ++ hu->proto->close(hu); + hu->hdev = NULL; + hci_free_dev(hdev); + return -ENODEV; +@@ -679,17 +691,12 @@ static int hci_uart_set_proto(struct hci + if (!p) + return -EPROTONOSUPPORT; + +- err = p->open(hu); +- if (err) +- return err; +- + hu->proto = p; + set_bit(HCI_UART_PROTO_READY, &hu->flags); + + err = hci_uart_register_dev(hu); + if (err) { + clear_bit(HCI_UART_PROTO_READY, &hu->flags); +- p->close(hu); + return err; + } + diff --git a/queue-4.14/bluetooth-hci_ldisc-postpone-hci_uart_proto_ready-bit-set-in-hci_uart_set_proto.patch b/queue-4.14/bluetooth-hci_ldisc-postpone-hci_uart_proto_ready-bit-set-in-hci_uart_set_proto.patch new file mode 100644 index 00000000000..da21f12efa0 --- /dev/null +++ b/queue-4.14/bluetooth-hci_ldisc-postpone-hci_uart_proto_ready-bit-set-in-hci_uart_set_proto.patch @@ -0,0 +1,57 @@ +From 56897b217a1d0a91c9920cb418d6b3fe922f590a Mon Sep 17 00:00:00 2001 +From: Kefeng Wang +Date: Sat, 23 Feb 2019 12:33:27 +0800 +Subject: Bluetooth: hci_ldisc: Postpone HCI_UART_PROTO_READY bit set in hci_uart_set_proto() + +From: Kefeng Wang + +commit 56897b217a1d0a91c9920cb418d6b3fe922f590a upstream. + +task A: task B: +hci_uart_set_proto flush_to_ldisc + - p->open(hu) -> h5_open //alloc h5 - receive_buf + - set_bit HCI_UART_PROTO_READY - tty_port_default_receive_buf + - hci_uart_register_dev - tty_ldisc_receive_buf + - hci_uart_tty_receive + - test_bit HCI_UART_PROTO_READY + - h5_recv + - clear_bit HCI_UART_PROTO_READY while() { + - p->open(hu) -> h5_close //free h5 + - h5_rx_3wire_hdr + - h5_reset() //use-after-free + } + +It could use ioctl to set hci uart proto, but there is +a use-after-free issue when hci_uart_register_dev() fail in +hci_uart_set_proto(), see stack above, fix this by setting +HCI_UART_PROTO_READY bit only when hci_uart_register_dev() +return success. + +Reported-by: syzbot+899a33dc0fa0dbaf06a6@syzkaller.appspotmail.com +Signed-off-by: Kefeng Wang +Reviewed-by: Jeremy Cline +Signed-off-by: Marcel Holtmann +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/bluetooth/hci_ldisc.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +--- a/drivers/bluetooth/hci_ldisc.c ++++ b/drivers/bluetooth/hci_ldisc.c +@@ -692,14 +692,13 @@ static int hci_uart_set_proto(struct hci + return -EPROTONOSUPPORT; + + hu->proto = p; +- set_bit(HCI_UART_PROTO_READY, &hu->flags); + + err = hci_uart_register_dev(hu); + if (err) { +- clear_bit(HCI_UART_PROTO_READY, &hu->flags); + return err; + } + ++ set_bit(HCI_UART_PROTO_READY, &hu->flags); + return 0; + } + diff --git a/queue-4.14/bluetooth-hci_uart-check-if-socket-buffer-is-err_ptr-in-h4_recv_buf.patch b/queue-4.14/bluetooth-hci_uart-check-if-socket-buffer-is-err_ptr-in-h4_recv_buf.patch new file mode 100644 index 00000000000..7de91e7934b --- /dev/null +++ b/queue-4.14/bluetooth-hci_uart-check-if-socket-buffer-is-err_ptr-in-h4_recv_buf.patch @@ -0,0 +1,37 @@ +From 1dc2d785156cbdc80806c32e8d2c7c735d0b4721 Mon Sep 17 00:00:00 2001 +From: Myungho Jung +Date: Tue, 22 Jan 2019 00:33:26 -0800 +Subject: Bluetooth: hci_uart: Check if socket buffer is ERR_PTR in h4_recv_buf() + +From: Myungho Jung + +commit 1dc2d785156cbdc80806c32e8d2c7c735d0b4721 upstream. + +h4_recv_buf() callers store the return value to socket buffer and +recursively pass the buffer to h4_recv_buf() without protection. So, +ERR_PTR returned from h4_recv_buf() can be dereferenced, if called again +before setting the socket buffer to NULL from previous error. Check if +skb is ERR_PTR in h4_recv_buf(). + +Reported-by: syzbot+017a32f149406df32703@syzkaller.appspotmail.com +Signed-off-by: Myungho Jung +Signed-off-by: Marcel Holtmann +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/bluetooth/hci_h4.c | 4 ++++ + 1 file changed, 4 insertions(+) + +--- a/drivers/bluetooth/hci_h4.c ++++ b/drivers/bluetooth/hci_h4.c +@@ -174,6 +174,10 @@ struct sk_buff *h4_recv_buf(struct hci_d + struct hci_uart *hu = hci_get_drvdata(hdev); + u8 alignment = hu->alignment ? hu->alignment : 1; + ++ /* Check for error from previous call */ ++ if (IS_ERR(skb)) ++ skb = NULL; ++ + while (count) { + int i, len; + diff --git a/queue-4.14/drm-reorder-set_property_atomic-to-avoid-returning-with-an-active-ww_ctx.patch b/queue-4.14/drm-reorder-set_property_atomic-to-avoid-returning-with-an-active-ww_ctx.patch new file mode 100644 index 00000000000..b959eab0fd3 --- /dev/null +++ b/queue-4.14/drm-reorder-set_property_atomic-to-avoid-returning-with-an-active-ww_ctx.patch @@ -0,0 +1,55 @@ +From 227ad6d957898a88b1746e30234ece64d305f066 Mon Sep 17 00:00:00 2001 +From: Chris Wilson +Date: Sun, 30 Dec 2018 12:28:42 +0000 +Subject: drm: Reorder set_property_atomic to avoid returning with an active ww_ctx + +From: Chris Wilson + +commit 227ad6d957898a88b1746e30234ece64d305f066 upstream. + +Delay the drm_modeset_acquire_init() until after we check for an +allocation failure so that we can return immediately upon error without +having to unwind. + +WARNING: lock held when returning to user space! +4.20.0+ #174 Not tainted +------------------------------------------------ +syz-executor556/8153 is leaving the kernel with locks still held! +1 lock held by syz-executor556/8153: + #0: 000000005100c85c (crtc_ww_class_acquire){+.+.}, at: +set_property_atomic+0xb3/0x330 drivers/gpu/drm/drm_mode_object.c:462 + +Reported-by: syzbot+6ea337c427f5083ebdf2@syzkaller.appspotmail.com +Fixes: 144a7999d633 ("drm: Handle properties in the core for atomic drivers") +Signed-off-by: Chris Wilson +Cc: Daniel Vetter +Cc: Maarten Lankhorst +Cc: Sean Paul +Cc: David Airlie +Cc: # v4.14+ +Reviewed-by: Maarten Lankhorst +Link: https://patchwork.freedesktop.org/patch/msgid/20181230122842.21917-1-chris@chris-wilson.co.uk +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/gpu/drm/drm_mode_object.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +--- a/drivers/gpu/drm/drm_mode_object.c ++++ b/drivers/gpu/drm/drm_mode_object.c +@@ -432,12 +432,13 @@ static int set_property_atomic(struct dr + struct drm_modeset_acquire_ctx ctx; + int ret; + +- drm_modeset_acquire_init(&ctx, 0); +- + state = drm_atomic_state_alloc(dev); + if (!state) + return -ENOMEM; ++ ++ drm_modeset_acquire_init(&ctx, 0); + state->acquire_ctx = &ctx; ++ + retry: + if (prop == state->dev->mode_config.dpms_property) { + if (obj->type != DRM_MODE_OBJECT_CONNECTOR) { diff --git a/queue-4.14/locking-lockdep-add-debug_locks-check-in-__lock_downgrade.patch b/queue-4.14/locking-lockdep-add-debug_locks-check-in-__lock_downgrade.patch new file mode 100644 index 00000000000..38524da60cb --- /dev/null +++ b/queue-4.14/locking-lockdep-add-debug_locks-check-in-__lock_downgrade.patch @@ -0,0 +1,48 @@ +From 71492580571467fb7177aade19c18ce7486267f5 Mon Sep 17 00:00:00 2001 +From: Waiman Long +Date: Wed, 9 Jan 2019 23:03:25 -0500 +Subject: locking/lockdep: Add debug_locks check in __lock_downgrade() + +From: Waiman Long + +commit 71492580571467fb7177aade19c18ce7486267f5 upstream. + +Tetsuo Handa had reported he saw an incorrect "downgrading a read lock" +warning right after a previous lockdep warning. It is likely that the +previous warning turned off lock debugging causing the lockdep to have +inconsistency states leading to the lock downgrade warning. + +Fix that by add a check for debug_locks at the beginning of +__lock_downgrade(). + +Debugged-by: Tetsuo Handa +Reported-by: Tetsuo Handa +Reported-by: syzbot+53383ae265fb161ef488@syzkaller.appspotmail.com +Signed-off-by: Waiman Long +Signed-off-by: Peter Zijlstra (Intel) +Cc: Andrew Morton +Cc: Linus Torvalds +Cc: Paul E. McKenney +Cc: Peter Zijlstra +Cc: Thomas Gleixner +Cc: Will Deacon +Link: https://lkml.kernel.org/r/1547093005-26085-1-git-send-email-longman@redhat.com +Signed-off-by: Ingo Molnar +Signed-off-by: Greg Kroah-Hartman + +--- + kernel/locking/lockdep.c | 3 +++ + 1 file changed, 3 insertions(+) + +--- a/kernel/locking/lockdep.c ++++ b/kernel/locking/lockdep.c +@@ -3650,6 +3650,9 @@ __lock_set_class(struct lockdep_map *loc + unsigned int depth; + int i; + ++ if (unlikely(!debug_locks)) ++ return 0; ++ + depth = curr->lockdep_depth; + /* + * This function is about (re)setting the class of a held lock, diff --git a/queue-4.14/media-v4l2-ctrls.c-uvc-zero-v4l2_event.patch b/queue-4.14/media-v4l2-ctrls.c-uvc-zero-v4l2_event.patch new file mode 100644 index 00000000000..7cf60752013 --- /dev/null +++ b/queue-4.14/media-v4l2-ctrls.c-uvc-zero-v4l2_event.patch @@ -0,0 +1,49 @@ +From f45f3f753b0a3d739acda8e311b4f744d82dc52a Mon Sep 17 00:00:00 2001 +From: Hans Verkuil +Date: Tue, 18 Dec 2018 08:37:08 -0500 +Subject: media: v4l2-ctrls.c/uvc: zero v4l2_event + +From: Hans Verkuil + +commit f45f3f753b0a3d739acda8e311b4f744d82dc52a upstream. + +Control events can leak kernel memory since they do not fully zero the +event. The same code is present in both v4l2-ctrls.c and uvc_ctrl.c, so +fix both. + +It appears that all other event code is properly zeroing the structure, +it's these two places. + +Signed-off-by: Hans Verkuil +Reported-by: syzbot+4f021cf3697781dbd9fb@syzkaller.appspotmail.com +Reviewed-by: Laurent Pinchart +Signed-off-by: Mauro Carvalho Chehab +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/media/usb/uvc/uvc_ctrl.c | 2 +- + drivers/media/v4l2-core/v4l2-ctrls.c | 2 +- + 2 files changed, 2 insertions(+), 2 deletions(-) + +--- a/drivers/media/usb/uvc/uvc_ctrl.c ++++ b/drivers/media/usb/uvc/uvc_ctrl.c +@@ -1203,7 +1203,7 @@ static void uvc_ctrl_fill_event(struct u + + __uvc_query_v4l2_ctrl(chain, ctrl, mapping, &v4l2_ctrl); + +- memset(ev->reserved, 0, sizeof(ev->reserved)); ++ memset(ev, 0, sizeof(*ev)); + ev->type = V4L2_EVENT_CTRL; + ev->id = v4l2_ctrl.id; + ev->u.ctrl.value = value; +--- a/drivers/media/v4l2-core/v4l2-ctrls.c ++++ b/drivers/media/v4l2-core/v4l2-ctrls.c +@@ -1239,7 +1239,7 @@ static u32 user_flags(const struct v4l2_ + + static void fill_event(struct v4l2_event *ev, struct v4l2_ctrl *ctrl, u32 changes) + { +- memset(ev->reserved, 0, sizeof(ev->reserved)); ++ memset(ev, 0, sizeof(*ev)); + ev->type = V4L2_EVENT_CTRL; + ev->id = ctrl->id; + ev->u.ctrl.changes = changes; diff --git a/queue-4.14/mm-mempolicy-fix-uninit-memory-access.patch b/queue-4.14/mm-mempolicy-fix-uninit-memory-access.patch new file mode 100644 index 00000000000..ec0b2aae223 --- /dev/null +++ b/queue-4.14/mm-mempolicy-fix-uninit-memory-access.patch @@ -0,0 +1,93 @@ +From 2e25644e8da4ed3a27e7b8315aaae74660be72dc Mon Sep 17 00:00:00 2001 +From: Vlastimil Babka +Date: Tue, 5 Mar 2019 15:46:50 -0800 +Subject: mm, mempolicy: fix uninit memory access + +From: Vlastimil Babka + +commit 2e25644e8da4ed3a27e7b8315aaae74660be72dc upstream. + +Syzbot with KMSAN reports (excerpt): + +================================================================== +BUG: KMSAN: uninit-value in mpol_rebind_policy mm/mempolicy.c:353 [inline] +BUG: KMSAN: uninit-value in mpol_rebind_mm+0x249/0x370 mm/mempolicy.c:384 +CPU: 1 PID: 17420 Comm: syz-executor4 Not tainted 4.20.0-rc7+ #15 +Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS +Google 01/01/2011 +Call Trace: + __dump_stack lib/dump_stack.c:77 [inline] + dump_stack+0x173/0x1d0 lib/dump_stack.c:113 + kmsan_report+0x12e/0x2a0 mm/kmsan/kmsan.c:613 + __msan_warning+0x82/0xf0 mm/kmsan/kmsan_instr.c:295 + mpol_rebind_policy mm/mempolicy.c:353 [inline] + mpol_rebind_mm+0x249/0x370 mm/mempolicy.c:384 + update_tasks_nodemask+0x608/0xca0 kernel/cgroup/cpuset.c:1120 + update_nodemasks_hier kernel/cgroup/cpuset.c:1185 [inline] + update_nodemask kernel/cgroup/cpuset.c:1253 [inline] + cpuset_write_resmask+0x2a98/0x34b0 kernel/cgroup/cpuset.c:1728 + +... + +Uninit was created at: + kmsan_save_stack_with_flags mm/kmsan/kmsan.c:204 [inline] + kmsan_internal_poison_shadow+0x92/0x150 mm/kmsan/kmsan.c:158 + kmsan_kmalloc+0xa6/0x130 mm/kmsan/kmsan_hooks.c:176 + kmem_cache_alloc+0x572/0xb90 mm/slub.c:2777 + mpol_new mm/mempolicy.c:276 [inline] + do_mbind mm/mempolicy.c:1180 [inline] + kernel_mbind+0x8a7/0x31a0 mm/mempolicy.c:1347 + __do_sys_mbind mm/mempolicy.c:1354 [inline] + +As it's difficult to report where exactly the uninit value resides in +the mempolicy object, we have to guess a bit. mm/mempolicy.c:353 +contains this part of mpol_rebind_policy(): + + if (!mpol_store_user_nodemask(pol) && + nodes_equal(pol->w.cpuset_mems_allowed, *newmask)) + +"mpol_store_user_nodemask(pol)" is testing pol->flags, which I couldn't +ever see being uninitialized after leaving mpol_new(). So I'll guess +it's actually about accessing pol->w.cpuset_mems_allowed on line 354, +but still part of statement starting on line 353. + +For w.cpuset_mems_allowed to be not initialized, and the nodes_equal() +reachable for a mempolicy where mpol_set_nodemask() is called in +do_mbind(), it seems the only possibility is a MPOL_PREFERRED policy +with empty set of nodes, i.e. MPOL_LOCAL equivalent, with MPOL_F_LOCAL +flag. Let's exclude such policies from the nodes_equal() check. Note +the uninit access should be benign anyway, as rebinding this kind of +policy is always a no-op. Therefore no actual need for stable +inclusion. + +Link: http://lkml.kernel.org/r/a71997c3-e8ae-a787-d5ce-3db05768b27c@suse.cz +Link: http://lkml.kernel.org/r/73da3e9c-cc84-509e-17d9-0c434bb9967d@suse.cz +Signed-off-by: Vlastimil Babka +Reported-by: syzbot+b19c2dc2c990ea657a71@syzkaller.appspotmail.com +Cc: Alexander Potapenko +Cc: Dmitry Vyukov +Cc: Andrea Arcangeli +Cc: "Kirill A. Shutemov" +Cc: Michal Hocko +Cc: David Rientjes +Cc: Yisheng Xie +Cc: zhong jiang +Signed-off-by: Andrew Morton +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- + mm/mempolicy.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/mm/mempolicy.c ++++ b/mm/mempolicy.c +@@ -349,7 +349,7 @@ static void mpol_rebind_policy(struct me + { + if (!pol) + return; +- if (!mpol_store_user_nodemask(pol) && ++ if (!mpol_store_user_nodemask(pol) && !(pol->flags & MPOL_F_LOCAL) && + nodes_equal(pol->w.cpuset_mems_allowed, *newmask)) + return; + diff --git a/queue-4.14/netfilter-ebtables-remove-bugprint-messages.patch b/queue-4.14/netfilter-ebtables-remove-bugprint-messages.patch new file mode 100644 index 00000000000..b86a4d3758d --- /dev/null +++ b/queue-4.14/netfilter-ebtables-remove-bugprint-messages.patch @@ -0,0 +1,361 @@ +From d824548dae220820bdf69b2d1561b7c4b072783f Mon Sep 17 00:00:00 2001 +From: Florian Westphal +Date: Tue, 19 Feb 2019 00:37:21 +0100 +Subject: netfilter: ebtables: remove BUGPRINT messages + +From: Florian Westphal + +commit d824548dae220820bdf69b2d1561b7c4b072783f upstream. + +They are however frequently triggered by syzkaller, so remove them. + +ebtables userspace should never trigger any of these, so there is little +value in making them pr_debug (or ratelimited). + +Signed-off-by: Florian Westphal +Signed-off-by: Pablo Neira Ayuso +Signed-off-by: Greg Kroah-Hartman + +--- + net/bridge/netfilter/ebtables.c | 131 +++++++++++----------------------------- + 1 file changed, 39 insertions(+), 92 deletions(-) + +--- a/net/bridge/netfilter/ebtables.c ++++ b/net/bridge/netfilter/ebtables.c +@@ -31,10 +31,6 @@ + /* needed for logical [in,out]-dev filtering */ + #include "../br_private.h" + +-#define BUGPRINT(format, args...) printk("kernel msg: ebtables bug: please "\ +- "report to author: "format, ## args) +-/* #define BUGPRINT(format, args...) */ +- + /* Each cpu has its own set of counters, so there is no need for write_lock in + * the softirq + * For reading or updating the counters, the user context needs to +@@ -453,8 +449,6 @@ static int ebt_verify_pointers(const str + /* we make userspace set this right, + * so there is no misunderstanding + */ +- BUGPRINT("EBT_ENTRY_OR_ENTRIES shouldn't be set " +- "in distinguisher\n"); + return -EINVAL; + } + if (i != NF_BR_NUMHOOKS) +@@ -472,18 +466,14 @@ static int ebt_verify_pointers(const str + offset += e->next_offset; + } + } +- if (offset != limit) { +- BUGPRINT("entries_size too small\n"); ++ if (offset != limit) + return -EINVAL; +- } + + /* check if all valid hooks have a chain */ + for (i = 0; i < NF_BR_NUMHOOKS; i++) { + if (!newinfo->hook_entry[i] && +- (valid_hooks & (1 << i))) { +- BUGPRINT("Valid hook without chain\n"); ++ (valid_hooks & (1 << i))) + return -EINVAL; +- } + } + return 0; + } +@@ -510,26 +500,20 @@ ebt_check_entry_size_and_hooks(const str + /* this checks if the previous chain has as many entries + * as it said it has + */ +- if (*n != *cnt) { +- BUGPRINT("nentries does not equal the nr of entries " +- "in the chain\n"); ++ if (*n != *cnt) + return -EINVAL; +- } ++ + if (((struct ebt_entries *)e)->policy != EBT_DROP && + ((struct ebt_entries *)e)->policy != EBT_ACCEPT) { + /* only RETURN from udc */ + if (i != NF_BR_NUMHOOKS || +- ((struct ebt_entries *)e)->policy != EBT_RETURN) { +- BUGPRINT("bad policy\n"); ++ ((struct ebt_entries *)e)->policy != EBT_RETURN) + return -EINVAL; +- } + } + if (i == NF_BR_NUMHOOKS) /* it's a user defined chain */ + (*udc_cnt)++; +- if (((struct ebt_entries *)e)->counter_offset != *totalcnt) { +- BUGPRINT("counter_offset != totalcnt"); ++ if (((struct ebt_entries *)e)->counter_offset != *totalcnt) + return -EINVAL; +- } + *n = ((struct ebt_entries *)e)->nentries; + *cnt = 0; + return 0; +@@ -537,15 +521,13 @@ ebt_check_entry_size_and_hooks(const str + /* a plain old entry, heh */ + if (sizeof(struct ebt_entry) > e->watchers_offset || + e->watchers_offset > e->target_offset || +- e->target_offset >= e->next_offset) { +- BUGPRINT("entry offsets not in right order\n"); ++ e->target_offset >= e->next_offset) + return -EINVAL; +- } ++ + /* this is not checked anywhere else */ +- if (e->next_offset - e->target_offset < sizeof(struct ebt_entry_target)) { +- BUGPRINT("target size too small\n"); ++ if (e->next_offset - e->target_offset < sizeof(struct ebt_entry_target)) + return -EINVAL; +- } ++ + (*cnt)++; + (*totalcnt)++; + return 0; +@@ -665,18 +647,15 @@ ebt_check_entry(struct ebt_entry *e, str + if (e->bitmask == 0) + return 0; + +- if (e->bitmask & ~EBT_F_MASK) { +- BUGPRINT("Unknown flag for bitmask\n"); ++ if (e->bitmask & ~EBT_F_MASK) + return -EINVAL; +- } +- if (e->invflags & ~EBT_INV_MASK) { +- BUGPRINT("Unknown flag for inv bitmask\n"); ++ ++ if (e->invflags & ~EBT_INV_MASK) + return -EINVAL; +- } +- if ((e->bitmask & EBT_NOPROTO) && (e->bitmask & EBT_802_3)) { +- BUGPRINT("NOPROTO & 802_3 not allowed\n"); ++ ++ if ((e->bitmask & EBT_NOPROTO) && (e->bitmask & EBT_802_3)) + return -EINVAL; +- } ++ + /* what hook do we belong to? */ + for (i = 0; i < NF_BR_NUMHOOKS; i++) { + if (!newinfo->hook_entry[i]) +@@ -735,13 +714,11 @@ ebt_check_entry(struct ebt_entry *e, str + t->u.target = target; + if (t->u.target == &ebt_standard_target) { + if (gap < sizeof(struct ebt_standard_target)) { +- BUGPRINT("Standard target size too big\n"); + ret = -EFAULT; + goto cleanup_watchers; + } + if (((struct ebt_standard_target *)t)->verdict < + -NUM_STANDARD_TARGETS) { +- BUGPRINT("Invalid standard target\n"); + ret = -EFAULT; + goto cleanup_watchers; + } +@@ -801,10 +778,9 @@ static int check_chainloops(const struct + if (strcmp(t->u.name, EBT_STANDARD_TARGET)) + goto letscontinue; + if (e->target_offset + sizeof(struct ebt_standard_target) > +- e->next_offset) { +- BUGPRINT("Standard target size too big\n"); ++ e->next_offset) + return -1; +- } ++ + verdict = ((struct ebt_standard_target *)t)->verdict; + if (verdict >= 0) { /* jump to another chain */ + struct ebt_entries *hlp2 = +@@ -813,14 +789,12 @@ static int check_chainloops(const struct + if (hlp2 == cl_s[i].cs.chaininfo) + break; + /* bad destination or loop */ +- if (i == udc_cnt) { +- BUGPRINT("bad destination\n"); ++ if (i == udc_cnt) + return -1; +- } +- if (cl_s[i].cs.n) { +- BUGPRINT("loop\n"); ++ ++ if (cl_s[i].cs.n) + return -1; +- } ++ + if (cl_s[i].hookmask & (1 << hooknr)) + goto letscontinue; + /* this can't be 0, so the loop test is correct */ +@@ -853,24 +827,21 @@ static int translate_table(struct net *n + i = 0; + while (i < NF_BR_NUMHOOKS && !newinfo->hook_entry[i]) + i++; +- if (i == NF_BR_NUMHOOKS) { +- BUGPRINT("No valid hooks specified\n"); ++ if (i == NF_BR_NUMHOOKS) + return -EINVAL; +- } +- if (newinfo->hook_entry[i] != (struct ebt_entries *)newinfo->entries) { +- BUGPRINT("Chains don't start at beginning\n"); ++ ++ if (newinfo->hook_entry[i] != (struct ebt_entries *)newinfo->entries) + return -EINVAL; +- } ++ + /* make sure chains are ordered after each other in same order + * as their corresponding hooks + */ + for (j = i + 1; j < NF_BR_NUMHOOKS; j++) { + if (!newinfo->hook_entry[j]) + continue; +- if (newinfo->hook_entry[j] <= newinfo->hook_entry[i]) { +- BUGPRINT("Hook order must be followed\n"); ++ if (newinfo->hook_entry[j] <= newinfo->hook_entry[i]) + return -EINVAL; +- } ++ + i = j; + } + +@@ -888,15 +859,11 @@ static int translate_table(struct net *n + if (ret != 0) + return ret; + +- if (i != j) { +- BUGPRINT("nentries does not equal the nr of entries in the " +- "(last) chain\n"); ++ if (i != j) + return -EINVAL; +- } +- if (k != newinfo->nentries) { +- BUGPRINT("Total nentries is wrong\n"); ++ ++ if (k != newinfo->nentries) + return -EINVAL; +- } + + /* get the location of the udc, put them in an array + * while we're at it, allocate the chainstack +@@ -929,7 +896,6 @@ static int translate_table(struct net *n + ebt_get_udc_positions, newinfo, &i, cl_s); + /* sanity check */ + if (i != udc_cnt) { +- BUGPRINT("i != udc_cnt\n"); + vfree(cl_s); + return -EFAULT; + } +@@ -1030,7 +996,6 @@ static int do_replace_finish(struct net + goto free_unlock; + + if (repl->num_counters && repl->num_counters != t->private->nentries) { +- BUGPRINT("Wrong nr. of counters requested\n"); + ret = -EINVAL; + goto free_unlock; + } +@@ -1115,15 +1080,12 @@ static int do_replace(struct net *net, c + if (copy_from_user(&tmp, user, sizeof(tmp)) != 0) + return -EFAULT; + +- if (len != sizeof(tmp) + tmp.entries_size) { +- BUGPRINT("Wrong len argument\n"); ++ if (len != sizeof(tmp) + tmp.entries_size) + return -EINVAL; +- } + +- if (tmp.entries_size == 0) { +- BUGPRINT("Entries_size never zero\n"); ++ if (tmp.entries_size == 0) + return -EINVAL; +- } ++ + /* overflow check */ + if (tmp.nentries >= ((INT_MAX - sizeof(struct ebt_table_info)) / + NR_CPUS - SMP_CACHE_BYTES) / sizeof(struct ebt_counter)) +@@ -1150,7 +1112,6 @@ static int do_replace(struct net *net, c + } + if (copy_from_user( + newinfo->entries, tmp.entries, tmp.entries_size) != 0) { +- BUGPRINT("Couldn't copy entries from userspace\n"); + ret = -EFAULT; + goto free_entries; + } +@@ -1197,10 +1158,8 @@ int ebt_register_table(struct net *net, + + if (input_table == NULL || (repl = input_table->table) == NULL || + repl->entries == NULL || repl->entries_size == 0 || +- repl->counters != NULL || input_table->private != NULL) { +- BUGPRINT("Bad table data for ebt_register_table!!!\n"); ++ repl->counters != NULL || input_table->private != NULL) + return -EINVAL; +- } + + /* Don't add one table to multiple lists. */ + table = kmemdup(input_table, sizeof(struct ebt_table), GFP_KERNEL); +@@ -1238,13 +1197,10 @@ int ebt_register_table(struct net *net, + ((char *)repl->hook_entry[i] - repl->entries); + } + ret = translate_table(net, repl->name, newinfo); +- if (ret != 0) { +- BUGPRINT("Translate_table failed\n"); ++ if (ret != 0) + goto free_chainstack; +- } + + if (table->check && table->check(newinfo, table->valid_hooks)) { +- BUGPRINT("The table doesn't like its own initial data, lol\n"); + ret = -EINVAL; + goto free_chainstack; + } +@@ -1255,7 +1211,6 @@ int ebt_register_table(struct net *net, + list_for_each_entry(t, &net->xt.tables[NFPROTO_BRIDGE], list) { + if (strcmp(t->name, table->name) == 0) { + ret = -EEXIST; +- BUGPRINT("Table name already exists\n"); + goto free_unlock; + } + } +@@ -1327,7 +1282,6 @@ static int do_update_counters(struct net + goto free_tmp; + + if (num_counters != t->private->nentries) { +- BUGPRINT("Wrong nr of counters\n"); + ret = -EINVAL; + goto unlock_mutex; + } +@@ -1452,10 +1406,8 @@ static int copy_counters_to_user(struct + if (num_counters == 0) + return 0; + +- if (num_counters != nentries) { +- BUGPRINT("Num_counters wrong\n"); ++ if (num_counters != nentries) + return -EINVAL; +- } + + counterstmp = vmalloc(nentries * sizeof(*counterstmp)); + if (!counterstmp) +@@ -1501,15 +1453,11 @@ static int copy_everything_to_user(struc + (tmp.num_counters ? nentries * sizeof(struct ebt_counter) : 0)) + return -EINVAL; + +- if (tmp.nentries != nentries) { +- BUGPRINT("Nentries wrong\n"); ++ if (tmp.nentries != nentries) + return -EINVAL; +- } + +- if (tmp.entries_size != entries_size) { +- BUGPRINT("Wrong size\n"); ++ if (tmp.entries_size != entries_size) + return -EINVAL; +- } + + ret = copy_counters_to_user(t, oldcounters, tmp.counters, + tmp.num_counters, nentries); +@@ -1581,7 +1529,6 @@ static int do_ebt_get_ctl(struct sock *s + } + mutex_unlock(&ebt_mutex); + if (copy_to_user(user, &tmp, *len) != 0) { +- BUGPRINT("c2u Didn't work\n"); + ret = -EFAULT; + break; + } diff --git a/queue-4.14/series b/queue-4.14/series index 8985e8869ea..e3c8c899f43 100644 --- a/queue-4.14/series +++ b/queue-4.14/series @@ -15,3 +15,14 @@ alsa-x86-fix-runtime-pm-for-hdmi-lpe-audio.patch ext4-fix-null-pointer-dereference-while-journal-is-aborted.patch ext4-fix-data-corruption-caused-by-unaligned-direct-aio.patch ext4-brelse-all-indirect-buffer-in-ext4_ind_remove_space.patch +media-v4l2-ctrls.c-uvc-zero-v4l2_event.patch +bluetooth-hci_uart-check-if-socket-buffer-is-err_ptr-in-h4_recv_buf.patch +bluetooth-fix-decrementing-reference-count-twice-in-releasing-socket.patch +bluetooth-hci_ldisc-initialize-hci_dev-before-open.patch +bluetooth-hci_ldisc-postpone-hci_uart_proto_ready-bit-set-in-hci_uart_set_proto.patch +drm-reorder-set_property_atomic-to-avoid-returning-with-an-active-ww_ctx.patch +netfilter-ebtables-remove-bugprint-messages.patch +x86-unwind-handle-null-pointer-calls-better-in-frame-unwinder.patch +x86-unwind-add-hardcoded-orc-entry-for-null.patch +locking-lockdep-add-debug_locks-check-in-__lock_downgrade.patch +mm-mempolicy-fix-uninit-memory-access.patch diff --git a/queue-4.14/x86-unwind-add-hardcoded-orc-entry-for-null.patch b/queue-4.14/x86-unwind-add-hardcoded-orc-entry-for-null.patch new file mode 100644 index 00000000000..671757c19c3 --- /dev/null +++ b/queue-4.14/x86-unwind-add-hardcoded-orc-entry-for-null.patch @@ -0,0 +1,89 @@ +From ac5ceccce5501e43d217c596e4ee859f2a3fef79 Mon Sep 17 00:00:00 2001 +From: Jann Horn +Date: Fri, 1 Mar 2019 04:12:01 +0100 +Subject: x86/unwind: Add hardcoded ORC entry for NULL + +From: Jann Horn + +commit ac5ceccce5501e43d217c596e4ee859f2a3fef79 upstream. + +When the ORC unwinder is invoked for an oops caused by IP==0, +it currently has no idea what to do because there is no debug information +for the stack frame of NULL. + +But if RIP is NULL, it is very likely that the last successfully executed +instruction was an indirect CALL/JMP, and it is possible to unwind out in +the same way as for the first instruction of a normal function. Hardcode +a corresponding ORC entry. + +With an artificially-added NULL call in prctl_set_seccomp(), before this +patch, the trace is: + +Call Trace: + ? __x64_sys_prctl+0x402/0x680 + ? __ia32_sys_prctl+0x6e0/0x6e0 + ? __do_page_fault+0x457/0x620 + ? do_syscall_64+0x6d/0x160 + ? entry_SYSCALL_64_after_hwframe+0x44/0xa9 + +After this patch, the trace looks like this: + +Call Trace: + __x64_sys_prctl+0x402/0x680 + ? __ia32_sys_prctl+0x6e0/0x6e0 + ? __do_page_fault+0x457/0x620 + do_syscall_64+0x6d/0x160 + entry_SYSCALL_64_after_hwframe+0x44/0xa9 + +prctl_set_seccomp() still doesn't show up in the trace because for some +reason, tail call optimization is only disabled in builds that use the +frame pointer unwinder. + +Signed-off-by: Jann Horn +Signed-off-by: Thomas Gleixner +Acked-by: Josh Poimboeuf +Cc: Borislav Petkov +Cc: Andrew Morton +Cc: syzbot +Cc: "H. Peter Anvin" +Cc: Masahiro Yamada +Cc: Michal Marek +Cc: linux-kbuild@vger.kernel.org +Link: https://lkml.kernel.org/r/20190301031201.7416-2-jannh@google.com +Signed-off-by: Greg Kroah-Hartman + +--- + arch/x86/kernel/unwind_orc.c | 17 +++++++++++++++++ + 1 file changed, 17 insertions(+) + +--- a/arch/x86/kernel/unwind_orc.c ++++ b/arch/x86/kernel/unwind_orc.c +@@ -74,11 +74,28 @@ static struct orc_entry *orc_module_find + } + #endif + ++/* ++ * If we crash with IP==0, the last successfully executed instruction ++ * was probably an indirect function call with a NULL function pointer, ++ * and we don't have unwind information for NULL. ++ * This hardcoded ORC entry for IP==0 allows us to unwind from a NULL function ++ * pointer into its parent and then continue normally from there. ++ */ ++static struct orc_entry null_orc_entry = { ++ .sp_offset = sizeof(long), ++ .sp_reg = ORC_REG_SP, ++ .bp_reg = ORC_REG_UNDEFINED, ++ .type = ORC_TYPE_CALL ++}; ++ + static struct orc_entry *orc_find(unsigned long ip) + { + if (!orc_init) + return NULL; + ++ if (ip == 0) ++ return &null_orc_entry; ++ + /* For non-init vmlinux addresses, use the fast lookup table: */ + if (ip >= LOOKUP_START_IP && ip < LOOKUP_STOP_IP) { + unsigned int idx, start, stop; diff --git a/queue-4.14/x86-unwind-handle-null-pointer-calls-better-in-frame-unwinder.patch b/queue-4.14/x86-unwind-handle-null-pointer-calls-better-in-frame-unwinder.patch new file mode 100644 index 00000000000..c301e8ad2d4 --- /dev/null +++ b/queue-4.14/x86-unwind-handle-null-pointer-calls-better-in-frame-unwinder.patch @@ -0,0 +1,123 @@ +From f4f34e1b82eb4219d8eaa1c7e2e17ca219a6a2b5 Mon Sep 17 00:00:00 2001 +From: Jann Horn +Date: Fri, 1 Mar 2019 04:12:00 +0100 +Subject: x86/unwind: Handle NULL pointer calls better in frame unwinder + +From: Jann Horn + +commit f4f34e1b82eb4219d8eaa1c7e2e17ca219a6a2b5 upstream. + +When the frame unwinder is invoked for an oops caused by a call to NULL, it +currently skips the parent function because BP still points to the parent's +stack frame; the (nonexistent) current function only has the first half of +a stack frame, and BP doesn't point to it yet. + +Add a special case for IP==0 that calculates a fake BP from SP, then uses +the real BP for the next frame. + +Note that this handles first_frame specially: Return information about the +parent function as long as the saved IP is >=first_frame, even if the fake +BP points below it. + +With an artificially-added NULL call in prctl_set_seccomp(), before this +patch, the trace is: + +Call Trace: + ? prctl_set_seccomp+0x3a/0x50 + __x64_sys_prctl+0x457/0x6f0 + ? __ia32_sys_prctl+0x750/0x750 + do_syscall_64+0x72/0x160 + entry_SYSCALL_64_after_hwframe+0x44/0xa9 + +After this patch, the trace is: + +Call Trace: + prctl_set_seccomp+0x3a/0x50 + __x64_sys_prctl+0x457/0x6f0 + ? __ia32_sys_prctl+0x750/0x750 + do_syscall_64+0x72/0x160 + entry_SYSCALL_64_after_hwframe+0x44/0xa9 + +Signed-off-by: Jann Horn +Signed-off-by: Thomas Gleixner +Acked-by: Josh Poimboeuf +Cc: Borislav Petkov +Cc: Andrew Morton +Cc: syzbot +Cc: "H. Peter Anvin" +Cc: Masahiro Yamada +Cc: Michal Marek +Cc: linux-kbuild@vger.kernel.org +Link: https://lkml.kernel.org/r/20190301031201.7416-1-jannh@google.com +Signed-off-by: Greg Kroah-Hartman + +--- + arch/x86/include/asm/unwind.h | 6 ++++++ + arch/x86/kernel/unwind_frame.c | 25 ++++++++++++++++++++++--- + 2 files changed, 28 insertions(+), 3 deletions(-) + +--- a/arch/x86/include/asm/unwind.h ++++ b/arch/x86/include/asm/unwind.h +@@ -23,6 +23,12 @@ struct unwind_state { + #elif defined(CONFIG_UNWINDER_FRAME_POINTER) + bool got_irq; + unsigned long *bp, *orig_sp, ip; ++ /* ++ * If non-NULL: The current frame is incomplete and doesn't contain a ++ * valid BP. When looking for the next frame, use this instead of the ++ * non-existent saved BP. ++ */ ++ unsigned long *next_bp; + struct pt_regs *regs; + #else + unsigned long *sp; +--- a/arch/x86/kernel/unwind_frame.c ++++ b/arch/x86/kernel/unwind_frame.c +@@ -320,10 +320,14 @@ bool unwind_next_frame(struct unwind_sta + } + + /* Get the next frame pointer: */ +- if (state->regs) ++ if (state->next_bp) { ++ next_bp = state->next_bp; ++ state->next_bp = NULL; ++ } else if (state->regs) { + next_bp = (unsigned long *)state->regs->bp; +- else ++ } else { + next_bp = (unsigned long *)READ_ONCE_TASK_STACK(state->task, *state->bp); ++ } + + /* Move to the next frame if it's safe: */ + if (!update_stack_state(state, next_bp)) +@@ -398,6 +402,21 @@ void __unwind_start(struct unwind_state + + bp = get_frame_pointer(task, regs); + ++ /* ++ * If we crash with IP==0, the last successfully executed instruction ++ * was probably an indirect function call with a NULL function pointer. ++ * That means that SP points into the middle of an incomplete frame: ++ * *SP is a return pointer, and *(SP-sizeof(unsigned long)) is where we ++ * would have written a frame pointer if we hadn't crashed. ++ * Pretend that the frame is complete and that BP points to it, but save ++ * the real BP so that we can use it when looking for the next frame. ++ */ ++ if (regs && regs->ip == 0 && ++ (unsigned long *)kernel_stack_pointer(regs) >= first_frame) { ++ state->next_bp = bp; ++ bp = ((unsigned long *)kernel_stack_pointer(regs)) - 1; ++ } ++ + /* Initialize stack info and make sure the frame data is accessible: */ + get_stack_info(bp, state->task, &state->stack_info, + &state->stack_mask); +@@ -410,7 +429,7 @@ void __unwind_start(struct unwind_state + */ + while (!unwind_done(state) && + (!on_stack(&state->stack_info, first_frame, sizeof(long)) || +- state->bp < first_frame)) ++ (state->next_bp == NULL && state->bp < first_frame))) + unwind_next_frame(state); + } + EXPORT_SYMBOL_GPL(__unwind_start);