From: Greg Kroah-Hartman Date: Sun, 11 Jun 2023 13:19:26 +0000 (+0200) Subject: 5.4-stable patches X-Git-Tag: v4.14.318~45 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=4ff3ef11d66f0e8b0408925f9e21be5cb9f31f15;p=thirdparty%2Fkernel%2Fstable-queue.git 5.4-stable patches added patches: bluetooth-fix-use-after-free-in-hci_remove_ltk-hci_remove_irk.patch can-j1939-avoid-possible-use-after-free-when-j1939_can_rx_register-fails.patch can-j1939-change-j1939_netdev_lock-type-to-mutex.patch can-j1939-j1939_sk_send_loop_abort-improved-error-queue-handling-in-j1939-socket.patch ceph-fix-use-after-free-bug-for-inodes-when-flushing-capsnaps.patch pinctrl-meson-axg-add-missing-gpioa_18-gpio-group.patch rbd-move-rbd_obj_flag_copyup_enabled-flag-setting.patch usb-usbfs-enforce-page-requirements-for-mmap.patch usb-usbfs-use-consistent-mmap-functions.patch --- diff --git a/queue-5.4/bluetooth-fix-use-after-free-in-hci_remove_ltk-hci_remove_irk.patch b/queue-5.4/bluetooth-fix-use-after-free-in-hci_remove_ltk-hci_remove_irk.patch new file mode 100644 index 00000000000..52ec6745aff --- /dev/null +++ b/queue-5.4/bluetooth-fix-use-after-free-in-hci_remove_ltk-hci_remove_irk.patch @@ -0,0 +1,48 @@ +From c5d2b6fa26b5b8386a9cc902cdece3a46bef2bd2 Mon Sep 17 00:00:00 2001 +From: Luiz Augusto von Dentz +Date: Tue, 30 May 2023 13:48:44 -0700 +Subject: Bluetooth: Fix use-after-free in hci_remove_ltk/hci_remove_irk + +From: Luiz Augusto von Dentz + +commit c5d2b6fa26b5b8386a9cc902cdece3a46bef2bd2 upstream. + +Similar to commit 0f7d9b31ce7a ("netfilter: nf_tables: fix use-after-free +in nft_set_catchall_destroy()"). We can not access k after kfree_rcu() +call. + +Cc: stable@vger.kernel.org +Signed-off-by: Min Li +Signed-off-by: Luiz Augusto von Dentz +Signed-off-by: Greg Kroah-Hartman +--- + net/bluetooth/hci_core.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +--- a/net/bluetooth/hci_core.c ++++ b/net/bluetooth/hci_core.c +@@ -2572,10 +2572,10 @@ int hci_remove_link_key(struct hci_dev * + + int hci_remove_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 bdaddr_type) + { +- struct smp_ltk *k; ++ struct smp_ltk *k, *tmp; + int removed = 0; + +- list_for_each_entry_rcu(k, &hdev->long_term_keys, list) { ++ list_for_each_entry_safe(k, tmp, &hdev->long_term_keys, list) { + if (bacmp(bdaddr, &k->bdaddr) || k->bdaddr_type != bdaddr_type) + continue; + +@@ -2591,9 +2591,9 @@ int hci_remove_ltk(struct hci_dev *hdev, + + void hci_remove_irk(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 addr_type) + { +- struct smp_irk *k; ++ struct smp_irk *k, *tmp; + +- list_for_each_entry_rcu(k, &hdev->identity_resolving_keys, list) { ++ list_for_each_entry_safe(k, tmp, &hdev->identity_resolving_keys, list) { + if (bacmp(bdaddr, &k->bdaddr) || k->addr_type != addr_type) + continue; + diff --git a/queue-5.4/can-j1939-avoid-possible-use-after-free-when-j1939_can_rx_register-fails.patch b/queue-5.4/can-j1939-avoid-possible-use-after-free-when-j1939_can_rx_register-fails.patch new file mode 100644 index 00000000000..76288f9001d --- /dev/null +++ b/queue-5.4/can-j1939-avoid-possible-use-after-free-when-j1939_can_rx_register-fails.patch @@ -0,0 +1,144 @@ +From 9f16eb106aa5fce15904625661312623ec783ed3 Mon Sep 17 00:00:00 2001 +From: Fedor Pchelkin +Date: Fri, 26 May 2023 20:19:10 +0300 +Subject: can: j1939: avoid possible use-after-free when j1939_can_rx_register fails + +From: Fedor Pchelkin + +commit 9f16eb106aa5fce15904625661312623ec783ed3 upstream. + +Syzkaller reports the following failure: + +BUG: KASAN: use-after-free in kref_put include/linux/kref.h:64 [inline] +BUG: KASAN: use-after-free in j1939_priv_put+0x25/0xa0 net/can/j1939/main.c:172 +Write of size 4 at addr ffff888141c15058 by task swapper/3/0 + +CPU: 3 PID: 0 Comm: swapper/3 Not tainted 5.10.144-syzkaller #0 +Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.12.0-1 04/01/2014 +Call Trace: + + __dump_stack lib/dump_stack.c:77 [inline] + dump_stack+0x107/0x167 lib/dump_stack.c:118 + print_address_description.constprop.0+0x1c/0x220 mm/kasan/report.c:385 + __kasan_report mm/kasan/report.c:545 [inline] + kasan_report.cold+0x1f/0x37 mm/kasan/report.c:562 + check_memory_region_inline mm/kasan/generic.c:186 [inline] + check_memory_region+0x145/0x190 mm/kasan/generic.c:192 + instrument_atomic_read_write include/linux/instrumented.h:101 [inline] + atomic_fetch_sub_release include/asm-generic/atomic-instrumented.h:220 [inline] + __refcount_sub_and_test include/linux/refcount.h:272 [inline] + __refcount_dec_and_test include/linux/refcount.h:315 [inline] + refcount_dec_and_test include/linux/refcount.h:333 [inline] + kref_put include/linux/kref.h:64 [inline] + j1939_priv_put+0x25/0xa0 net/can/j1939/main.c:172 + j1939_sk_sock_destruct+0x44/0x90 net/can/j1939/socket.c:374 + __sk_destruct+0x4e/0x820 net/core/sock.c:1784 + rcu_do_batch kernel/rcu/tree.c:2485 [inline] + rcu_core+0xb35/0x1a30 kernel/rcu/tree.c:2726 + __do_softirq+0x289/0x9a3 kernel/softirq.c:298 + asm_call_irq_on_stack+0x12/0x20 + + __run_on_irqstack arch/x86/include/asm/irq_stack.h:26 [inline] + run_on_irqstack_cond arch/x86/include/asm/irq_stack.h:77 [inline] + do_softirq_own_stack+0xaa/0xe0 arch/x86/kernel/irq_64.c:77 + invoke_softirq kernel/softirq.c:393 [inline] + __irq_exit_rcu kernel/softirq.c:423 [inline] + irq_exit_rcu+0x136/0x200 kernel/softirq.c:435 + sysvec_apic_timer_interrupt+0x4d/0x100 arch/x86/kernel/apic/apic.c:1095 + asm_sysvec_apic_timer_interrupt+0x12/0x20 arch/x86/include/asm/idtentry.h:635 + +Allocated by task 1141: + kasan_save_stack+0x1b/0x40 mm/kasan/common.c:48 + kasan_set_track mm/kasan/common.c:56 [inline] + __kasan_kmalloc.constprop.0+0xc9/0xd0 mm/kasan/common.c:461 + kmalloc include/linux/slab.h:552 [inline] + kzalloc include/linux/slab.h:664 [inline] + j1939_priv_create net/can/j1939/main.c:131 [inline] + j1939_netdev_start+0x111/0x860 net/can/j1939/main.c:268 + j1939_sk_bind+0x8ea/0xd30 net/can/j1939/socket.c:485 + __sys_bind+0x1f2/0x260 net/socket.c:1645 + __do_sys_bind net/socket.c:1656 [inline] + __se_sys_bind net/socket.c:1654 [inline] + __x64_sys_bind+0x6f/0xb0 net/socket.c:1654 + do_syscall_64+0x33/0x40 arch/x86/entry/common.c:46 + entry_SYSCALL_64_after_hwframe+0x61/0xc6 + +Freed by task 1141: + kasan_save_stack+0x1b/0x40 mm/kasan/common.c:48 + kasan_set_track+0x1c/0x30 mm/kasan/common.c:56 + kasan_set_free_info+0x1b/0x30 mm/kasan/generic.c:355 + __kasan_slab_free+0x112/0x170 mm/kasan/common.c:422 + slab_free_hook mm/slub.c:1542 [inline] + slab_free_freelist_hook+0xad/0x190 mm/slub.c:1576 + slab_free mm/slub.c:3149 [inline] + kfree+0xd9/0x3b0 mm/slub.c:4125 + j1939_netdev_start+0x5ee/0x860 net/can/j1939/main.c:300 + j1939_sk_bind+0x8ea/0xd30 net/can/j1939/socket.c:485 + __sys_bind+0x1f2/0x260 net/socket.c:1645 + __do_sys_bind net/socket.c:1656 [inline] + __se_sys_bind net/socket.c:1654 [inline] + __x64_sys_bind+0x6f/0xb0 net/socket.c:1654 + do_syscall_64+0x33/0x40 arch/x86/entry/common.c:46 + entry_SYSCALL_64_after_hwframe+0x61/0xc6 + +It can be caused by this scenario: + +CPU0 CPU1 +j1939_sk_bind(socket0, ndev0, ...) + j1939_netdev_start() + j1939_sk_bind(socket1, ndev0, ...) + j1939_netdev_start() + mutex_lock(&j1939_netdev_lock) + j1939_priv_set(ndev0, priv) + mutex_unlock(&j1939_netdev_lock) + if (priv_new) + kref_get(&priv_new->rx_kref) + return priv_new; + /* inside j1939_sk_bind() */ + jsk->priv = priv + j1939_can_rx_register(priv) // fails + j1939_priv_set(ndev, NULL) + kfree(priv) + j1939_sk_sock_destruct() + j1939_priv_put() // <- uaf + +To avoid this, call j1939_can_rx_register() under j1939_netdev_lock so +that a concurrent thread cannot process j1939_priv before +j1939_can_rx_register() returns. + +Found by Linux Verification Center (linuxtesting.org) with Syzkaller. + +Fixes: 9d71dd0c7009 ("can: add support of SAE J1939 protocol") +Signed-off-by: Fedor Pchelkin +Tested-by: Oleksij Rempel +Acked-by: Oleksij Rempel +Link: https://lore.kernel.org/r/20230526171910.227615-3-pchelkin@ispras.ru +Cc: stable@vger.kernel.org +Signed-off-by: Marc Kleine-Budde +Signed-off-by: Greg Kroah-Hartman +--- + net/can/j1939/main.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +--- a/net/can/j1939/main.c ++++ b/net/can/j1939/main.c +@@ -286,16 +286,18 @@ struct j1939_priv *j1939_netdev_start(st + return priv_new; + } + j1939_priv_set(ndev, priv); +- mutex_unlock(&j1939_netdev_lock); + + ret = j1939_can_rx_register(priv); + if (ret < 0) + goto out_priv_put; + ++ mutex_unlock(&j1939_netdev_lock); + return priv; + + out_priv_put: + j1939_priv_set(ndev, NULL); ++ mutex_unlock(&j1939_netdev_lock); ++ + dev_put(ndev); + kfree(priv); + diff --git a/queue-5.4/can-j1939-change-j1939_netdev_lock-type-to-mutex.patch b/queue-5.4/can-j1939-change-j1939_netdev_lock-type-to-mutex.patch new file mode 100644 index 00000000000..a33e8fa9832 --- /dev/null +++ b/queue-5.4/can-j1939-change-j1939_netdev_lock-type-to-mutex.patch @@ -0,0 +1,119 @@ +From cd9c790de2088b0d797dc4d244b4f174f9962554 Mon Sep 17 00:00:00 2001 +From: Fedor Pchelkin +Date: Fri, 26 May 2023 20:19:09 +0300 +Subject: can: j1939: change j1939_netdev_lock type to mutex + +From: Fedor Pchelkin + +commit cd9c790de2088b0d797dc4d244b4f174f9962554 upstream. + +It turns out access to j1939_can_rx_register() needs to be serialized, +otherwise j1939_priv can be corrupted when parallel threads call +j1939_netdev_start() and j1939_can_rx_register() fails. This issue is +thoroughly covered in other commit which serializes access to +j1939_can_rx_register(). + +Change j1939_netdev_lock type to mutex so that we do not need to remove +GFP_KERNEL from can_rx_register(). + +j1939_netdev_lock seems to be used in normal contexts where mutex usage +is not prohibited. + +Found by Linux Verification Center (linuxtesting.org) with Syzkaller. + +Fixes: 9d71dd0c7009 ("can: add support of SAE J1939 protocol") +Suggested-by: Alexey Khoroshilov +Signed-off-by: Fedor Pchelkin +Tested-by: Oleksij Rempel +Acked-by: Oleksij Rempel +Link: https://lore.kernel.org/r/20230526171910.227615-2-pchelkin@ispras.ru +Cc: stable@vger.kernel.org +Signed-off-by: Marc Kleine-Budde +Signed-off-by: Greg Kroah-Hartman +--- + net/can/j1939/main.c | 22 +++++++++++----------- + 1 file changed, 11 insertions(+), 11 deletions(-) + +--- a/net/can/j1939/main.c ++++ b/net/can/j1939/main.c +@@ -122,7 +122,7 @@ static void j1939_can_recv(struct sk_buf + #define J1939_CAN_ID CAN_EFF_FLAG + #define J1939_CAN_MASK (CAN_EFF_FLAG | CAN_RTR_FLAG) + +-static DEFINE_SPINLOCK(j1939_netdev_lock); ++static DEFINE_MUTEX(j1939_netdev_lock); + + static struct j1939_priv *j1939_priv_create(struct net_device *ndev) + { +@@ -216,7 +216,7 @@ static void __j1939_rx_release(struct kr + j1939_can_rx_unregister(priv); + j1939_ecu_unmap_all(priv); + j1939_priv_set(priv->ndev, NULL); +- spin_unlock(&j1939_netdev_lock); ++ mutex_unlock(&j1939_netdev_lock); + } + + /* get pointer to priv without increasing ref counter */ +@@ -244,9 +244,9 @@ static struct j1939_priv *j1939_priv_get + { + struct j1939_priv *priv; + +- spin_lock(&j1939_netdev_lock); ++ mutex_lock(&j1939_netdev_lock); + priv = j1939_priv_get_by_ndev_locked(ndev); +- spin_unlock(&j1939_netdev_lock); ++ mutex_unlock(&j1939_netdev_lock); + + return priv; + } +@@ -256,14 +256,14 @@ struct j1939_priv *j1939_netdev_start(st + struct j1939_priv *priv, *priv_new; + int ret; + +- spin_lock(&j1939_netdev_lock); ++ mutex_lock(&j1939_netdev_lock); + priv = j1939_priv_get_by_ndev_locked(ndev); + if (priv) { + kref_get(&priv->rx_kref); +- spin_unlock(&j1939_netdev_lock); ++ mutex_unlock(&j1939_netdev_lock); + return priv; + } +- spin_unlock(&j1939_netdev_lock); ++ mutex_unlock(&j1939_netdev_lock); + + priv = j1939_priv_create(ndev); + if (!priv) +@@ -273,20 +273,20 @@ struct j1939_priv *j1939_netdev_start(st + spin_lock_init(&priv->j1939_socks_lock); + INIT_LIST_HEAD(&priv->j1939_socks); + +- spin_lock(&j1939_netdev_lock); ++ mutex_lock(&j1939_netdev_lock); + priv_new = j1939_priv_get_by_ndev_locked(ndev); + if (priv_new) { + /* Someone was faster than us, use their priv and roll + * back our's. + */ + kref_get(&priv_new->rx_kref); +- spin_unlock(&j1939_netdev_lock); ++ mutex_unlock(&j1939_netdev_lock); + dev_put(ndev); + kfree(priv); + return priv_new; + } + j1939_priv_set(ndev, priv); +- spin_unlock(&j1939_netdev_lock); ++ mutex_unlock(&j1939_netdev_lock); + + ret = j1939_can_rx_register(priv); + if (ret < 0) +@@ -304,7 +304,7 @@ struct j1939_priv *j1939_netdev_start(st + + void j1939_netdev_stop(struct j1939_priv *priv) + { +- kref_put_lock(&priv->rx_kref, __j1939_rx_release, &j1939_netdev_lock); ++ kref_put_mutex(&priv->rx_kref, __j1939_rx_release, &j1939_netdev_lock); + j1939_priv_put(priv); + } + diff --git a/queue-5.4/can-j1939-j1939_sk_send_loop_abort-improved-error-queue-handling-in-j1939-socket.patch b/queue-5.4/can-j1939-j1939_sk_send_loop_abort-improved-error-queue-handling-in-j1939-socket.patch new file mode 100644 index 00000000000..e71b9d7bc3e --- /dev/null +++ b/queue-5.4/can-j1939-j1939_sk_send_loop_abort-improved-error-queue-handling-in-j1939-socket.patch @@ -0,0 +1,63 @@ +From 2a84aea80e925ecba6349090559754f8e8eb68ef Mon Sep 17 00:00:00 2001 +From: Oleksij Rempel +Date: Fri, 26 May 2023 10:19:46 +0200 +Subject: can: j1939: j1939_sk_send_loop_abort(): improved error queue handling in J1939 Socket + +From: Oleksij Rempel + +commit 2a84aea80e925ecba6349090559754f8e8eb68ef upstream. + +This patch addresses an issue within the j1939_sk_send_loop_abort() +function in the j1939/socket.c file, specifically in the context of +Transport Protocol (TP) sessions. + +Without this patch, when a TP session is initiated and a Clear To Send +(CTS) frame is received from the remote side requesting one data packet, +the kernel dispatches the first Data Transport (DT) frame and then waits +for the next CTS. If the remote side doesn't respond with another CTS, +the kernel aborts due to a timeout. This leads to the user-space +receiving an EPOLLERR on the socket, and the socket becomes active. + +However, when trying to read the error queue from the socket with +sock.recvmsg(, , socket.MSG_ERRQUEUE), it returns -EAGAIN, +given that the socket is non-blocking. This situation results in an +infinite loop: the user-space repeatedly calls epoll(), epoll() returns +the socket file descriptor with EPOLLERR, but the socket then blocks on +the recv() of ERRQUEUE. + +This patch introduces an additional check for the J1939_SOCK_ERRQUEUE +flag within the j1939_sk_send_loop_abort() function. If the flag is set, +it indicates that the application has subscribed to receive error queue +messages. In such cases, the kernel can communicate the current transfer +state via the error queue. This allows for the function to return early, +preventing the unnecessary setting of the socket into an error state, +and breaking the infinite loop. It is crucial to note that a socket +error is only needed if the application isn't using the error queue, as, +without it, the application wouldn't be aware of transfer issues. + +Fixes: 9d71dd0c7009 ("can: add support of SAE J1939 protocol") +Reported-by: David Jander +Tested-by: David Jander +Signed-off-by: Oleksij Rempel +Link: https://lore.kernel.org/r/20230526081946.715190-1-o.rempel@pengutronix.de +Cc: stable@vger.kernel.org +Signed-off-by: Marc Kleine-Budde +Signed-off-by: Greg Kroah-Hartman +--- + net/can/j1939/socket.c | 5 +++++ + 1 file changed, 5 insertions(+) + +--- a/net/can/j1939/socket.c ++++ b/net/can/j1939/socket.c +@@ -1013,6 +1013,11 @@ void j1939_sk_errqueue(struct j1939_sess + + void j1939_sk_send_loop_abort(struct sock *sk, int err) + { ++ struct j1939_sock *jsk = j1939_sk(sk); ++ ++ if (jsk->state & J1939_SOCK_ERRQUEUE) ++ return; ++ + sk->sk_err = err; + + sk->sk_error_report(sk); diff --git a/queue-5.4/ceph-fix-use-after-free-bug-for-inodes-when-flushing-capsnaps.patch b/queue-5.4/ceph-fix-use-after-free-bug-for-inodes-when-flushing-capsnaps.patch new file mode 100644 index 00000000000..09913e96293 --- /dev/null +++ b/queue-5.4/ceph-fix-use-after-free-bug-for-inodes-when-flushing-capsnaps.patch @@ -0,0 +1,90 @@ +From 409e873ea3c1fd3079909718bbeb06ac1ec7f38b Mon Sep 17 00:00:00 2001 +From: Xiubo Li +Date: Thu, 1 Jun 2023 08:59:31 +0800 +Subject: ceph: fix use-after-free bug for inodes when flushing capsnaps + +From: Xiubo Li + +commit 409e873ea3c1fd3079909718bbeb06ac1ec7f38b upstream. + +There is a race between capsnaps flush and removing the inode from +'mdsc->snap_flush_list' list: + + == Thread A == == Thread B == +ceph_queue_cap_snap() + -> allocate 'capsnapA' + ->ihold('&ci->vfs_inode') + ->add 'capsnapA' to 'ci->i_cap_snaps' + ->add 'ci' to 'mdsc->snap_flush_list' + ... + == Thread C == +ceph_flush_snaps() + ->__ceph_flush_snaps() + ->__send_flush_snap() + handle_cap_flushsnap_ack() + ->iput('&ci->vfs_inode') + this also will release 'ci' + ... + == Thread D == + ceph_handle_snap() + ->flush_snaps() + ->iterate 'mdsc->snap_flush_list' + ->get the stale 'ci' + ->remove 'ci' from ->ihold(&ci->vfs_inode) this + 'mdsc->snap_flush_list' will WARNING + +To fix this we will increase the inode's i_count ref when adding 'ci' +to the 'mdsc->snap_flush_list' list. + +[ idryomov: need_put int -> bool ] + +Cc: stable@vger.kernel.org +Link: https://bugzilla.redhat.com/show_bug.cgi?id=2209299 +Signed-off-by: Xiubo Li +Reviewed-by: Milind Changire +Reviewed-by: Ilya Dryomov +Signed-off-by: Ilya Dryomov +Signed-off-by: Greg Kroah-Hartman +--- + fs/ceph/caps.c | 6 ++++++ + fs/ceph/snap.c | 4 +++- + 2 files changed, 9 insertions(+), 1 deletion(-) + +--- a/fs/ceph/caps.c ++++ b/fs/ceph/caps.c +@@ -1558,6 +1558,7 @@ void ceph_flush_snaps(struct ceph_inode_ + struct inode *inode = &ci->vfs_inode; + struct ceph_mds_client *mdsc = ceph_inode_to_client(inode)->mdsc; + struct ceph_mds_session *session = NULL; ++ bool need_put = false; + int mds; + + dout("ceph_flush_snaps %p\n", inode); +@@ -1609,8 +1610,13 @@ out: + } + /* we flushed them all; remove this inode from the queue */ + spin_lock(&mdsc->snap_flush_lock); ++ if (!list_empty(&ci->i_snap_flush_item)) ++ need_put = true; + list_del_init(&ci->i_snap_flush_item); + spin_unlock(&mdsc->snap_flush_lock); ++ ++ if (need_put) ++ iput(inode); + } + + /* +--- a/fs/ceph/snap.c ++++ b/fs/ceph/snap.c +@@ -644,8 +644,10 @@ int __ceph_finish_cap_snap(struct ceph_i + capsnap->size); + + spin_lock(&mdsc->snap_flush_lock); +- if (list_empty(&ci->i_snap_flush_item)) ++ if (list_empty(&ci->i_snap_flush_item)) { ++ ihold(inode); + list_add_tail(&ci->i_snap_flush_item, &mdsc->snap_flush_list); ++ } + spin_unlock(&mdsc->snap_flush_lock); + return 1; /* caller may want to ceph_flush_snaps */ + } diff --git a/queue-5.4/pinctrl-meson-axg-add-missing-gpioa_18-gpio-group.patch b/queue-5.4/pinctrl-meson-axg-add-missing-gpioa_18-gpio-group.patch new file mode 100644 index 00000000000..562ad5c334e --- /dev/null +++ b/queue-5.4/pinctrl-meson-axg-add-missing-gpioa_18-gpio-group.patch @@ -0,0 +1,36 @@ +From 5b10ff013e8a57f8845615ac2cc37edf7f6eef05 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Martin=20Hundeb=C3=B8ll?= +Date: Fri, 12 May 2023 08:49:25 +0200 +Subject: pinctrl: meson-axg: add missing GPIOA_18 gpio group +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Martin Hundebøll + +commit 5b10ff013e8a57f8845615ac2cc37edf7f6eef05 upstream. + +Without this, the gpio cannot be explicitly mux'ed to its gpio function. + +Fixes: 83c566806a68a ("pinctrl: meson-axg: Add new pinctrl driver for Meson AXG SoC") +Cc: stable@vger.kernel.org +Signed-off-by: Martin Hundebøll +Reviewed-by: Neil Armstrong +Reviewed-by: Dmitry Rokosov +Link: https://lore.kernel.org/r/20230512064925.133516-1-martin@geanix.com +Signed-off-by: Linus Walleij +Signed-off-by: Greg Kroah-Hartman +--- + drivers/pinctrl/meson/pinctrl-meson-axg.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/pinctrl/meson/pinctrl-meson-axg.c ++++ b/drivers/pinctrl/meson/pinctrl-meson-axg.c +@@ -400,6 +400,7 @@ static struct meson_pmx_group meson_axg_ + GPIO_GROUP(GPIOA_15), + GPIO_GROUP(GPIOA_16), + GPIO_GROUP(GPIOA_17), ++ GPIO_GROUP(GPIOA_18), + GPIO_GROUP(GPIOA_19), + GPIO_GROUP(GPIOA_20), + diff --git a/queue-5.4/rbd-move-rbd_obj_flag_copyup_enabled-flag-setting.patch b/queue-5.4/rbd-move-rbd_obj_flag_copyup_enabled-flag-setting.patch new file mode 100644 index 00000000000..375accebb92 --- /dev/null +++ b/queue-5.4/rbd-move-rbd_obj_flag_copyup_enabled-flag-setting.patch @@ -0,0 +1,85 @@ +From 09fe05c57b5aaf23e2c35036c98ea9f282b19a77 Mon Sep 17 00:00:00 2001 +From: Ilya Dryomov +Date: Mon, 5 Jun 2023 16:33:35 +0200 +Subject: rbd: move RBD_OBJ_FLAG_COPYUP_ENABLED flag setting + +From: Ilya Dryomov + +commit 09fe05c57b5aaf23e2c35036c98ea9f282b19a77 upstream. + +Move RBD_OBJ_FLAG_COPYUP_ENABLED flag setting into the object request +state machine to allow for the snapshot context to be captured in the +image request state machine rather than in rbd_queue_workfn(). + +Cc: stable@vger.kernel.org +Signed-off-by: Ilya Dryomov +Reviewed-by: Dongsheng Yang +Signed-off-by: Greg Kroah-Hartman +--- + drivers/block/rbd.c | 32 +++++++++++++++++++++----------- + 1 file changed, 21 insertions(+), 11 deletions(-) + +--- a/drivers/block/rbd.c ++++ b/drivers/block/rbd.c +@@ -1493,14 +1493,28 @@ static bool rbd_obj_is_tail(struct rbd_o + /* + * Must be called after rbd_obj_calc_img_extents(). + */ +-static bool rbd_obj_copyup_enabled(struct rbd_obj_request *obj_req) ++static void rbd_obj_set_copyup_enabled(struct rbd_obj_request *obj_req) + { +- if (!obj_req->num_img_extents || +- (rbd_obj_is_entire(obj_req) && +- !obj_req->img_request->snapc->num_snaps)) +- return false; ++ if (obj_req->img_request->op_type == OBJ_OP_DISCARD) { ++ dout("%s %p objno %llu discard\n", __func__, obj_req, ++ obj_req->ex.oe_objno); ++ return; ++ } + +- return true; ++ if (!obj_req->num_img_extents) { ++ dout("%s %p objno %llu not overlapping\n", __func__, obj_req, ++ obj_req->ex.oe_objno); ++ return; ++ } ++ ++ if (rbd_obj_is_entire(obj_req) && ++ !obj_req->img_request->snapc->num_snaps) { ++ dout("%s %p objno %llu entire\n", __func__, obj_req, ++ obj_req->ex.oe_objno); ++ return; ++ } ++ ++ obj_req->flags |= RBD_OBJ_FLAG_COPYUP_ENABLED; + } + + static u64 rbd_obj_img_extents_bytes(struct rbd_obj_request *obj_req) +@@ -2389,9 +2403,6 @@ static int rbd_obj_init_write(struct rbd + if (ret) + return ret; + +- if (rbd_obj_copyup_enabled(obj_req)) +- obj_req->flags |= RBD_OBJ_FLAG_COPYUP_ENABLED; +- + obj_req->write_state = RBD_OBJ_WRITE_START; + return 0; + } +@@ -2497,8 +2508,6 @@ static int rbd_obj_init_zeroout(struct r + if (ret) + return ret; + +- if (rbd_obj_copyup_enabled(obj_req)) +- obj_req->flags |= RBD_OBJ_FLAG_COPYUP_ENABLED; + if (!obj_req->num_img_extents) { + obj_req->flags |= RBD_OBJ_FLAG_NOOP_FOR_NONEXISTENT; + if (rbd_obj_is_entire(obj_req)) +@@ -3439,6 +3448,7 @@ again: + case RBD_OBJ_WRITE_START: + rbd_assert(!*result); + ++ rbd_obj_set_copyup_enabled(obj_req); + if (rbd_obj_write_is_noop(obj_req)) + return true; + diff --git a/queue-5.4/series b/queue-5.4/series index d8300e43b6a..6f4f7c79e0f 100644 --- a/queue-5.4/series +++ b/queue-5.4/series @@ -22,3 +22,12 @@ input-psmouse-fix-oob-access-in-elantech-protocol.patch alsa-hda-realtek-add-a-quirk-for-hp-slim-desktop-s01.patch alsa-hda-realtek-add-lenovo-p3-tower-platform.patch drm-amdgpu-fix-xclk-freq-on-chip_stoney.patch +can-j1939-j1939_sk_send_loop_abort-improved-error-queue-handling-in-j1939-socket.patch +can-j1939-change-j1939_netdev_lock-type-to-mutex.patch +can-j1939-avoid-possible-use-after-free-when-j1939_can_rx_register-fails.patch +ceph-fix-use-after-free-bug-for-inodes-when-flushing-capsnaps.patch +bluetooth-fix-use-after-free-in-hci_remove_ltk-hci_remove_irk.patch +rbd-move-rbd_obj_flag_copyup_enabled-flag-setting.patch +pinctrl-meson-axg-add-missing-gpioa_18-gpio-group.patch +usb-usbfs-enforce-page-requirements-for-mmap.patch +usb-usbfs-use-consistent-mmap-functions.patch diff --git a/queue-5.4/usb-usbfs-enforce-page-requirements-for-mmap.patch b/queue-5.4/usb-usbfs-enforce-page-requirements-for-mmap.patch new file mode 100644 index 00000000000..f7d72d014b7 --- /dev/null +++ b/queue-5.4/usb-usbfs-enforce-page-requirements-for-mmap.patch @@ -0,0 +1,140 @@ +From 0143d148d1e882fb1538dc9974c94d63961719b9 Mon Sep 17 00:00:00 2001 +From: Ruihan Li +Date: Mon, 15 May 2023 21:09:55 +0800 +Subject: usb: usbfs: Enforce page requirements for mmap + +From: Ruihan Li + +commit 0143d148d1e882fb1538dc9974c94d63961719b9 upstream. + +The current implementation of usbdev_mmap uses usb_alloc_coherent to +allocate memory pages that will later be mapped into the user space. +Meanwhile, usb_alloc_coherent employs three different methods to +allocate memory, as outlined below: + * If hcd->localmem_pool is non-null, it uses gen_pool_dma_alloc to + allocate memory; + * If DMA is not available, it uses kmalloc to allocate memory; + * Otherwise, it uses dma_alloc_coherent. + +However, it should be noted that gen_pool_dma_alloc does not guarantee +that the resulting memory will be page-aligned. Furthermore, trying to +map slab pages (i.e., memory allocated by kmalloc) into the user space +is not resonable and can lead to problems, such as a type confusion bug +when PAGE_TABLE_CHECK=y [1]. + +To address these issues, this patch introduces hcd_alloc_coherent_pages, +which addresses the above two problems. Specifically, +hcd_alloc_coherent_pages uses gen_pool_dma_alloc_align instead of +gen_pool_dma_alloc to ensure that the memory is page-aligned. To replace +kmalloc, hcd_alloc_coherent_pages directly allocates pages by calling +__get_free_pages. + +Reported-by: syzbot+fcf1a817ceb50935ce99@syzkaller.appspotmail.comm +Closes: https://lore.kernel.org/lkml/000000000000258e5e05fae79fc1@google.com/ [1] +Fixes: f7d34b445abc ("USB: Add support for usbfs zerocopy.") +Fixes: ff2437befd8f ("usb: host: Fix excessive alignment restriction for local memory allocations") +Cc: stable@vger.kernel.org +Signed-off-by: Ruihan Li +Acked-by: Alan Stern +Link: https://lore.kernel.org/r/20230515130958.32471-2-lrh2000@pku.edu.cn +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/core/buffer.c | 41 +++++++++++++++++++++++++++++++++++++++++ + drivers/usb/core/devio.c | 9 +++++---- + include/linux/usb/hcd.h | 5 +++++ + 3 files changed, 51 insertions(+), 4 deletions(-) + +--- a/drivers/usb/core/buffer.c ++++ b/drivers/usb/core/buffer.c +@@ -170,3 +170,44 @@ void hcd_buffer_free( + } + dma_free_coherent(hcd->self.sysdev, size, addr, dma); + } ++ ++void *hcd_buffer_alloc_pages(struct usb_hcd *hcd, ++ size_t size, gfp_t mem_flags, dma_addr_t *dma) ++{ ++ if (size == 0) ++ return NULL; ++ ++ if (hcd->localmem_pool) ++ return gen_pool_dma_alloc_align(hcd->localmem_pool, ++ size, dma, PAGE_SIZE); ++ ++ /* some USB hosts just use PIO */ ++ if (!hcd_uses_dma(hcd)) { ++ *dma = DMA_MAPPING_ERROR; ++ return (void *)__get_free_pages(mem_flags, ++ get_order(size)); ++ } ++ ++ return dma_alloc_coherent(hcd->self.sysdev, ++ size, dma, mem_flags); ++} ++ ++void hcd_buffer_free_pages(struct usb_hcd *hcd, ++ size_t size, void *addr, dma_addr_t dma) ++{ ++ if (!addr) ++ return; ++ ++ if (hcd->localmem_pool) { ++ gen_pool_free(hcd->localmem_pool, ++ (unsigned long)addr, size); ++ return; ++ } ++ ++ if (!hcd_uses_dma(hcd)) { ++ free_pages((unsigned long)addr, get_order(size)); ++ return; ++ } ++ ++ dma_free_coherent(hcd->self.sysdev, size, addr, dma); ++} +--- a/drivers/usb/core/devio.c ++++ b/drivers/usb/core/devio.c +@@ -173,6 +173,7 @@ static int connected(struct usb_dev_stat + static void dec_usb_memory_use_count(struct usb_memory *usbm, int *count) + { + struct usb_dev_state *ps = usbm->ps; ++ struct usb_hcd *hcd = bus_to_hcd(ps->dev->bus); + unsigned long flags; + + spin_lock_irqsave(&ps->lock, flags); +@@ -181,8 +182,8 @@ static void dec_usb_memory_use_count(str + list_del(&usbm->memlist); + spin_unlock_irqrestore(&ps->lock, flags); + +- usb_free_coherent(ps->dev, usbm->size, usbm->mem, +- usbm->dma_handle); ++ hcd_buffer_free_pages(hcd, usbm->size, ++ usbm->mem, usbm->dma_handle); + usbfs_decrease_memory_usage( + usbm->size + sizeof(struct usb_memory)); + kfree(usbm); +@@ -234,8 +235,8 @@ static int usbdev_mmap(struct file *file + goto error_decrease_mem; + } + +- mem = usb_alloc_coherent(ps->dev, size, GFP_USER | __GFP_NOWARN, +- &dma_handle); ++ mem = hcd_buffer_alloc_pages(hcd, ++ size, GFP_USER | __GFP_NOWARN, &dma_handle); + if (!mem) { + ret = -ENOMEM; + goto error_free_usbm; +--- a/include/linux/usb/hcd.h ++++ b/include/linux/usb/hcd.h +@@ -503,6 +503,11 @@ void *hcd_buffer_alloc(struct usb_bus *b + void hcd_buffer_free(struct usb_bus *bus, size_t size, + void *addr, dma_addr_t dma); + ++void *hcd_buffer_alloc_pages(struct usb_hcd *hcd, ++ size_t size, gfp_t mem_flags, dma_addr_t *dma); ++void hcd_buffer_free_pages(struct usb_hcd *hcd, ++ size_t size, void *addr, dma_addr_t dma); ++ + /* generic bus glue, needed for host controllers that don't use PCI */ + extern irqreturn_t usb_hcd_irq(int irq, void *__hcd); + diff --git a/queue-5.4/usb-usbfs-use-consistent-mmap-functions.patch b/queue-5.4/usb-usbfs-use-consistent-mmap-functions.patch new file mode 100644 index 00000000000..ce0fd32586f --- /dev/null +++ b/queue-5.4/usb-usbfs-use-consistent-mmap-functions.patch @@ -0,0 +1,60 @@ +From d0b861653f8c16839c3035875b556afc4472f941 Mon Sep 17 00:00:00 2001 +From: Ruihan Li +Date: Mon, 15 May 2023 21:09:56 +0800 +Subject: usb: usbfs: Use consistent mmap functions + +From: Ruihan Li + +commit d0b861653f8c16839c3035875b556afc4472f941 upstream. + +When hcd->localmem_pool is non-null, localmem_pool is used to allocate +DMA memory. In this case, the dma address will be properly returned (in +dma_handle), and dma_mmap_coherent should be used to map this memory +into the user space. However, the current implementation uses +pfn_remap_range, which is supposed to map normal pages. + +Instead of repeating the logic in the memory allocation function, this +patch introduces a more robust solution. Here, the type of allocated +memory is checked by testing whether dma_handle is properly set. If +dma_handle is properly returned, it means some DMA pages are allocated +and dma_mmap_coherent should be used to map them. Otherwise, normal +pages are allocated and pfn_remap_range should be called. This ensures +that the correct mmap functions are used consistently, independently +with logic details that determine which type of memory gets allocated. + +Fixes: a0e710a7def4 ("USB: usbfs: fix mmap dma mismatch") +Cc: stable@vger.kernel.org +Signed-off-by: Ruihan Li +Link: https://lore.kernel.org/r/20230515130958.32471-3-lrh2000@pku.edu.cn +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/core/devio.c | 11 +++++++++-- + 1 file changed, 9 insertions(+), 2 deletions(-) + +--- a/drivers/usb/core/devio.c ++++ b/drivers/usb/core/devio.c +@@ -222,7 +222,7 @@ static int usbdev_mmap(struct file *file + size_t size = vma->vm_end - vma->vm_start; + void *mem; + unsigned long flags; +- dma_addr_t dma_handle; ++ dma_addr_t dma_handle = DMA_MAPPING_ERROR; + int ret; + + ret = usbfs_increase_memory_usage(size + sizeof(struct usb_memory)); +@@ -252,7 +252,14 @@ static int usbdev_mmap(struct file *file + usbm->vma_use_count = 1; + INIT_LIST_HEAD(&usbm->memlist); + +- if (hcd->localmem_pool || !hcd_uses_dma(hcd)) { ++ /* ++ * In DMA-unavailable cases, hcd_buffer_alloc_pages allocates ++ * normal pages and assigns DMA_MAPPING_ERROR to dma_handle. Check ++ * whether we are in such cases, and then use remap_pfn_range (or ++ * dma_mmap_coherent) to map normal (or DMA) pages into the user ++ * space, respectively. ++ */ ++ if (dma_handle == DMA_MAPPING_ERROR) { + if (remap_pfn_range(vma, vma->vm_start, + virt_to_phys(usbm->mem) >> PAGE_SHIFT, + size, vma->vm_page_prot) < 0) {