From: Sasha Levin Date: Sun, 8 Aug 2021 21:30:47 +0000 (-0400) Subject: Fixes for 4.9 X-Git-Tag: v4.4.280~67^2~1 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=a117dd5032c17ca9707797c0b1b00332f508fd30;p=thirdparty%2Fkernel%2Fstable-queue.git Fixes for 4.9 Signed-off-by: Sasha Levin --- diff --git a/queue-4.9/bluetooth-defer-cleanup-of-resources-in-hci_unregist.patch b/queue-4.9/bluetooth-defer-cleanup-of-resources-in-hci_unregist.patch new file mode 100644 index 00000000000..f2480d31917 --- /dev/null +++ b/queue-4.9/bluetooth-defer-cleanup-of-resources-in-hci_unregist.patch @@ -0,0 +1,244 @@ +From caa76ecba270414ef8f71f7bb727fd9345cb6e4e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 4 Aug 2021 19:26:56 +0900 +Subject: Bluetooth: defer cleanup of resources in hci_unregister_dev() + +From: Tetsuo Handa + +[ Upstream commit e04480920d1eec9c061841399aa6f35b6f987d8b ] + +syzbot is hitting might_sleep() warning at hci_sock_dev_event() due to +calling lock_sock() with rw spinlock held [1]. + +It seems that history of this locking problem is a trial and error. + +Commit b40df5743ee8 ("[PATCH] bluetooth: fix socket locking in +hci_sock_dev_event()") in 2.6.21-rc4 changed bh_lock_sock() to +lock_sock() as an attempt to fix lockdep warning. + +Then, commit 4ce61d1c7a8e ("[BLUETOOTH]: Fix locking in +hci_sock_dev_event().") in 2.6.22-rc2 changed lock_sock() to +local_bh_disable() + bh_lock_sock_nested() as an attempt to fix the +sleep in atomic context warning. + +Then, commit 4b5dd696f81b ("Bluetooth: Remove local_bh_disable() from +hci_sock.c") in 3.3-rc1 removed local_bh_disable(). + +Then, commit e305509e678b ("Bluetooth: use correct lock to prevent UAF +of hdev object") in 5.13-rc5 again changed bh_lock_sock_nested() to +lock_sock() as an attempt to fix CVE-2021-3573. + +This difficulty comes from current implementation that +hci_sock_dev_event(HCI_DEV_UNREG) is responsible for dropping all +references from sockets because hci_unregister_dev() immediately +reclaims resources as soon as returning from +hci_sock_dev_event(HCI_DEV_UNREG). + +But the history suggests that hci_sock_dev_event(HCI_DEV_UNREG) was not +doing what it should do. + +Therefore, instead of trying to detach sockets from device, let's accept +not detaching sockets from device at hci_sock_dev_event(HCI_DEV_UNREG), +by moving actual cleanup of resources from hci_unregister_dev() to +hci_cleanup_dev() which is called by bt_host_release() when all +references to this unregistered device (which is a kobject) are gone. + +Since hci_sock_dev_event(HCI_DEV_UNREG) no longer resets +hci_pi(sk)->hdev, we need to check whether this device was unregistered +and return an error based on HCI_UNREGISTER flag. There might be subtle +behavioral difference in "monitor the hdev" functionality; please report +if you found something went wrong due to this patch. + +Link: https://syzkaller.appspot.com/bug?extid=a5df189917e79d5e59c9 [1] +Reported-by: syzbot +Suggested-by: Linus Torvalds +Signed-off-by: Tetsuo Handa +Fixes: e305509e678b ("Bluetooth: use correct lock to prevent UAF of hdev object") +Acked-by: Luiz Augusto von Dentz +Signed-off-by: Linus Torvalds +Signed-off-by: Sasha Levin +--- + include/net/bluetooth/hci_core.h | 1 + + net/bluetooth/hci_core.c | 16 +++++------ + net/bluetooth/hci_sock.c | 49 +++++++++++++++++++++----------- + net/bluetooth/hci_sysfs.c | 3 ++ + 4 files changed, 45 insertions(+), 24 deletions(-) + +diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h +index 33db6c6d3fba..819796fb9d46 100644 +--- a/include/net/bluetooth/hci_core.h ++++ b/include/net/bluetooth/hci_core.h +@@ -1028,6 +1028,7 @@ struct hci_dev *hci_alloc_dev(void); + void hci_free_dev(struct hci_dev *hdev); + int hci_register_dev(struct hci_dev *hdev); + void hci_unregister_dev(struct hci_dev *hdev); ++void hci_cleanup_dev(struct hci_dev *hdev); + int hci_suspend_dev(struct hci_dev *hdev); + int hci_resume_dev(struct hci_dev *hdev); + int hci_reset_dev(struct hci_dev *hdev); +diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c +index 839c534bdcdb..8517da7f282e 100644 +--- a/net/bluetooth/hci_core.c ++++ b/net/bluetooth/hci_core.c +@@ -3146,14 +3146,10 @@ EXPORT_SYMBOL(hci_register_dev); + /* Unregister HCI device */ + void hci_unregister_dev(struct hci_dev *hdev) + { +- int id; +- + BT_DBG("%p name %s bus %d", hdev, hdev->name, hdev->bus); + + hci_dev_set_flag(hdev, HCI_UNREGISTER); + +- id = hdev->id; +- + write_lock(&hci_dev_list_lock); + list_del(&hdev->list); + write_unlock(&hci_dev_list_lock); +@@ -3182,7 +3178,14 @@ void hci_unregister_dev(struct hci_dev *hdev) + } + + device_del(&hdev->dev); ++ /* Actual cleanup is deferred until hci_cleanup_dev(). */ ++ hci_dev_put(hdev); ++} ++EXPORT_SYMBOL(hci_unregister_dev); + ++/* Cleanup HCI device */ ++void hci_cleanup_dev(struct hci_dev *hdev) ++{ + debugfs_remove_recursive(hdev->debugfs); + kfree_const(hdev->hw_info); + kfree_const(hdev->fw_info); +@@ -3204,11 +3207,8 @@ void hci_unregister_dev(struct hci_dev *hdev) + hci_discovery_filter_clear(hdev); + hci_dev_unlock(hdev); + +- hci_dev_put(hdev); +- +- ida_simple_remove(&hci_index_ida, id); ++ ida_simple_remove(&hci_index_ida, hdev->id); + } +-EXPORT_SYMBOL(hci_unregister_dev); + + /* Suspend HCI device */ + int hci_suspend_dev(struct hci_dev *hdev) +diff --git a/net/bluetooth/hci_sock.c b/net/bluetooth/hci_sock.c +index 35f5585188de..d30163eb1643 100644 +--- a/net/bluetooth/hci_sock.c ++++ b/net/bluetooth/hci_sock.c +@@ -59,6 +59,17 @@ struct hci_pinfo { + char comm[TASK_COMM_LEN]; + }; + ++static struct hci_dev *hci_hdev_from_sock(struct sock *sk) ++{ ++ struct hci_dev *hdev = hci_pi(sk)->hdev; ++ ++ if (!hdev) ++ return ERR_PTR(-EBADFD); ++ if (hci_dev_test_flag(hdev, HCI_UNREGISTER)) ++ return ERR_PTR(-EPIPE); ++ return hdev; ++} ++ + void hci_sock_set_flag(struct sock *sk, int nr) + { + set_bit(nr, &hci_pi(sk)->flags); +@@ -747,19 +758,13 @@ void hci_sock_dev_event(struct hci_dev *hdev, int event) + if (event == HCI_DEV_UNREG) { + struct sock *sk; + +- /* Detach sockets from device */ ++ /* Wake up sockets using this dead device */ + read_lock(&hci_sk_list.lock); + sk_for_each(sk, &hci_sk_list.head) { +- lock_sock(sk); + if (hci_pi(sk)->hdev == hdev) { +- hci_pi(sk)->hdev = NULL; + sk->sk_err = EPIPE; +- sk->sk_state = BT_OPEN; + sk->sk_state_change(sk); +- +- hci_dev_put(hdev); + } +- release_sock(sk); + } + read_unlock(&hci_sk_list.lock); + } +@@ -918,10 +923,10 @@ static int hci_sock_blacklist_del(struct hci_dev *hdev, void __user *arg) + static int hci_sock_bound_ioctl(struct sock *sk, unsigned int cmd, + unsigned long arg) + { +- struct hci_dev *hdev = hci_pi(sk)->hdev; ++ struct hci_dev *hdev = hci_hdev_from_sock(sk); + +- if (!hdev) +- return -EBADFD; ++ if (IS_ERR(hdev)) ++ return PTR_ERR(hdev); + + if (hci_dev_test_flag(hdev, HCI_USER_CHANNEL)) + return -EBUSY; +@@ -1075,6 +1080,18 @@ static int hci_sock_bind(struct socket *sock, struct sockaddr *addr, + + lock_sock(sk); + ++ /* Allow detaching from dead device and attaching to alive device, if ++ * the caller wants to re-bind (instead of close) this socket in ++ * response to hci_sock_dev_event(HCI_DEV_UNREG) notification. ++ */ ++ hdev = hci_pi(sk)->hdev; ++ if (hdev && hci_dev_test_flag(hdev, HCI_UNREGISTER)) { ++ hci_pi(sk)->hdev = NULL; ++ sk->sk_state = BT_OPEN; ++ hci_dev_put(hdev); ++ } ++ hdev = NULL; ++ + if (sk->sk_state == BT_BOUND) { + err = -EALREADY; + goto done; +@@ -1351,9 +1368,9 @@ static int hci_sock_getname(struct socket *sock, struct sockaddr *addr, + + lock_sock(sk); + +- hdev = hci_pi(sk)->hdev; +- if (!hdev) { +- err = -EBADFD; ++ hdev = hci_hdev_from_sock(sk); ++ if (IS_ERR(hdev)) { ++ err = PTR_ERR(hdev); + goto done; + } + +@@ -1713,9 +1730,9 @@ static int hci_sock_sendmsg(struct socket *sock, struct msghdr *msg, + goto done; + } + +- hdev = hci_pi(sk)->hdev; +- if (!hdev) { +- err = -EBADFD; ++ hdev = hci_hdev_from_sock(sk); ++ if (IS_ERR(hdev)) { ++ err = PTR_ERR(hdev); + goto done; + } + +diff --git a/net/bluetooth/hci_sysfs.c b/net/bluetooth/hci_sysfs.c +index ca7a35ebaefb..cb7d06bb0243 100644 +--- a/net/bluetooth/hci_sysfs.c ++++ b/net/bluetooth/hci_sysfs.c +@@ -82,6 +82,9 @@ void hci_conn_del_sysfs(struct hci_conn *conn) + static void bt_host_release(struct device *dev) + { + struct hci_dev *hdev = to_hci_dev(dev); ++ ++ if (hci_dev_test_flag(hdev, HCI_UNREGISTER)) ++ hci_cleanup_dev(hdev); + kfree(hdev); + module_put(THIS_MODULE); + } +-- +2.30.2 + diff --git a/queue-4.9/bnx2x-fix-an-error-code-in-bnx2x_nic_load.patch b/queue-4.9/bnx2x-fix-an-error-code-in-bnx2x_nic_load.patch new file mode 100644 index 00000000000..0608bca9ddc --- /dev/null +++ b/queue-4.9/bnx2x-fix-an-error-code-in-bnx2x_nic_load.patch @@ -0,0 +1,37 @@ +From e7d88c99c24bfd31654906247a78713b4070bb8b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 5 Aug 2021 13:38:26 +0300 +Subject: bnx2x: fix an error code in bnx2x_nic_load() + +From: Dan Carpenter + +[ Upstream commit fb653827c758725b149b5c924a5eb50ab4812750 ] + +Set the error code if bnx2x_alloc_fw_stats_mem() fails. The current +code returns success. + +Fixes: ad5afc89365e ("bnx2x: Separate VF and PF logic") +Signed-off-by: Dan Carpenter +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c +index 46a7dcf2ff4a..9d7f491931ce 100644 +--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c ++++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c +@@ -2672,7 +2672,8 @@ int bnx2x_nic_load(struct bnx2x *bp, int load_mode) + } + + /* Allocated memory for FW statistics */ +- if (bnx2x_alloc_fw_stats_mem(bp)) ++ rc = bnx2x_alloc_fw_stats_mem(bp); ++ if (rc) + LOAD_ERROR_EXIT(bp, load_error0); + + /* request pf to initialize status blocks */ +-- +2.30.2 + diff --git a/queue-4.9/media-videobuf2-core-dequeue-if-start_streaming-fail.patch b/queue-4.9/media-videobuf2-core-dequeue-if-start_streaming-fail.patch new file mode 100644 index 00000000000..361b7a0484a --- /dev/null +++ b/queue-4.9/media-videobuf2-core-dequeue-if-start_streaming-fail.patch @@ -0,0 +1,71 @@ +From 7e2a7fa1eb1e4da6c088792bc19792e8ae9f514b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 30 Jun 2021 09:58:23 +0200 +Subject: media: videobuf2-core: dequeue if start_streaming fails + +From: Hans Verkuil + +[ Upstream commit c592b46907adbeb81243f7eb7a468c36692658b8 ] + +If a vb2_queue sets q->min_buffers_needed then when the number of +queued buffers reaches q->min_buffers_needed, vb2_core_qbuf() will call +the start_streaming() callback. If start_streaming() returns an error, +then that error was just returned by vb2_core_qbuf(), but the buffer +was still queued. However, userspace expects that if VIDIOC_QBUF fails, +the buffer is returned dequeued. + +So if start_streaming() fails, then remove the buffer from the queue, +thus avoiding this unwanted side-effect. + +Signed-off-by: Hans Verkuil +Reviewed-by: Laurent Pinchart +Tested-by: Kieran Bingham +Fixes: b3379c6201bb ("[media] vb2: only call start_streaming if sufficient buffers are queued") +Signed-off-by: Mauro Carvalho Chehab +Signed-off-by: Sasha Levin +--- + drivers/media/v4l2-core/videobuf2-core.c | 13 ++++++++++++- + 1 file changed, 12 insertions(+), 1 deletion(-) + +diff --git a/drivers/media/v4l2-core/videobuf2-core.c b/drivers/media/v4l2-core/videobuf2-core.c +index b1a4d4e2341b..3ac9f7260e72 100644 +--- a/drivers/media/v4l2-core/videobuf2-core.c ++++ b/drivers/media/v4l2-core/videobuf2-core.c +@@ -1370,6 +1370,7 @@ static int vb2_start_streaming(struct vb2_queue *q) + int vb2_core_qbuf(struct vb2_queue *q, unsigned int index, void *pb) + { + struct vb2_buffer *vb; ++ enum vb2_buffer_state orig_state; + int ret; + + if (q->error) { +@@ -1399,6 +1400,7 @@ int vb2_core_qbuf(struct vb2_queue *q, unsigned int index, void *pb) + * Add to the queued buffers list, a buffer will stay on it until + * dequeued in dqbuf. + */ ++ orig_state = vb->state; + list_add_tail(&vb->queued_entry, &q->queued_list); + q->queued_count++; + q->waiting_for_buffers = false; +@@ -1429,8 +1431,17 @@ int vb2_core_qbuf(struct vb2_queue *q, unsigned int index, void *pb) + if (q->streaming && !q->start_streaming_called && + q->queued_count >= q->min_buffers_needed) { + ret = vb2_start_streaming(q); +- if (ret) ++ if (ret) { ++ /* ++ * Since vb2_core_qbuf will return with an error, ++ * we should return it to state DEQUEUED since ++ * the error indicates that the buffer wasn't queued. ++ */ ++ list_del(&vb->queued_entry); ++ q->queued_count--; ++ vb->state = orig_state; + return ret; ++ } + } + + dprintk(1, "qbuf of buffer %d succeeded\n", vb->index); +-- +2.30.2 + diff --git a/queue-4.9/mips-fix-non-posix-regexp.patch b/queue-4.9/mips-fix-non-posix-regexp.patch new file mode 100644 index 00000000000..79c9da6a47f --- /dev/null +++ b/queue-4.9/mips-fix-non-posix-regexp.patch @@ -0,0 +1,57 @@ +From 2ce00e749003f8a2dd4108578fe564f0a808375f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 8 Jul 2021 10:57:10 +0200 +Subject: mips: Fix non-POSIX regexp + +From: H. Nikolaus Schaller + +[ Upstream commit 28bbbb9875a35975904e46f9b06fa689d051b290 ] + +When cross compiling a MIPS kernel on a BSD based HOSTCC leads +to errors like + + SYNC include/config/auto.conf.cmd - due to: .config +egrep: empty (sub)expression + UPD include/config/kernel.release + HOSTCC scripts/dtc/dtc.o - due to target missing + +It turns out that egrep uses this egrep pattern: + + (|MINOR_|PATCHLEVEL_) + +This is not valid syntax or gives undefined results according +to POSIX 9.5.3 ERE Grammar + + https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap09.html + +It seems to be silently accepted by the Linux egrep implementation +while a BSD host complains. + +Such patterns can be replaced by a transformation like + + "(|p1|p2)" -> "(p1|p2)?" + +Fixes: 48c35b2d245f ("[MIPS] There is no __GNUC_MAJOR__") +Signed-off-by: H. Nikolaus Schaller +Signed-off-by: Masahiro Yamada +Signed-off-by: Sasha Levin +--- + arch/mips/Makefile | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/arch/mips/Makefile b/arch/mips/Makefile +index 25f3bfef9b39..af4eff7d22ec 100644 +--- a/arch/mips/Makefile ++++ b/arch/mips/Makefile +@@ -286,7 +286,7 @@ LDFLAGS += -m $(ld-emul) + + ifdef CONFIG_MIPS + CHECKFLAGS += $(shell $(CC) $(KBUILD_CFLAGS) -dM -E -x c /dev/null | \ +- egrep -vw '__GNUC_(|MINOR_|PATCHLEVEL_)_' | \ ++ egrep -vw '__GNUC_(MINOR_|PATCHLEVEL_)?_' | \ + sed -e "s/^\#define /-D'/" -e "s/ /'='/" -e "s/$$/'/" -e 's/\$$/&&/g') + ifdef CONFIG_64BIT + CHECKFLAGS += -m64 +-- +2.30.2 + diff --git a/queue-4.9/net-fec-fix-use-after-free-in-fec_drv_remove.patch b/queue-4.9/net-fec-fix-use-after-free-in-fec_drv_remove.patch new file mode 100644 index 00000000000..3e5fad36a61 --- /dev/null +++ b/queue-4.9/net-fec-fix-use-after-free-in-fec_drv_remove.patch @@ -0,0 +1,50 @@ +From 8de45b1527842b393600ccdec39b128fb39bc14c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 4 Aug 2021 18:51:51 +0300 +Subject: net: fec: fix use-after-free in fec_drv_remove + +From: Pavel Skripkin + +[ Upstream commit 44712965bf12ae1758cec4de53816ed4b914ca1a ] + +Smatch says: + drivers/net/ethernet/freescale/fec_main.c:3994 fec_drv_remove() error: Using fep after free_{netdev,candev}(ndev); + drivers/net/ethernet/freescale/fec_main.c:3995 fec_drv_remove() error: Using fep after free_{netdev,candev}(ndev); + +Since fep pointer is netdev private data, accessing it after free_netdev() +call can cause use-after-free bug. Fix it by moving free_netdev() call at +the end of the function + +Reported-by: Dan Carpenter +Fixes: a31eda65ba21 ("net: fec: fix clock count mis-match") +Signed-off-by: Pavel Skripkin +Reviewed-by: Joakim Zhang +Reviewed-by: Jesse Brandeburg +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/freescale/fec_main.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/net/ethernet/freescale/fec_main.c b/drivers/net/ethernet/freescale/fec_main.c +index 9b3ea0406e0d..5fc40f025d21 100644 +--- a/drivers/net/ethernet/freescale/fec_main.c ++++ b/drivers/net/ethernet/freescale/fec_main.c +@@ -3546,13 +3546,13 @@ fec_drv_remove(struct platform_device *pdev) + if (of_phy_is_fixed_link(np)) + of_phy_deregister_fixed_link(np); + of_node_put(fep->phy_node); +- free_netdev(ndev); + + clk_disable_unprepare(fep->clk_ahb); + clk_disable_unprepare(fep->clk_ipg); + pm_runtime_put_noidle(&pdev->dev); + pm_runtime_disable(&pdev->dev); + ++ free_netdev(ndev); + return 0; + } + +-- +2.30.2 + diff --git a/queue-4.9/net-natsemi-fix-missing-pci_disable_device-in-probe-.patch b/queue-4.9/net-natsemi-fix-missing-pci_disable_device-in-probe-.patch new file mode 100644 index 00000000000..fd12a493f3d --- /dev/null +++ b/queue-4.9/net-natsemi-fix-missing-pci_disable_device-in-probe-.patch @@ -0,0 +1,65 @@ +From 3980ba0bb97fd724581c8491da60c8b1476f7fec Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 31 Jul 2021 14:38:01 +0800 +Subject: net: natsemi: Fix missing pci_disable_device() in probe and remove + +From: Wang Hai + +[ Upstream commit 7fe74dfd41c428afb24e2e615470832fa997ff14 ] + +Replace pci_enable_device() with pcim_enable_device(), +pci_disable_device() and pci_release_regions() will be +called in release automatically. + +Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") +Reported-by: Hulk Robot +Signed-off-by: Wang Hai +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/natsemi/natsemi.c | 8 ++------ + 1 file changed, 2 insertions(+), 6 deletions(-) + +diff --git a/drivers/net/ethernet/natsemi/natsemi.c b/drivers/net/ethernet/natsemi/natsemi.c +index ed89029ff75b..c0e128e17321 100644 +--- a/drivers/net/ethernet/natsemi/natsemi.c ++++ b/drivers/net/ethernet/natsemi/natsemi.c +@@ -817,7 +817,7 @@ static int natsemi_probe1(struct pci_dev *pdev, const struct pci_device_id *ent) + printk(version); + #endif + +- i = pci_enable_device(pdev); ++ i = pcim_enable_device(pdev); + if (i) return i; + + /* natsemi has a non-standard PM control register +@@ -850,7 +850,7 @@ static int natsemi_probe1(struct pci_dev *pdev, const struct pci_device_id *ent) + ioaddr = ioremap(iostart, iosize); + if (!ioaddr) { + i = -ENOMEM; +- goto err_ioremap; ++ goto err_pci_request_regions; + } + + /* Work around the dropped serial bit. */ +@@ -968,9 +968,6 @@ static int natsemi_probe1(struct pci_dev *pdev, const struct pci_device_id *ent) + err_register_netdev: + iounmap(ioaddr); + +- err_ioremap: +- pci_release_regions(pdev); +- + err_pci_request_regions: + free_netdev(dev); + return i; +@@ -3228,7 +3225,6 @@ static void natsemi_remove1(struct pci_dev *pdev) + + NATSEMI_REMOVE_FILE(pdev, dspcfg_workaround); + unregister_netdev (dev); +- pci_release_regions (pdev); + iounmap(ioaddr); + free_netdev (dev); + } +-- +2.30.2 + diff --git a/queue-4.9/net-pegasus-fix-uninit-value-in-get_interrupt_interv.patch b/queue-4.9/net-pegasus-fix-uninit-value-in-get_interrupt_interv.patch new file mode 100644 index 00000000000..9086c879879 --- /dev/null +++ b/queue-4.9/net-pegasus-fix-uninit-value-in-get_interrupt_interv.patch @@ -0,0 +1,96 @@ +From 84fee2f4ba840acdd7624597c7592c800868cc87 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 4 Aug 2021 17:30:05 +0300 +Subject: net: pegasus: fix uninit-value in get_interrupt_interval + +From: Pavel Skripkin + +[ Upstream commit af35fc37354cda3c9c8cc4961b1d24bdc9d27903 ] + +Syzbot reported uninit value pegasus_probe(). The problem was in missing +error handling. + +get_interrupt_interval() internally calls read_eprom_word() which can +fail in some cases. For example: failed to receive usb control message. +These cases should be handled to prevent uninit value bug, since +read_eprom_word() will not initialize passed stack variable in case of +internal failure. + +Fail log: + +BUG: KMSAN: uninit-value in get_interrupt_interval drivers/net/usb/pegasus.c:746 [inline] +BUG: KMSAN: uninit-value in pegasus_probe+0x10e7/0x4080 drivers/net/usb/pegasus.c:1152 +CPU: 1 PID: 825 Comm: kworker/1:1 Not tainted 5.12.0-rc6-syzkaller #0 +... +Workqueue: usb_hub_wq hub_event +Call Trace: + __dump_stack lib/dump_stack.c:79 [inline] + dump_stack+0x24c/0x2e0 lib/dump_stack.c:120 + kmsan_report+0xfb/0x1e0 mm/kmsan/kmsan_report.c:118 + __msan_warning+0x5c/0xa0 mm/kmsan/kmsan_instr.c:197 + get_interrupt_interval drivers/net/usb/pegasus.c:746 [inline] + pegasus_probe+0x10e7/0x4080 drivers/net/usb/pegasus.c:1152 +.... + +Local variable ----data.i@pegasus_probe created at: + get_interrupt_interval drivers/net/usb/pegasus.c:1151 [inline] + pegasus_probe+0xe57/0x4080 drivers/net/usb/pegasus.c:1152 + get_interrupt_interval drivers/net/usb/pegasus.c:1151 [inline] + pegasus_probe+0xe57/0x4080 drivers/net/usb/pegasus.c:1152 + +Reported-and-tested-by: syzbot+02c9f70f3afae308464a@syzkaller.appspotmail.com +Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") +Signed-off-by: Pavel Skripkin +Link: https://lore.kernel.org/r/20210804143005.439-1-paskripkin@gmail.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/usb/pegasus.c | 14 +++++++++++--- + 1 file changed, 11 insertions(+), 3 deletions(-) + +diff --git a/drivers/net/usb/pegasus.c b/drivers/net/usb/pegasus.c +index 5fe9f1273fe2..6cfc6faf9747 100644 +--- a/drivers/net/usb/pegasus.c ++++ b/drivers/net/usb/pegasus.c +@@ -755,12 +755,16 @@ static inline void disable_net_traffic(pegasus_t *pegasus) + set_registers(pegasus, EthCtrl0, sizeof(tmp), &tmp); + } + +-static inline void get_interrupt_interval(pegasus_t *pegasus) ++static inline int get_interrupt_interval(pegasus_t *pegasus) + { + u16 data; + u8 interval; ++ int ret; ++ ++ ret = read_eprom_word(pegasus, 4, &data); ++ if (ret < 0) ++ return ret; + +- read_eprom_word(pegasus, 4, &data); + interval = data >> 8; + if (pegasus->usb->speed != USB_SPEED_HIGH) { + if (interval < 0x80) { +@@ -775,6 +779,8 @@ static inline void get_interrupt_interval(pegasus_t *pegasus) + } + } + pegasus->intr_interval = interval; ++ ++ return 0; + } + + static void set_carrier(struct net_device *net) +@@ -1191,7 +1197,9 @@ static int pegasus_probe(struct usb_interface *intf, + | NETIF_MSG_PROBE | NETIF_MSG_LINK); + + pegasus->features = usb_dev_id[dev_index].private; +- get_interrupt_interval(pegasus); ++ res = get_interrupt_interval(pegasus); ++ if (res) ++ goto out2; + if (reset_mac(pegasus)) { + dev_err(&intf->dev, "can't reset MAC\n"); + res = -EIO; +-- +2.30.2 + diff --git a/queue-4.9/net-vxge-fix-use-after-free-in-vxge_device_unregiste.patch b/queue-4.9/net-vxge-fix-use-after-free-in-vxge_device_unregiste.patch new file mode 100644 index 00000000000..69accec221a --- /dev/null +++ b/queue-4.9/net-vxge-fix-use-after-free-in-vxge_device_unregiste.patch @@ -0,0 +1,53 @@ +From eca245ac5214503c92d75077df94ba7a7e1121fc Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 4 Aug 2021 18:52:20 +0300 +Subject: net: vxge: fix use-after-free in vxge_device_unregister + +From: Pavel Skripkin + +[ Upstream commit 942e560a3d3862dd5dee1411dbdd7097d29b8416 ] + +Smatch says: +drivers/net/ethernet/neterion/vxge/vxge-main.c:3518 vxge_device_unregister() error: Using vdev after free_{netdev,candev}(dev); +drivers/net/ethernet/neterion/vxge/vxge-main.c:3518 vxge_device_unregister() error: Using vdev after free_{netdev,candev}(dev); +drivers/net/ethernet/neterion/vxge/vxge-main.c:3520 vxge_device_unregister() error: Using vdev after free_{netdev,candev}(dev); +drivers/net/ethernet/neterion/vxge/vxge-main.c:3520 vxge_device_unregister() error: Using vdev after free_{netdev,candev}(dev); + +Since vdev pointer is netdev private data accessing it after free_netdev() +call can cause use-after-free bug. Fix it by moving free_netdev() call at +the end of the function + +Fixes: 6cca200362b4 ("vxge: cleanup probe error paths") +Reported-by: Dan Carpenter +Signed-off-by: Pavel Skripkin +Reviewed-by: Jesse Brandeburg +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/neterion/vxge/vxge-main.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/drivers/net/ethernet/neterion/vxge/vxge-main.c b/drivers/net/ethernet/neterion/vxge/vxge-main.c +index e0993eba5df3..c6950e580883 100644 +--- a/drivers/net/ethernet/neterion/vxge/vxge-main.c ++++ b/drivers/net/ethernet/neterion/vxge/vxge-main.c +@@ -3539,13 +3539,13 @@ static void vxge_device_unregister(struct __vxge_hw_device *hldev) + + kfree(vdev->vpaths); + +- /* we are safe to free it now */ +- free_netdev(dev); +- + vxge_debug_init(vdev->level_trace, "%s: ethernet device unregistered", + buf); + vxge_debug_entryexit(vdev->level_trace, "%s: %s:%d Exiting...", buf, + __func__, __LINE__); ++ ++ /* we are safe to free it now */ ++ free_netdev(dev); + } + + /* +-- +2.30.2 + diff --git a/queue-4.9/scsi-sr-return-correct-event-when-media-event-code-i.patch b/queue-4.9/scsi-sr-return-correct-event-when-media-event-code-i.patch new file mode 100644 index 00000000000..5deb1656899 --- /dev/null +++ b/queue-4.9/scsi-sr-return-correct-event-when-media-event-code-i.patch @@ -0,0 +1,46 @@ +From a98eb4e1ec459453ecb525b7da86159092a31db3 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 26 Jul 2021 19:49:13 +0800 +Subject: scsi: sr: Return correct event when media event code is 3 + +From: Li Manyi + +[ Upstream commit 5c04243a56a7977185b00400e59ca7e108004faf ] + +Media event code 3 is defined in the MMC-6 spec as follows: + + "MediaRemoval: The media has been removed from the specified slot, and + the Drive is unable to access the media without user intervention. This + applies to media changers only." + +This indicated that treating the condition as an EJECT_REQUEST was +appropriate. However, doing so had the unfortunate side-effect of causing +the drive tray to be physically ejected on resume. Instead treat the event +as a MEDIA_CHANGE request. + +Fixes: 7dd753ca59d6 ("scsi: sr: Return appropriate error code when disk is ejected") +Link: https://bugzilla.kernel.org/show_bug.cgi?id=213759 +Link: https://lore.kernel.org/r/20210726114913.6760-1-limanyi@uniontech.com +Signed-off-by: Li Manyi +Signed-off-by: Martin K. Petersen +Signed-off-by: Sasha Levin +--- + drivers/scsi/sr.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/scsi/sr.c b/drivers/scsi/sr.c +index 5e51a39a0c27..9b63e46edffc 100644 +--- a/drivers/scsi/sr.c ++++ b/drivers/scsi/sr.c +@@ -217,7 +217,7 @@ static unsigned int sr_get_events(struct scsi_device *sdev) + else if (med->media_event_code == 2) + return DISK_EVENT_MEDIA_CHANGE; + else if (med->media_event_code == 3) +- return DISK_EVENT_EJECT_REQUEST; ++ return DISK_EVENT_MEDIA_CHANGE; + return 0; + } + +-- +2.30.2 + diff --git a/queue-4.9/series b/queue-4.9/series new file mode 100644 index 00000000000..832631babe2 --- /dev/null +++ b/queue-4.9/series @@ -0,0 +1,9 @@ +scsi-sr-return-correct-event-when-media-event-code-i.patch +media-videobuf2-core-dequeue-if-start_streaming-fail.patch +net-natsemi-fix-missing-pci_disable_device-in-probe-.patch +mips-fix-non-posix-regexp.patch +bnx2x-fix-an-error-code-in-bnx2x_nic_load.patch +net-pegasus-fix-uninit-value-in-get_interrupt_interv.patch +net-fec-fix-use-after-free-in-fec_drv_remove.patch +net-vxge-fix-use-after-free-in-vxge_device_unregiste.patch +bluetooth-defer-cleanup-of-resources-in-hci_unregist.patch