From: Greg Kroah-Hartman Date: Tue, 4 Feb 2025 17:57:24 +0000 (+0100) Subject: 6.12-stable patches X-Git-Tag: v6.6.76~26 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=5d8bd0fd19baef31af8d9a406bca00ea7ff32cc3;p=thirdparty%2Fkernel%2Fstable-queue.git 6.12-stable patches added patches: btrfs-output-the-reason-for-open_ctree-failure.patch hid-core-fix-assumption-that-resolution-multipliers-must-be-in-logical-collections.patch md-md-bitmap-synchronize-bitmap_get_stats-with-bitmap-lifetime.patch media-imx-jpeg-fix-potential-error-pointer-dereference-in-detach_pm.patch media-uvcvideo-fix-double-free-in-error-path.patch mptcp-blackhole-only-if-1st-syn-retrans-w-o-mpc-is-accepted.patch mptcp-consolidate-suboption-status.patch mptcp-handle-fastopen-disconnect-correctly.patch mptcp-pm-only-set-fullmesh-for-subflow-endp.patch powerpc-pseries-iommu-don-t-unset-window-if-it-was-never-set.patch pps-fix-a-use-after-free.patch rdma-mlx5-fix-implicit-odp-use-after-free.patch remoteproc-core-fix-ida_free-call-while-not-allocated.patch staging-media-max96712-fix-kernel-oops-when-removing-module.patch usb-gadget-f_tcm-don-t-free-command-immediately.patch --- diff --git a/queue-6.12/btrfs-output-the-reason-for-open_ctree-failure.patch b/queue-6.12/btrfs-output-the-reason-for-open_ctree-failure.patch new file mode 100644 index 0000000000..7b668d437d --- /dev/null +++ b/queue-6.12/btrfs-output-the-reason-for-open_ctree-failure.patch @@ -0,0 +1,46 @@ +From d0f038104fa37380e2a725e669508e43d0c503e9 Mon Sep 17 00:00:00 2001 +From: Qu Wenruo +Date: Tue, 10 Dec 2024 15:23:06 +1030 +Subject: btrfs: output the reason for open_ctree() failure + +From: Qu Wenruo + +commit d0f038104fa37380e2a725e669508e43d0c503e9 upstream. + +There is a recent ML report that mounting a large fs backed by hardware +RAID56 controller (with one device missing) took too much time, and +systemd seems to kill the mount attempt. + +In that case, the only error message is: + + BTRFS error (device sdj): open_ctree failed + +There is no reason on why the failure happened, making it very hard to +understand the reason. + +At least output the error number (in the particular case it should be +-EINTR) to provide some clue. + +Link: https://lore.kernel.org/linux-btrfs/9b9c4d2810abcca2f9f76e32220ed9a90febb235.camel@scientia.org/ +Reported-by: Christoph Anton Mitterer +Cc: stable@vger.kernel.org +Reviewed-by: Filipe Manana +Signed-off-by: Qu Wenruo +Reviewed-by: David Sterba +Signed-off-by: David Sterba +Signed-off-by: Greg Kroah-Hartman +--- + fs/btrfs/super.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/fs/btrfs/super.c ++++ b/fs/btrfs/super.c +@@ -972,7 +972,7 @@ static int btrfs_fill_super(struct super + + err = open_ctree(sb, fs_devices); + if (err) { +- btrfs_err(fs_info, "open_ctree failed"); ++ btrfs_err(fs_info, "open_ctree failed: %d", err); + return err; + } + diff --git a/queue-6.12/hid-core-fix-assumption-that-resolution-multipliers-must-be-in-logical-collections.patch b/queue-6.12/hid-core-fix-assumption-that-resolution-multipliers-must-be-in-logical-collections.patch new file mode 100644 index 0000000000..92d1af626f --- /dev/null +++ b/queue-6.12/hid-core-fix-assumption-that-resolution-multipliers-must-be-in-logical-collections.patch @@ -0,0 +1,60 @@ +From 64f2657b579343cf923aa933f08074e6258eb07b Mon Sep 17 00:00:00 2001 +From: Alan Stern +Date: Tue, 31 Dec 2024 14:23:12 -0500 +Subject: HID: core: Fix assumption that Resolution Multipliers must be in Logical Collections + +From: Alan Stern + +commit 64f2657b579343cf923aa933f08074e6258eb07b upstream. + +A report in 2019 by the syzbot fuzzer was found to be connected to two +errors in the HID core associated with Resolution Multipliers. One of +the errors was fixed by commit ea427a222d8b ("HID: core: Fix deadloop +in hid_apply_multiplier."), but the other has not been fixed. + +This error arises because hid_apply_multipler() assumes that every +Resolution Multiplier control is contained in a Logical Collection, +i.e., there's no way the routine can ever set multiplier_collection to +NULL. This is in spite of the fact that the function starts with a +big comment saying: + + * "The Resolution Multiplier control must be contained in the same + * Logical Collection as the control(s) to which it is to be applied. + ... + * If no Logical Collection is + * defined, the Resolution Multiplier is associated with all + * controls in the report." + * HID Usage Table, v1.12, Section 4.3.1, p30 + * + * Thus, search from the current collection upwards until we find a + * logical collection... + +The comment and the code overlook the possibility that none of the +collections found may be a Logical Collection. + +The fix is to set the multiplier_collection pointer to NULL if the +collection found isn't a Logical Collection. + +Reported-by: syzbot+ec5f884c4a135aa0dbb9@syzkaller.appspotmail.com +Closes: https://lore.kernel.org/all/000000000000109c040597dc5843@google.com/ +Signed-off-by: Alan Stern +Cc: Peter Hutterer +Fixes: 5a4abb36f312 ("HID: core: process the Resolution Multiplier") +Cc: stable@vger.kernel.org +Signed-off-by: Jiri Kosina +Signed-off-by: Greg Kroah-Hartman +--- + drivers/hid/hid-core.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/drivers/hid/hid-core.c ++++ b/drivers/hid/hid-core.c +@@ -1125,6 +1125,8 @@ static void hid_apply_multiplier(struct + while (multiplier_collection->parent_idx != -1 && + multiplier_collection->type != HID_COLLECTION_LOGICAL) + multiplier_collection = &hid->collection[multiplier_collection->parent_idx]; ++ if (multiplier_collection->type != HID_COLLECTION_LOGICAL) ++ multiplier_collection = NULL; + + effective_multiplier = hid_calculate_multiplier(hid, multiplier); + diff --git a/queue-6.12/md-md-bitmap-synchronize-bitmap_get_stats-with-bitmap-lifetime.patch b/queue-6.12/md-md-bitmap-synchronize-bitmap_get_stats-with-bitmap-lifetime.patch new file mode 100644 index 0000000000..c0fe92f8d2 --- /dev/null +++ b/queue-6.12/md-md-bitmap-synchronize-bitmap_get_stats-with-bitmap-lifetime.patch @@ -0,0 +1,81 @@ +From 8d28d0ddb986f56920ac97ae704cc3340a699a30 Mon Sep 17 00:00:00 2001 +From: Yu Kuai +Date: Fri, 24 Jan 2025 17:20:55 +0800 +Subject: md/md-bitmap: Synchronize bitmap_get_stats() with bitmap lifetime + +From: Yu Kuai + +commit 8d28d0ddb986f56920ac97ae704cc3340a699a30 upstream. + +After commit ec6bb299c7c3 ("md/md-bitmap: add 'sync_size' into struct +md_bitmap_stats"), following panic is reported: + +Oops: general protection fault, probably for non-canonical address +RIP: 0010:bitmap_get_stats+0x2b/0xa0 +Call Trace: + + md_seq_show+0x2d2/0x5b0 + seq_read_iter+0x2b9/0x470 + seq_read+0x12f/0x180 + proc_reg_read+0x57/0xb0 + vfs_read+0xf6/0x380 + ksys_read+0x6c/0xf0 + do_syscall_64+0x82/0x170 + entry_SYSCALL_64_after_hwframe+0x76/0x7e + +Root cause is that bitmap_get_stats() can be called at anytime if mddev +is still there, even if bitmap is destroyed, or not fully initialized. +Deferenceing bitmap in this case can crash the kernel. Meanwhile, the +above commit start to deferencing bitmap->storage, make the problem +easier to trigger. + +Fix the problem by protecting bitmap_get_stats() with bitmap_info.mutex. + +Cc: stable@vger.kernel.org # v6.12+ +Fixes: 32a7627cf3a3 ("[PATCH] md: optimised resync using Bitmap based intent logging") +Reported-and-tested-by: Harshit Mogalapalli +Closes: https://lore.kernel.org/linux-raid/ca3a91a2-50ae-4f68-b317-abd9889f3907@oracle.com/T/#m6e5086c95201135e4941fe38f9efa76daf9666c5 +Signed-off-by: Yu Kuai +Link: https://lore.kernel.org/r/20250124092055.4050195-1-yukuai1@huaweicloud.com +Signed-off-by: Song Liu +Signed-off-by: Greg Kroah-Hartman +--- + drivers/md/md-bitmap.c | 5 ++++- + drivers/md/md.c | 5 +++++ + 2 files changed, 9 insertions(+), 1 deletion(-) + +--- a/drivers/md/md-bitmap.c ++++ b/drivers/md/md-bitmap.c +@@ -2355,7 +2355,10 @@ static int bitmap_get_stats(void *data, + + if (!bitmap) + return -ENOENT; +- ++ if (bitmap->mddev->bitmap_info.external) ++ return -ENOENT; ++ if (!bitmap->storage.sb_page) /* no superblock */ ++ return -EINVAL; + sb = kmap_local_page(bitmap->storage.sb_page); + stats->sync_size = le64_to_cpu(sb->sync_size); + kunmap_local(sb); +--- a/drivers/md/md.c ++++ b/drivers/md/md.c +@@ -8376,6 +8376,10 @@ static int md_seq_show(struct seq_file * + return 0; + + spin_unlock(&all_mddevs_lock); ++ ++ /* prevent bitmap to be freed after checking */ ++ mutex_lock(&mddev->bitmap_info.mutex); ++ + spin_lock(&mddev->lock); + if (mddev->pers || mddev->raid_disks || !list_empty(&mddev->disks)) { + seq_printf(seq, "%s : ", mdname(mddev)); +@@ -8451,6 +8455,7 @@ static int md_seq_show(struct seq_file * + seq_printf(seq, "\n"); + } + spin_unlock(&mddev->lock); ++ mutex_unlock(&mddev->bitmap_info.mutex); + spin_lock(&all_mddevs_lock); + + if (mddev == list_last_entry(&all_mddevs, struct mddev, all_mddevs)) diff --git a/queue-6.12/media-imx-jpeg-fix-potential-error-pointer-dereference-in-detach_pm.patch b/queue-6.12/media-imx-jpeg-fix-potential-error-pointer-dereference-in-detach_pm.patch new file mode 100644 index 0000000000..a806d99bf5 --- /dev/null +++ b/queue-6.12/media-imx-jpeg-fix-potential-error-pointer-dereference-in-detach_pm.patch @@ -0,0 +1,46 @@ +From 1378ffec30367233152b7dbf4fa6a25ee98585d1 Mon Sep 17 00:00:00 2001 +From: Dan Carpenter +Date: Thu, 17 Oct 2024 23:34:16 +0300 +Subject: media: imx-jpeg: Fix potential error pointer dereference in detach_pm() + +From: Dan Carpenter + +commit 1378ffec30367233152b7dbf4fa6a25ee98585d1 upstream. + +The proble is on the first line: + + if (jpeg->pd_dev[i] && !pm_runtime_suspended(jpeg->pd_dev[i])) + +If jpeg->pd_dev[i] is an error pointer, then passing it to +pm_runtime_suspended() will lead to an Oops. The other conditions +check for both error pointers and NULL, but it would be more clear to +use the IS_ERR_OR_NULL() check for that. + +Fixes: fd0af4cd35da ("media: imx-jpeg: Ensure power suppliers be suspended before detach them") +Cc: +Signed-off-by: Dan Carpenter +Reviewed-by: Ming Qian +Signed-off-by: Hans Verkuil +Signed-off-by: Greg Kroah-Hartman +--- + drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c | 7 ++++--- + 1 file changed, 4 insertions(+), 3 deletions(-) + +--- a/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c ++++ b/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c +@@ -2679,11 +2679,12 @@ static void mxc_jpeg_detach_pm_domains(s + int i; + + for (i = 0; i < jpeg->num_domains; i++) { +- if (jpeg->pd_dev[i] && !pm_runtime_suspended(jpeg->pd_dev[i])) ++ if (!IS_ERR_OR_NULL(jpeg->pd_dev[i]) && ++ !pm_runtime_suspended(jpeg->pd_dev[i])) + pm_runtime_force_suspend(jpeg->pd_dev[i]); +- if (jpeg->pd_link[i] && !IS_ERR(jpeg->pd_link[i])) ++ if (!IS_ERR_OR_NULL(jpeg->pd_link[i])) + device_link_del(jpeg->pd_link[i]); +- if (jpeg->pd_dev[i] && !IS_ERR(jpeg->pd_dev[i])) ++ if (!IS_ERR_OR_NULL(jpeg->pd_dev[i])) + dev_pm_domain_detach(jpeg->pd_dev[i], true); + jpeg->pd_dev[i] = NULL; + jpeg->pd_link[i] = NULL; diff --git a/queue-6.12/media-uvcvideo-fix-double-free-in-error-path.patch b/queue-6.12/media-uvcvideo-fix-double-free-in-error-path.patch new file mode 100644 index 0000000000..dc3d94c7b6 --- /dev/null +++ b/queue-6.12/media-uvcvideo-fix-double-free-in-error-path.patch @@ -0,0 +1,36 @@ +From c6ef3a7fa97ec823a1e1af9085cf13db9f7b3bac Mon Sep 17 00:00:00 2001 +From: Laurent Pinchart +Date: Fri, 8 Nov 2024 01:51:30 +0200 +Subject: media: uvcvideo: Fix double free in error path + +From: Laurent Pinchart + +commit c6ef3a7fa97ec823a1e1af9085cf13db9f7b3bac upstream. + +If the uvc_status_init() function fails to allocate the int_urb, it will +free the dev->status pointer but doesn't reset the pointer to NULL. This +results in the kfree() call in uvc_status_cleanup() trying to +double-free the memory. Fix it by resetting the dev->status pointer to +NULL after freeing it. + +Fixes: a31a4055473b ("V4L/DVB:usbvideo:don't use part of buffer for USB transfer #4") +Cc: stable@vger.kernel.org +Link: https://lore.kernel.org/r/20241107235130.31372-1-laurent.pinchart@ideasonboard.com +Signed-off-by: Laurent Pinchart +Reviewed by: Ricardo Ribalda +Signed-off-by: Mauro Carvalho Chehab +Signed-off-by: Greg Kroah-Hartman +--- + drivers/media/usb/uvc/uvc_status.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/media/usb/uvc/uvc_status.c ++++ b/drivers/media/usb/uvc/uvc_status.c +@@ -269,6 +269,7 @@ int uvc_status_init(struct uvc_device *d + dev->int_urb = usb_alloc_urb(0, GFP_KERNEL); + if (!dev->int_urb) { + kfree(dev->status); ++ dev->status = NULL; + return -ENOMEM; + } + diff --git a/queue-6.12/mptcp-blackhole-only-if-1st-syn-retrans-w-o-mpc-is-accepted.patch b/queue-6.12/mptcp-blackhole-only-if-1st-syn-retrans-w-o-mpc-is-accepted.patch new file mode 100644 index 0000000000..89f4bcf160 --- /dev/null +++ b/queue-6.12/mptcp-blackhole-only-if-1st-syn-retrans-w-o-mpc-is-accepted.patch @@ -0,0 +1,49 @@ +From e598d8981fd34470b78a1ae777dbf131b15d5bf2 Mon Sep 17 00:00:00 2001 +From: "Matthieu Baerts (NGI0)" +Date: Wed, 29 Jan 2025 13:24:32 +0100 +Subject: mptcp: blackhole only if 1st SYN retrans w/o MPC is accepted + +From: Matthieu Baerts (NGI0) + +commit e598d8981fd34470b78a1ae777dbf131b15d5bf2 upstream. + +The Fixes commit mentioned this: + +> An MPTCP firewall blackhole can be detected if the following SYN +> retransmission after a fallback to "plain" TCP is accepted. + +But in fact, this blackhole was detected if any following SYN +retransmissions after a fallback to TCP was accepted. + +That's because 'mptcp_subflow_early_fallback()' will set 'request_mptcp' +to 0, and 'mpc_drop' will never be reset to 0 after. + +This is an issue, because some not so unusual situations might cause the +kernel to detect a false-positive blackhole, e.g. a client trying to +connect to a server while the network is not ready yet, causing a few +SYN retransmissions, before reaching the end server. + +Fixes: 27069e7cb3d1 ("mptcp: disable active MPTCP in case of blackhole") +Cc: stable@vger.kernel.org +Reviewed-by: Mat Martineau +Signed-off-by: Matthieu Baerts (NGI0) +Signed-off-by: Paolo Abeni +Signed-off-by: Greg Kroah-Hartman +--- + net/mptcp/ctrl.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/net/mptcp/ctrl.c ++++ b/net/mptcp/ctrl.c +@@ -405,9 +405,9 @@ void mptcp_active_detect_blackhole(struc + MPTCP_INC_STATS(sock_net(ssk), MPTCP_MIB_MPCAPABLEACTIVEDROP); + subflow->mpc_drop = 1; + mptcp_subflow_early_fallback(mptcp_sk(subflow->conn), subflow); +- } else { +- subflow->mpc_drop = 0; + } ++ } else if (ssk->sk_state == TCP_SYN_SENT) { ++ subflow->mpc_drop = 0; + } + } + diff --git a/queue-6.12/mptcp-consolidate-suboption-status.patch b/queue-6.12/mptcp-consolidate-suboption-status.patch new file mode 100644 index 0000000000..f6f2fa3e0c --- /dev/null +++ b/queue-6.12/mptcp-consolidate-suboption-status.patch @@ -0,0 +1,328 @@ +From c86b000782daba926c627d2fa00c3f60a75e7472 Mon Sep 17 00:00:00 2001 +From: Paolo Abeni +Date: Thu, 23 Jan 2025 19:05:54 +0100 +Subject: mptcp: consolidate suboption status + +From: Paolo Abeni + +commit c86b000782daba926c627d2fa00c3f60a75e7472 upstream. + +MPTCP maintains the received sub-options status is the bitmask carrying +the received suboptions and in several bitfields carrying per suboption +additional info. + +Zeroing the bitmask before parsing is not enough to ensure a consistent +status, and the MPTCP code has to additionally clear some bitfiled +depending on the actually parsed suboption. + +The above schema is fragile, and syzbot managed to trigger a path where +a relevant bitfield is not cleared/initialized: + + BUG: KMSAN: uninit-value in __mptcp_expand_seq net/mptcp/options.c:1030 [inline] + BUG: KMSAN: uninit-value in mptcp_expand_seq net/mptcp/protocol.h:864 [inline] + BUG: KMSAN: uninit-value in ack_update_msk net/mptcp/options.c:1060 [inline] + BUG: KMSAN: uninit-value in mptcp_incoming_options+0x2036/0x3d30 net/mptcp/options.c:1209 + __mptcp_expand_seq net/mptcp/options.c:1030 [inline] + mptcp_expand_seq net/mptcp/protocol.h:864 [inline] + ack_update_msk net/mptcp/options.c:1060 [inline] + mptcp_incoming_options+0x2036/0x3d30 net/mptcp/options.c:1209 + tcp_data_queue+0xb4/0x7be0 net/ipv4/tcp_input.c:5233 + tcp_rcv_established+0x1061/0x2510 net/ipv4/tcp_input.c:6264 + tcp_v4_do_rcv+0x7f3/0x11a0 net/ipv4/tcp_ipv4.c:1916 + tcp_v4_rcv+0x51df/0x5750 net/ipv4/tcp_ipv4.c:2351 + ip_protocol_deliver_rcu+0x2a3/0x13d0 net/ipv4/ip_input.c:205 + ip_local_deliver_finish+0x336/0x500 net/ipv4/ip_input.c:233 + NF_HOOK include/linux/netfilter.h:314 [inline] + ip_local_deliver+0x21f/0x490 net/ipv4/ip_input.c:254 + dst_input include/net/dst.h:460 [inline] + ip_rcv_finish+0x4a2/0x520 net/ipv4/ip_input.c:447 + NF_HOOK include/linux/netfilter.h:314 [inline] + ip_rcv+0xcd/0x380 net/ipv4/ip_input.c:567 + __netif_receive_skb_one_core net/core/dev.c:5704 [inline] + __netif_receive_skb+0x319/0xa00 net/core/dev.c:5817 + process_backlog+0x4ad/0xa50 net/core/dev.c:6149 + __napi_poll+0xe7/0x980 net/core/dev.c:6902 + napi_poll net/core/dev.c:6971 [inline] + net_rx_action+0xa5a/0x19b0 net/core/dev.c:7093 + handle_softirqs+0x1a0/0x7c0 kernel/softirq.c:561 + __do_softirq+0x14/0x1a kernel/softirq.c:595 + do_softirq+0x9a/0x100 kernel/softirq.c:462 + __local_bh_enable_ip+0x9f/0xb0 kernel/softirq.c:389 + local_bh_enable include/linux/bottom_half.h:33 [inline] + rcu_read_unlock_bh include/linux/rcupdate.h:919 [inline] + __dev_queue_xmit+0x2758/0x57d0 net/core/dev.c:4493 + dev_queue_xmit include/linux/netdevice.h:3168 [inline] + neigh_hh_output include/net/neighbour.h:523 [inline] + neigh_output include/net/neighbour.h:537 [inline] + ip_finish_output2+0x187c/0x1b70 net/ipv4/ip_output.c:236 + __ip_finish_output+0x287/0x810 + ip_finish_output+0x4b/0x600 net/ipv4/ip_output.c:324 + NF_HOOK_COND include/linux/netfilter.h:303 [inline] + ip_output+0x15f/0x3f0 net/ipv4/ip_output.c:434 + dst_output include/net/dst.h:450 [inline] + ip_local_out net/ipv4/ip_output.c:130 [inline] + __ip_queue_xmit+0x1f2a/0x20d0 net/ipv4/ip_output.c:536 + ip_queue_xmit+0x60/0x80 net/ipv4/ip_output.c:550 + __tcp_transmit_skb+0x3cea/0x4900 net/ipv4/tcp_output.c:1468 + tcp_transmit_skb net/ipv4/tcp_output.c:1486 [inline] + tcp_write_xmit+0x3b90/0x9070 net/ipv4/tcp_output.c:2829 + __tcp_push_pending_frames+0xc4/0x380 net/ipv4/tcp_output.c:3012 + tcp_send_fin+0x9f6/0xf50 net/ipv4/tcp_output.c:3618 + __tcp_close+0x140c/0x1550 net/ipv4/tcp.c:3130 + __mptcp_close_ssk+0x74e/0x16f0 net/mptcp/protocol.c:2496 + mptcp_close_ssk+0x26b/0x2c0 net/mptcp/protocol.c:2550 + mptcp_pm_nl_rm_addr_or_subflow+0x635/0xd10 net/mptcp/pm_netlink.c:889 + mptcp_pm_nl_rm_subflow_received net/mptcp/pm_netlink.c:924 [inline] + mptcp_pm_flush_addrs_and_subflows net/mptcp/pm_netlink.c:1688 [inline] + mptcp_nl_flush_addrs_list net/mptcp/pm_netlink.c:1709 [inline] + mptcp_pm_nl_flush_addrs_doit+0xe10/0x1630 net/mptcp/pm_netlink.c:1750 + genl_family_rcv_msg_doit net/netlink/genetlink.c:1115 [inline] + genl_family_rcv_msg net/netlink/genetlink.c:1195 [inline] + genl_rcv_msg+0x1214/0x12c0 net/netlink/genetlink.c:1210 + netlink_rcv_skb+0x375/0x650 net/netlink/af_netlink.c:2542 + genl_rcv+0x40/0x60 net/netlink/genetlink.c:1219 + netlink_unicast_kernel net/netlink/af_netlink.c:1321 [inline] + netlink_unicast+0xf52/0x1260 net/netlink/af_netlink.c:1347 + netlink_sendmsg+0x10da/0x11e0 net/netlink/af_netlink.c:1891 + sock_sendmsg_nosec net/socket.c:711 [inline] + __sock_sendmsg+0x30f/0x380 net/socket.c:726 + ____sys_sendmsg+0x877/0xb60 net/socket.c:2583 + ___sys_sendmsg+0x28d/0x3c0 net/socket.c:2637 + __sys_sendmsg net/socket.c:2669 [inline] + __do_sys_sendmsg net/socket.c:2674 [inline] + __se_sys_sendmsg net/socket.c:2672 [inline] + __x64_sys_sendmsg+0x212/0x3c0 net/socket.c:2672 + x64_sys_call+0x2ed6/0x3c30 arch/x86/include/generated/asm/syscalls_64.h:47 + do_syscall_x64 arch/x86/entry/common.c:52 [inline] + do_syscall_64+0xcd/0x1e0 arch/x86/entry/common.c:83 + entry_SYSCALL_64_after_hwframe+0x77/0x7f + + Uninit was stored to memory at: + mptcp_get_options+0x2c0f/0x2f20 net/mptcp/options.c:397 + mptcp_incoming_options+0x19a/0x3d30 net/mptcp/options.c:1150 + tcp_data_queue+0xb4/0x7be0 net/ipv4/tcp_input.c:5233 + tcp_rcv_established+0x1061/0x2510 net/ipv4/tcp_input.c:6264 + tcp_v4_do_rcv+0x7f3/0x11a0 net/ipv4/tcp_ipv4.c:1916 + tcp_v4_rcv+0x51df/0x5750 net/ipv4/tcp_ipv4.c:2351 + ip_protocol_deliver_rcu+0x2a3/0x13d0 net/ipv4/ip_input.c:205 + ip_local_deliver_finish+0x336/0x500 net/ipv4/ip_input.c:233 + NF_HOOK include/linux/netfilter.h:314 [inline] + ip_local_deliver+0x21f/0x490 net/ipv4/ip_input.c:254 + dst_input include/net/dst.h:460 [inline] + ip_rcv_finish+0x4a2/0x520 net/ipv4/ip_input.c:447 + NF_HOOK include/linux/netfilter.h:314 [inline] + ip_rcv+0xcd/0x380 net/ipv4/ip_input.c:567 + __netif_receive_skb_one_core net/core/dev.c:5704 [inline] + __netif_receive_skb+0x319/0xa00 net/core/dev.c:5817 + process_backlog+0x4ad/0xa50 net/core/dev.c:6149 + __napi_poll+0xe7/0x980 net/core/dev.c:6902 + napi_poll net/core/dev.c:6971 [inline] + net_rx_action+0xa5a/0x19b0 net/core/dev.c:7093 + handle_softirqs+0x1a0/0x7c0 kernel/softirq.c:561 + __do_softirq+0x14/0x1a kernel/softirq.c:595 + + Uninit was stored to memory at: + put_unaligned_be32 include/linux/unaligned.h:68 [inline] + mptcp_write_options+0x17f9/0x3100 net/mptcp/options.c:1417 + mptcp_options_write net/ipv4/tcp_output.c:465 [inline] + tcp_options_write+0x6d9/0xe90 net/ipv4/tcp_output.c:759 + __tcp_transmit_skb+0x294b/0x4900 net/ipv4/tcp_output.c:1414 + tcp_transmit_skb net/ipv4/tcp_output.c:1486 [inline] + tcp_write_xmit+0x3b90/0x9070 net/ipv4/tcp_output.c:2829 + __tcp_push_pending_frames+0xc4/0x380 net/ipv4/tcp_output.c:3012 + tcp_send_fin+0x9f6/0xf50 net/ipv4/tcp_output.c:3618 + __tcp_close+0x140c/0x1550 net/ipv4/tcp.c:3130 + __mptcp_close_ssk+0x74e/0x16f0 net/mptcp/protocol.c:2496 + mptcp_close_ssk+0x26b/0x2c0 net/mptcp/protocol.c:2550 + mptcp_pm_nl_rm_addr_or_subflow+0x635/0xd10 net/mptcp/pm_netlink.c:889 + mptcp_pm_nl_rm_subflow_received net/mptcp/pm_netlink.c:924 [inline] + mptcp_pm_flush_addrs_and_subflows net/mptcp/pm_netlink.c:1688 [inline] + mptcp_nl_flush_addrs_list net/mptcp/pm_netlink.c:1709 [inline] + mptcp_pm_nl_flush_addrs_doit+0xe10/0x1630 net/mptcp/pm_netlink.c:1750 + genl_family_rcv_msg_doit net/netlink/genetlink.c:1115 [inline] + genl_family_rcv_msg net/netlink/genetlink.c:1195 [inline] + genl_rcv_msg+0x1214/0x12c0 net/netlink/genetlink.c:1210 + netlink_rcv_skb+0x375/0x650 net/netlink/af_netlink.c:2542 + genl_rcv+0x40/0x60 net/netlink/genetlink.c:1219 + netlink_unicast_kernel net/netlink/af_netlink.c:1321 [inline] + netlink_unicast+0xf52/0x1260 net/netlink/af_netlink.c:1347 + netlink_sendmsg+0x10da/0x11e0 net/netlink/af_netlink.c:1891 + sock_sendmsg_nosec net/socket.c:711 [inline] + __sock_sendmsg+0x30f/0x380 net/socket.c:726 + ____sys_sendmsg+0x877/0xb60 net/socket.c:2583 + ___sys_sendmsg+0x28d/0x3c0 net/socket.c:2637 + __sys_sendmsg net/socket.c:2669 [inline] + __do_sys_sendmsg net/socket.c:2674 [inline] + __se_sys_sendmsg net/socket.c:2672 [inline] + __x64_sys_sendmsg+0x212/0x3c0 net/socket.c:2672 + x64_sys_call+0x2ed6/0x3c30 arch/x86/include/generated/asm/syscalls_64.h:47 + do_syscall_x64 arch/x86/entry/common.c:52 [inline] + do_syscall_64+0xcd/0x1e0 arch/x86/entry/common.c:83 + entry_SYSCALL_64_after_hwframe+0x77/0x7f + + Uninit was stored to memory at: + mptcp_pm_add_addr_signal+0x3d7/0x4c0 + mptcp_established_options_add_addr net/mptcp/options.c:666 [inline] + mptcp_established_options+0x1b9b/0x3a00 net/mptcp/options.c:884 + tcp_established_options+0x2c4/0x7d0 net/ipv4/tcp_output.c:1012 + __tcp_transmit_skb+0x5b7/0x4900 net/ipv4/tcp_output.c:1333 + tcp_transmit_skb net/ipv4/tcp_output.c:1486 [inline] + tcp_write_xmit+0x3b90/0x9070 net/ipv4/tcp_output.c:2829 + __tcp_push_pending_frames+0xc4/0x380 net/ipv4/tcp_output.c:3012 + tcp_send_fin+0x9f6/0xf50 net/ipv4/tcp_output.c:3618 + __tcp_close+0x140c/0x1550 net/ipv4/tcp.c:3130 + __mptcp_close_ssk+0x74e/0x16f0 net/mptcp/protocol.c:2496 + mptcp_close_ssk+0x26b/0x2c0 net/mptcp/protocol.c:2550 + mptcp_pm_nl_rm_addr_or_subflow+0x635/0xd10 net/mptcp/pm_netlink.c:889 + mptcp_pm_nl_rm_subflow_received net/mptcp/pm_netlink.c:924 [inline] + mptcp_pm_flush_addrs_and_subflows net/mptcp/pm_netlink.c:1688 [inline] + mptcp_nl_flush_addrs_list net/mptcp/pm_netlink.c:1709 [inline] + mptcp_pm_nl_flush_addrs_doit+0xe10/0x1630 net/mptcp/pm_netlink.c:1750 + genl_family_rcv_msg_doit net/netlink/genetlink.c:1115 [inline] + genl_family_rcv_msg net/netlink/genetlink.c:1195 [inline] + genl_rcv_msg+0x1214/0x12c0 net/netlink/genetlink.c:1210 + netlink_rcv_skb+0x375/0x650 net/netlink/af_netlink.c:2542 + genl_rcv+0x40/0x60 net/netlink/genetlink.c:1219 + netlink_unicast_kernel net/netlink/af_netlink.c:1321 [inline] + netlink_unicast+0xf52/0x1260 net/netlink/af_netlink.c:1347 + netlink_sendmsg+0x10da/0x11e0 net/netlink/af_netlink.c:1891 + sock_sendmsg_nosec net/socket.c:711 [inline] + __sock_sendmsg+0x30f/0x380 net/socket.c:726 + ____sys_sendmsg+0x877/0xb60 net/socket.c:2583 + ___sys_sendmsg+0x28d/0x3c0 net/socket.c:2637 + __sys_sendmsg net/socket.c:2669 [inline] + __do_sys_sendmsg net/socket.c:2674 [inline] + __se_sys_sendmsg net/socket.c:2672 [inline] + __x64_sys_sendmsg+0x212/0x3c0 net/socket.c:2672 + x64_sys_call+0x2ed6/0x3c30 arch/x86/include/generated/asm/syscalls_64.h:47 + do_syscall_x64 arch/x86/entry/common.c:52 [inline] + do_syscall_64+0xcd/0x1e0 arch/x86/entry/common.c:83 + entry_SYSCALL_64_after_hwframe+0x77/0x7f + + Uninit was stored to memory at: + mptcp_pm_add_addr_received+0x95f/0xdd0 net/mptcp/pm.c:235 + mptcp_incoming_options+0x2983/0x3d30 net/mptcp/options.c:1169 + tcp_data_queue+0xb4/0x7be0 net/ipv4/tcp_input.c:5233 + tcp_rcv_state_process+0x2a38/0x49d0 net/ipv4/tcp_input.c:6972 + tcp_v4_do_rcv+0xbf9/0x11a0 net/ipv4/tcp_ipv4.c:1939 + tcp_v4_rcv+0x51df/0x5750 net/ipv4/tcp_ipv4.c:2351 + ip_protocol_deliver_rcu+0x2a3/0x13d0 net/ipv4/ip_input.c:205 + ip_local_deliver_finish+0x336/0x500 net/ipv4/ip_input.c:233 + NF_HOOK include/linux/netfilter.h:314 [inline] + ip_local_deliver+0x21f/0x490 net/ipv4/ip_input.c:254 + dst_input include/net/dst.h:460 [inline] + ip_rcv_finish+0x4a2/0x520 net/ipv4/ip_input.c:447 + NF_HOOK include/linux/netfilter.h:314 [inline] + ip_rcv+0xcd/0x380 net/ipv4/ip_input.c:567 + __netif_receive_skb_one_core net/core/dev.c:5704 [inline] + __netif_receive_skb+0x319/0xa00 net/core/dev.c:5817 + process_backlog+0x4ad/0xa50 net/core/dev.c:6149 + __napi_poll+0xe7/0x980 net/core/dev.c:6902 + napi_poll net/core/dev.c:6971 [inline] + net_rx_action+0xa5a/0x19b0 net/core/dev.c:7093 + handle_softirqs+0x1a0/0x7c0 kernel/softirq.c:561 + __do_softirq+0x14/0x1a kernel/softirq.c:595 + + Local variable mp_opt created at: + mptcp_incoming_options+0x119/0x3d30 net/mptcp/options.c:1127 + tcp_data_queue+0xb4/0x7be0 net/ipv4/tcp_input.c:5233 + +The current schema is too fragile; address the issue grouping all the +state-related data together and clearing the whole group instead of +just the bitmask. This also cleans-up the code a bit, as there is no +need to individually clear "random" bitfield in a couple of places +any more. + +Fixes: 84dfe3677a6f ("mptcp: send out dedicated ADD_ADDR packet") +Cc: stable@vger.kernel.org +Reported-by: syzbot+23728c2df58b3bd175ad@syzkaller.appspotmail.com +Closes: https://lore.kernel.org/6786ac51.050a0220.216c54.00a7.GAE@google.com +Closes: https://github.com/multipath-tcp/mptcp_net-next/issues/541 +Signed-off-by: Paolo Abeni +Reviewed-by: Matthieu Baerts (NGI0) +Signed-off-by: Matthieu Baerts (NGI0) +Link: https://patch.msgid.link/20250123-net-mptcp-syzbot-issues-v1-1-af73258a726f@kernel.org +Signed-off-by: Jakub Kicinski +Signed-off-by: Greg Kroah-Hartman +--- + net/mptcp/options.c | 13 +++++-------- + net/mptcp/protocol.h | 30 ++++++++++++++++-------------- + 2 files changed, 21 insertions(+), 22 deletions(-) + +--- a/net/mptcp/options.c ++++ b/net/mptcp/options.c +@@ -108,7 +108,6 @@ static void mptcp_parse_option(const str + mp_opt->suboptions |= OPTION_MPTCP_DSS; + mp_opt->use_map = 1; + mp_opt->mpc_map = 1; +- mp_opt->use_ack = 0; + mp_opt->data_len = get_unaligned_be16(ptr); + ptr += 2; + } +@@ -157,11 +156,6 @@ static void mptcp_parse_option(const str + pr_debug("DSS\n"); + ptr++; + +- /* we must clear 'mpc_map' be able to detect MP_CAPABLE +- * map vs DSS map in mptcp_incoming_options(), and reconstruct +- * map info accordingly +- */ +- mp_opt->mpc_map = 0; + flags = (*ptr++) & MPTCP_DSS_FLAG_MASK; + mp_opt->data_fin = (flags & MPTCP_DSS_DATA_FIN) != 0; + mp_opt->dsn64 = (flags & MPTCP_DSS_DSN64) != 0; +@@ -369,8 +363,11 @@ void mptcp_get_options(const struct sk_b + const unsigned char *ptr; + int length; + +- /* initialize option status */ +- mp_opt->suboptions = 0; ++ /* Ensure that casting the whole status to u32 is efficient and safe */ ++ BUILD_BUG_ON(sizeof_field(struct mptcp_options_received, status) != sizeof(u32)); ++ BUILD_BUG_ON(!IS_ALIGNED(offsetof(struct mptcp_options_received, status), ++ sizeof(u32))); ++ *(u32 *)&mp_opt->status = 0; + + length = (th->doff * 4) - sizeof(struct tcphdr); + ptr = (const unsigned char *)(th + 1); +--- a/net/mptcp/protocol.h ++++ b/net/mptcp/protocol.h +@@ -149,22 +149,24 @@ struct mptcp_options_received { + u32 subflow_seq; + u16 data_len; + __sum16 csum; +- u16 suboptions; ++ struct_group(status, ++ u16 suboptions; ++ u16 use_map:1, ++ dsn64:1, ++ data_fin:1, ++ use_ack:1, ++ ack64:1, ++ mpc_map:1, ++ reset_reason:4, ++ reset_transient:1, ++ echo:1, ++ backup:1, ++ deny_join_id0:1, ++ __unused:2; ++ ); ++ u8 join_id; + u32 token; + u32 nonce; +- u16 use_map:1, +- dsn64:1, +- data_fin:1, +- use_ack:1, +- ack64:1, +- mpc_map:1, +- reset_reason:4, +- reset_transient:1, +- echo:1, +- backup:1, +- deny_join_id0:1, +- __unused:2; +- u8 join_id; + u64 thmac; + u8 hmac[MPTCPOPT_HMAC_LEN]; + struct mptcp_addr_info addr; diff --git a/queue-6.12/mptcp-handle-fastopen-disconnect-correctly.patch b/queue-6.12/mptcp-handle-fastopen-disconnect-correctly.patch new file mode 100644 index 0000000000..2e5bc372e1 --- /dev/null +++ b/queue-6.12/mptcp-handle-fastopen-disconnect-correctly.patch @@ -0,0 +1,92 @@ +From 619af16b3b57a3a4ee50b9a30add9ff155541e71 Mon Sep 17 00:00:00 2001 +From: Paolo Abeni +Date: Thu, 23 Jan 2025 19:05:56 +0100 +Subject: mptcp: handle fastopen disconnect correctly + +From: Paolo Abeni + +commit 619af16b3b57a3a4ee50b9a30add9ff155541e71 upstream. + +Syzbot was able to trigger a data stream corruption: + + WARNING: CPU: 0 PID: 9846 at net/mptcp/protocol.c:1024 __mptcp_clean_una+0xddb/0xff0 net/mptcp/protocol.c:1024 + Modules linked in: + CPU: 0 UID: 0 PID: 9846 Comm: syz-executor351 Not tainted 6.13.0-rc2-syzkaller-00059-g00a5acdbf398 #0 + Hardware name: Google Compute Engine/Google Compute Engine, BIOS Google 11/25/2024 + RIP: 0010:__mptcp_clean_una+0xddb/0xff0 net/mptcp/protocol.c:1024 + Code: fa ff ff 48 8b 4c 24 18 80 e1 07 fe c1 38 c1 0f 8c 8e fa ff ff 48 8b 7c 24 18 e8 e0 db 54 f6 e9 7f fa ff ff e8 e6 80 ee f5 90 <0f> 0b 90 4c 8b 6c 24 40 4d 89 f4 e9 04 f5 ff ff 44 89 f1 80 e1 07 + RSP: 0018:ffffc9000c0cf400 EFLAGS: 00010293 + RAX: ffffffff8bb0dd5a RBX: ffff888033f5d230 RCX: ffff888059ce8000 + RDX: 0000000000000000 RSI: 0000000000000000 RDI: 0000000000000000 + RBP: ffffc9000c0cf518 R08: ffffffff8bb0d1dd R09: 1ffff110170c8928 + R10: dffffc0000000000 R11: ffffed10170c8929 R12: 0000000000000000 + R13: ffff888033f5d220 R14: dffffc0000000000 R15: ffff8880592b8000 + FS: 00007f6e866496c0(0000) GS:ffff8880b8600000(0000) knlGS:0000000000000000 + CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 + CR2: 00007f6e86f491a0 CR3: 00000000310e6000 CR4: 00000000003526f0 + DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 + DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 + Call Trace: + + __mptcp_clean_una_wakeup+0x7f/0x2d0 net/mptcp/protocol.c:1074 + mptcp_release_cb+0x7cb/0xb30 net/mptcp/protocol.c:3493 + release_sock+0x1aa/0x1f0 net/core/sock.c:3640 + inet_wait_for_connect net/ipv4/af_inet.c:609 [inline] + __inet_stream_connect+0x8bd/0xf30 net/ipv4/af_inet.c:703 + mptcp_sendmsg_fastopen+0x2a2/0x530 net/mptcp/protocol.c:1755 + mptcp_sendmsg+0x1884/0x1b10 net/mptcp/protocol.c:1830 + sock_sendmsg_nosec net/socket.c:711 [inline] + __sock_sendmsg+0x1a6/0x270 net/socket.c:726 + ____sys_sendmsg+0x52a/0x7e0 net/socket.c:2583 + ___sys_sendmsg net/socket.c:2637 [inline] + __sys_sendmsg+0x269/0x350 net/socket.c:2669 + do_syscall_x64 arch/x86/entry/common.c:52 [inline] + do_syscall_64+0xf3/0x230 arch/x86/entry/common.c:83 + entry_SYSCALL_64_after_hwframe+0x77/0x7f + RIP: 0033:0x7f6e86ebfe69 + Code: 28 00 00 00 75 05 48 83 c4 28 c3 e8 b1 1f 00 00 90 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 c7 c1 b0 ff ff ff f7 d8 64 89 01 48 + RSP: 002b:00007f6e86649168 EFLAGS: 00000246 ORIG_RAX: 000000000000002e + RAX: ffffffffffffffda RBX: 00007f6e86f491b8 RCX: 00007f6e86ebfe69 + RDX: 0000000030004001 RSI: 0000000020000080 RDI: 0000000000000003 + RBP: 00007f6e86f491b0 R08: 00007f6e866496c0 R09: 0000000000000000 + R10: 0000000000000000 R11: 0000000000000246 R12: 00007f6e86f491bc + R13: 000000000000006e R14: 00007ffe445d9420 R15: 00007ffe445d9508 + + +The root cause is the bad handling of disconnect() generated internally +by the MPTCP protocol in case of connect FASTOPEN errors. + +Address the issue increasing the socket disconnect counter even on such +a case, to allow other threads waiting on the same socket lock to +properly error out. + +Fixes: c2b2ae3925b6 ("mptcp: handle correctly disconnect() failures") +Cc: stable@vger.kernel.org +Reported-by: syzbot+ebc0b8ae5d3590b2c074@syzkaller.appspotmail.com +Closes: https://lore.kernel.org/67605870.050a0220.37aaf.0137.GAE@google.com +Closes: https://github.com/multipath-tcp/mptcp_net-next/issues/537 +Tested-by: syzbot+ebc0b8ae5d3590b2c074@syzkaller.appspotmail.com +Signed-off-by: Paolo Abeni +Reviewed-by: Matthieu Baerts (NGI0) +Signed-off-by: Matthieu Baerts (NGI0) +Link: https://patch.msgid.link/20250123-net-mptcp-syzbot-issues-v1-3-af73258a726f@kernel.org +Signed-off-by: Jakub Kicinski +Signed-off-by: Greg Kroah-Hartman +--- + net/mptcp/protocol.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +--- a/net/mptcp/protocol.c ++++ b/net/mptcp/protocol.c +@@ -1766,8 +1766,10 @@ static int mptcp_sendmsg_fastopen(struct + * see mptcp_disconnect(). + * Attempt it again outside the problematic scope. + */ +- if (!mptcp_disconnect(sk, 0)) ++ if (!mptcp_disconnect(sk, 0)) { ++ sk->sk_disconnects++; + sk->sk_socket->state = SS_UNCONNECTED; ++ } + } + inet_clear_bit(DEFER_CONNECT, sk); + diff --git a/queue-6.12/mptcp-pm-only-set-fullmesh-for-subflow-endp.patch b/queue-6.12/mptcp-pm-only-set-fullmesh-for-subflow-endp.patch new file mode 100644 index 0000000000..74ead0dda6 --- /dev/null +++ b/queue-6.12/mptcp-pm-only-set-fullmesh-for-subflow-endp.patch @@ -0,0 +1,107 @@ +From 1bb0d1348546ad059f55c93def34e67cb2a034a6 Mon Sep 17 00:00:00 2001 +From: "Matthieu Baerts (NGI0)" +Date: Thu, 23 Jan 2025 19:05:55 +0100 +Subject: mptcp: pm: only set fullmesh for subflow endp + +From: Matthieu Baerts (NGI0) + +commit 1bb0d1348546ad059f55c93def34e67cb2a034a6 upstream. + +With the in-kernel path-manager, it is possible to change the 'fullmesh' +flag. The code in mptcp_pm_nl_fullmesh() expects to change it only on +'subflow' endpoints, to recreate more or less subflows using the linked +address. + +Unfortunately, the set_flags() hook was a bit more permissive, and +allowed 'implicit' endpoints to get the 'fullmesh' flag while it is not +allowed before. + +That's what syzbot found, triggering the following warning: + + WARNING: CPU: 0 PID: 6499 at net/mptcp/pm_netlink.c:1496 __mark_subflow_endp_available net/mptcp/pm_netlink.c:1496 [inline] + WARNING: CPU: 0 PID: 6499 at net/mptcp/pm_netlink.c:1496 mptcp_pm_nl_fullmesh net/mptcp/pm_netlink.c:1980 [inline] + WARNING: CPU: 0 PID: 6499 at net/mptcp/pm_netlink.c:1496 mptcp_nl_set_flags net/mptcp/pm_netlink.c:2003 [inline] + WARNING: CPU: 0 PID: 6499 at net/mptcp/pm_netlink.c:1496 mptcp_pm_nl_set_flags+0x974/0xdc0 net/mptcp/pm_netlink.c:2064 + Modules linked in: + CPU: 0 UID: 0 PID: 6499 Comm: syz.1.413 Not tainted 6.13.0-rc5-syzkaller-00172-gd1bf27c4e176 #0 + Hardware name: Google Compute Engine/Google Compute Engine, BIOS Google 09/13/2024 + RIP: 0010:__mark_subflow_endp_available net/mptcp/pm_netlink.c:1496 [inline] + RIP: 0010:mptcp_pm_nl_fullmesh net/mptcp/pm_netlink.c:1980 [inline] + RIP: 0010:mptcp_nl_set_flags net/mptcp/pm_netlink.c:2003 [inline] + RIP: 0010:mptcp_pm_nl_set_flags+0x974/0xdc0 net/mptcp/pm_netlink.c:2064 + Code: 01 00 00 49 89 c5 e8 fb 45 e8 f5 e9 b8 fc ff ff e8 f1 45 e8 f5 4c 89 f7 be 03 00 00 00 e8 44 1d 0b f9 eb a0 e8 dd 45 e8 f5 90 <0f> 0b 90 e9 17 ff ff ff 89 d9 80 e1 07 38 c1 0f 8c c9 fc ff ff 48 + RSP: 0018:ffffc9000d307240 EFLAGS: 00010293 + RAX: ffffffff8bb72e03 RBX: 0000000000000000 RCX: ffff88807da88000 + RDX: 0000000000000000 RSI: 0000000000000000 RDI: 0000000000000000 + RBP: ffffc9000d307430 R08: ffffffff8bb72cf0 R09: 1ffff1100b842a5e + R10: dffffc0000000000 R11: ffffed100b842a5f R12: ffff88801e2e5ac0 + R13: ffff88805c214800 R14: ffff88805c2152e8 R15: 1ffff1100b842a5d + FS: 00005555619f6500(0000) GS:ffff8880b8600000(0000) knlGS:0000000000000000 + CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 + CR2: 0000000020002840 CR3: 00000000247e6000 CR4: 00000000003526f0 + DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 + DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 + Call Trace: + + genl_family_rcv_msg_doit net/netlink/genetlink.c:1115 [inline] + genl_family_rcv_msg net/netlink/genetlink.c:1195 [inline] + genl_rcv_msg+0xb14/0xec0 net/netlink/genetlink.c:1210 + netlink_rcv_skb+0x1e3/0x430 net/netlink/af_netlink.c:2542 + genl_rcv+0x28/0x40 net/netlink/genetlink.c:1219 + netlink_unicast_kernel net/netlink/af_netlink.c:1321 [inline] + netlink_unicast+0x7f6/0x990 net/netlink/af_netlink.c:1347 + netlink_sendmsg+0x8e4/0xcb0 net/netlink/af_netlink.c:1891 + sock_sendmsg_nosec net/socket.c:711 [inline] + __sock_sendmsg+0x221/0x270 net/socket.c:726 + ____sys_sendmsg+0x52a/0x7e0 net/socket.c:2583 + ___sys_sendmsg net/socket.c:2637 [inline] + __sys_sendmsg+0x269/0x350 net/socket.c:2669 + do_syscall_x64 arch/x86/entry/common.c:52 [inline] + do_syscall_64+0xf3/0x230 arch/x86/entry/common.c:83 + entry_SYSCALL_64_after_hwframe+0x77/0x7f + RIP: 0033:0x7f5fe8785d29 + Code: ff ff c3 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 40 00 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 c7 c1 a8 ff ff ff f7 d8 64 89 01 48 + RSP: 002b:00007fff571f5558 EFLAGS: 00000246 ORIG_RAX: 000000000000002e + RAX: ffffffffffffffda RBX: 00007f5fe8975fa0 RCX: 00007f5fe8785d29 + RDX: 0000000000000000 RSI: 0000000020000480 RDI: 0000000000000007 + RBP: 00007f5fe8801b08 R08: 0000000000000000 R09: 0000000000000000 + R10: 0000000000000000 R11: 0000000000000246 R12: 0000000000000000 + R13: 00007f5fe8975fa0 R14: 00007f5fe8975fa0 R15: 00000000000011f4 + + +Here, syzbot managed to set the 'fullmesh' flag on an 'implicit' and +used -- according to 'id_avail_bitmap' -- endpoint, causing the PM to +try decrement the local_addr_used counter which is only incremented for +the 'subflow' endpoint. + +Note that 'no type' endpoints -- not 'subflow', 'signal', 'implicit' -- +are fine, because their ID will not be marked as used in the 'id_avail' +bitmap, and setting 'fullmesh' can help forcing the creation of subflow +when receiving an ADD_ADDR. + +Fixes: 73c762c1f07d ("mptcp: set fullmesh flag in pm_netlink") +Cc: stable@vger.kernel.org +Reported-by: syzbot+cd16e79c1e45f3fe0377@syzkaller.appspotmail.com +Closes: https://lore.kernel.org/6786ac51.050a0220.216c54.00a6.GAE@google.com +Closes: https://github.com/multipath-tcp/mptcp_net-next/issues/540 +Reviewed-by: Mat Martineau +Signed-off-by: Matthieu Baerts (NGI0) +Link: https://patch.msgid.link/20250123-net-mptcp-syzbot-issues-v1-2-af73258a726f@kernel.org +Signed-off-by: Jakub Kicinski +Signed-off-by: Greg Kroah-Hartman +--- + net/mptcp/pm_netlink.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/net/mptcp/pm_netlink.c ++++ b/net/mptcp/pm_netlink.c +@@ -2049,7 +2049,8 @@ int mptcp_pm_nl_set_flags(struct sk_buff + return -EINVAL; + } + if ((addr.flags & MPTCP_PM_ADDR_FLAG_FULLMESH) && +- (entry->flags & MPTCP_PM_ADDR_FLAG_SIGNAL)) { ++ (entry->flags & (MPTCP_PM_ADDR_FLAG_SIGNAL | ++ MPTCP_PM_ADDR_FLAG_IMPLICIT))) { + spin_unlock_bh(&pernet->lock); + GENL_SET_ERR_MSG(info, "invalid addr flags"); + return -EINVAL; diff --git a/queue-6.12/powerpc-pseries-iommu-don-t-unset-window-if-it-was-never-set.patch b/queue-6.12/powerpc-pseries-iommu-don-t-unset-window-if-it-was-never-set.patch new file mode 100644 index 0000000000..cecd27d0e0 --- /dev/null +++ b/queue-6.12/powerpc-pseries-iommu-don-t-unset-window-if-it-was-never-set.patch @@ -0,0 +1,63 @@ +From 17391cb2613b82f8c405570fea605af3255ff8d2 Mon Sep 17 00:00:00 2001 +From: Shivaprasad G Bhat +Date: Mon, 13 Jan 2025 03:48:55 +0000 +Subject: powerpc/pseries/iommu: Don't unset window if it was never set + +From: Shivaprasad G Bhat + +commit 17391cb2613b82f8c405570fea605af3255ff8d2 upstream. + +On pSeries, when user attempts to use the same vfio container used by +different iommu group, the spapr_tce_set_window() returns -EPERM +and the subsequent cleanup leads to the below crash. + + Kernel attempted to read user page (308) - exploit attempt? + BUG: Kernel NULL pointer dereference on read at 0x00000308 + Faulting instruction address: 0xc0000000001ce358 + Oops: Kernel access of bad area, sig: 11 [#1] + NIP: c0000000001ce358 LR: c0000000001ce05c CTR: c00000000005add0 + + NIP [c0000000001ce358] spapr_tce_unset_window+0x3b8/0x510 + LR [c0000000001ce05c] spapr_tce_unset_window+0xbc/0x510 + Call Trace: + spapr_tce_unset_window+0xbc/0x510 (unreliable) + tce_iommu_attach_group+0x24c/0x340 [vfio_iommu_spapr_tce] + vfio_container_attach_group+0xec/0x240 [vfio] + vfio_group_fops_unl_ioctl+0x548/0xb00 [vfio] + sys_ioctl+0x754/0x1580 + system_call_exception+0x13c/0x330 + system_call_vectored_common+0x15c/0x2ec + + --- interrupt: 3000 + +Fix this by having null check for the tbl passed to the +spapr_tce_unset_window(). + +Fixes: f431a8cde7f1 ("powerpc/iommu: Reimplement the iommu_table_group_ops for pSeries") +Cc: stable@vger.kernel.org +Reported-by: Vaishnavi Bhat +Signed-off-by: Shivaprasad G Bhat +Signed-off-by: Madhavan Srinivasan +Link: https://patch.msgid.link/173674009556.1559.12487885286848752833.stgit@linux.ibm.com +Signed-off-by: Greg Kroah-Hartman +--- + arch/powerpc/platforms/pseries/iommu.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/arch/powerpc/platforms/pseries/iommu.c b/arch/powerpc/platforms/pseries/iommu.c +index 29f1a0cc59cd..ae6f7a235d8b 100644 +--- a/arch/powerpc/platforms/pseries/iommu.c ++++ b/arch/powerpc/platforms/pseries/iommu.c +@@ -2208,6 +2208,9 @@ static long spapr_tce_unset_window(struct iommu_table_group *table_group, int nu + const char *win_name; + int ret = -ENODEV; + ++ if (!tbl) /* The table was never created OR window was never opened */ ++ return 0; ++ + mutex_lock(&dma_win_init_mutex); + + if ((num == 0) && is_default_window_table(table_group, tbl)) +-- +2.48.1 + diff --git a/queue-6.12/pps-fix-a-use-after-free.patch b/queue-6.12/pps-fix-a-use-after-free.patch new file mode 100644 index 0000000000..f4c0e6f413 --- /dev/null +++ b/queue-6.12/pps-fix-a-use-after-free.patch @@ -0,0 +1,600 @@ +From c79a39dc8d060b9e64e8b0fa9d245d44befeefbe Mon Sep 17 00:00:00 2001 +From: Calvin Owens +Date: Mon, 11 Nov 2024 20:13:29 -0800 +Subject: pps: Fix a use-after-free + +From: Calvin Owens + +commit c79a39dc8d060b9e64e8b0fa9d245d44befeefbe upstream. + +On a board running ntpd and gpsd, I'm seeing a consistent use-after-free +in sys_exit() from gpsd when rebooting: + + pps pps1: removed + ------------[ cut here ]------------ + kobject: '(null)' (00000000db4bec24): is not initialized, yet kobject_put() is being called. + WARNING: CPU: 2 PID: 440 at lib/kobject.c:734 kobject_put+0x120/0x150 + CPU: 2 UID: 299 PID: 440 Comm: gpsd Not tainted 6.11.0-rc6-00308-gb31c44928842 #1 + Hardware name: Raspberry Pi 4 Model B Rev 1.1 (DT) + pstate: 60000005 (nZCv daif -PAN -UAO -TCO -DIT -SSBS BTYPE=--) + pc : kobject_put+0x120/0x150 + lr : kobject_put+0x120/0x150 + sp : ffffffc0803d3ae0 + x29: ffffffc0803d3ae0 x28: ffffff8042dc9738 x27: 0000000000000001 + x26: 0000000000000000 x25: ffffff8042dc9040 x24: ffffff8042dc9440 + x23: ffffff80402a4620 x22: ffffff8042ef4bd0 x21: ffffff80405cb600 + x20: 000000000008001b x19: ffffff8040b3b6e0 x18: 0000000000000000 + x17: 0000000000000000 x16: 0000000000000000 x15: 696e6920746f6e20 + x14: 7369203a29343263 x13: 205d303434542020 x12: 0000000000000000 + x11: 0000000000000000 x10: 0000000000000000 x9 : 0000000000000000 + x8 : 0000000000000000 x7 : 0000000000000000 x6 : 0000000000000000 + x5 : 0000000000000000 x4 : 0000000000000000 x3 : 0000000000000000 + x2 : 0000000000000000 x1 : 0000000000000000 x0 : 0000000000000000 + Call trace: + kobject_put+0x120/0x150 + cdev_put+0x20/0x3c + __fput+0x2c4/0x2d8 + ____fput+0x1c/0x38 + task_work_run+0x70/0xfc + do_exit+0x2a0/0x924 + do_group_exit+0x34/0x90 + get_signal+0x7fc/0x8c0 + do_signal+0x128/0x13b4 + do_notify_resume+0xdc/0x160 + el0_svc+0xd4/0xf8 + el0t_64_sync_handler+0x140/0x14c + el0t_64_sync+0x190/0x194 + ---[ end trace 0000000000000000 ]--- + +...followed by more symptoms of corruption, with similar stacks: + + refcount_t: underflow; use-after-free. + kernel BUG at lib/list_debug.c:62! + Kernel panic - not syncing: Oops - BUG: Fatal exception + +This happens because pps_device_destruct() frees the pps_device with the +embedded cdev immediately after calling cdev_del(), but, as the comment +above cdev_del() notes, fops for previously opened cdevs are still +callable even after cdev_del() returns. I think this bug has always +been there: I can't explain why it suddenly started happening every time +I reboot this particular board. + +In commit d953e0e837e6 ("pps: Fix a use-after free bug when +unregistering a source."), George Spelvin suggested removing the +embedded cdev. That seems like the simplest way to fix this, so I've +implemented his suggestion, using __register_chrdev() with pps_idr +becoming the source of truth for which minor corresponds to which +device. + +But now that pps_idr defines userspace visibility instead of cdev_add(), +we need to be sure the pps->dev refcount can't reach zero while +userspace can still find it again. So, the idr_remove() call moves to +pps_unregister_cdev(), and pps_idr now holds a reference to pps->dev. + + pps_core: source serial1 got cdev (251:1) + <...> + pps pps1: removed + pps_core: unregistering pps1 + pps_core: deallocating pps1 + +Fixes: d953e0e837e6 ("pps: Fix a use-after free bug when unregistering a source.") +Cc: stable@vger.kernel.org +Signed-off-by: Calvin Owens +Reviewed-by: Michal Schmidt +Link: https://lore.kernel.org/r/a17975fd5ae99385791929e563f72564edbcf28f.1731383727.git.calvin@wbinvd.org +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Greg Kroah-Hartman +--- + drivers/pps/clients/pps-gpio.c | 4 - + drivers/pps/clients/pps-ktimer.c | 4 - + drivers/pps/clients/pps-ldisc.c | 6 - + drivers/pps/clients/pps_parport.c | 4 - + drivers/pps/kapi.c | 10 +- + drivers/pps/kc.c | 10 +- + drivers/pps/pps.c | 127 +++++++++++++++++++------------------- + drivers/ptp/ptp_ocp.c | 2 + include/linux/pps_kernel.h | 3 + 9 files changed, 87 insertions(+), 83 deletions(-) + +--- a/drivers/pps/clients/pps-gpio.c ++++ b/drivers/pps/clients/pps-gpio.c +@@ -214,8 +214,8 @@ static int pps_gpio_probe(struct platfor + return -EINVAL; + } + +- dev_info(data->pps->dev, "Registered IRQ %d as PPS source\n", +- data->irq); ++ dev_dbg(&data->pps->dev, "Registered IRQ %d as PPS source\n", ++ data->irq); + + return 0; + } +--- a/drivers/pps/clients/pps-ktimer.c ++++ b/drivers/pps/clients/pps-ktimer.c +@@ -56,7 +56,7 @@ static struct pps_source_info pps_ktimer + + static void __exit pps_ktimer_exit(void) + { +- dev_info(pps->dev, "ktimer PPS source unregistered\n"); ++ dev_dbg(&pps->dev, "ktimer PPS source unregistered\n"); + + del_timer_sync(&ktimer); + pps_unregister_source(pps); +@@ -74,7 +74,7 @@ static int __init pps_ktimer_init(void) + timer_setup(&ktimer, pps_ktimer_event, 0); + mod_timer(&ktimer, jiffies + HZ); + +- dev_info(pps->dev, "ktimer PPS source registered\n"); ++ dev_dbg(&pps->dev, "ktimer PPS source registered\n"); + + return 0; + } +--- a/drivers/pps/clients/pps-ldisc.c ++++ b/drivers/pps/clients/pps-ldisc.c +@@ -32,7 +32,7 @@ static void pps_tty_dcd_change(struct tt + pps_event(pps, &ts, active ? PPS_CAPTUREASSERT : + PPS_CAPTURECLEAR, NULL); + +- dev_dbg(pps->dev, "PPS %s at %lu\n", ++ dev_dbg(&pps->dev, "PPS %s at %lu\n", + active ? "assert" : "clear", jiffies); + } + +@@ -69,7 +69,7 @@ static int pps_tty_open(struct tty_struc + goto err_unregister; + } + +- dev_info(pps->dev, "source \"%s\" added\n", info.path); ++ dev_dbg(&pps->dev, "source \"%s\" added\n", info.path); + + return 0; + +@@ -89,7 +89,7 @@ static void pps_tty_close(struct tty_str + if (WARN_ON(!pps)) + return; + +- dev_info(pps->dev, "removed\n"); ++ dev_info(&pps->dev, "removed\n"); + pps_unregister_source(pps); + } + +--- a/drivers/pps/clients/pps_parport.c ++++ b/drivers/pps/clients/pps_parport.c +@@ -81,7 +81,7 @@ static void parport_irq(void *handle) + /* check the signal (no signal means the pulse is lost this time) */ + if (!signal_is_set(port)) { + local_irq_restore(flags); +- dev_err(dev->pps->dev, "lost the signal\n"); ++ dev_err(&dev->pps->dev, "lost the signal\n"); + goto out_assert; + } + +@@ -98,7 +98,7 @@ static void parport_irq(void *handle) + /* timeout */ + dev->cw_err++; + if (dev->cw_err >= CLEAR_WAIT_MAX_ERRORS) { +- dev_err(dev->pps->dev, "disabled clear edge capture after %d" ++ dev_err(&dev->pps->dev, "disabled clear edge capture after %d" + " timeouts\n", dev->cw_err); + dev->cw = 0; + dev->cw_err = 0; +--- a/drivers/pps/kapi.c ++++ b/drivers/pps/kapi.c +@@ -41,7 +41,7 @@ static void pps_add_offset(struct pps_kt + static void pps_echo_client_default(struct pps_device *pps, int event, + void *data) + { +- dev_info(pps->dev, "echo %s %s\n", ++ dev_info(&pps->dev, "echo %s %s\n", + event & PPS_CAPTUREASSERT ? "assert" : "", + event & PPS_CAPTURECLEAR ? "clear" : ""); + } +@@ -112,7 +112,7 @@ struct pps_device *pps_register_source(s + goto kfree_pps; + } + +- dev_info(pps->dev, "new PPS source %s\n", info->name); ++ dev_dbg(&pps->dev, "new PPS source %s\n", info->name); + + return pps; + +@@ -166,7 +166,7 @@ void pps_event(struct pps_device *pps, s + /* check event type */ + BUG_ON((event & (PPS_CAPTUREASSERT | PPS_CAPTURECLEAR)) == 0); + +- dev_dbg(pps->dev, "PPS event at %lld.%09ld\n", ++ dev_dbg(&pps->dev, "PPS event at %lld.%09ld\n", + (s64)ts->ts_real.tv_sec, ts->ts_real.tv_nsec); + + timespec_to_pps_ktime(&ts_real, ts->ts_real); +@@ -188,7 +188,7 @@ void pps_event(struct pps_device *pps, s + /* Save the time stamp */ + pps->assert_tu = ts_real; + pps->assert_sequence++; +- dev_dbg(pps->dev, "capture assert seq #%u\n", ++ dev_dbg(&pps->dev, "capture assert seq #%u\n", + pps->assert_sequence); + + captured = ~0; +@@ -202,7 +202,7 @@ void pps_event(struct pps_device *pps, s + /* Save the time stamp */ + pps->clear_tu = ts_real; + pps->clear_sequence++; +- dev_dbg(pps->dev, "capture clear seq #%u\n", ++ dev_dbg(&pps->dev, "capture clear seq #%u\n", + pps->clear_sequence); + + captured = ~0; +--- a/drivers/pps/kc.c ++++ b/drivers/pps/kc.c +@@ -43,11 +43,11 @@ int pps_kc_bind(struct pps_device *pps, + pps_kc_hardpps_mode = 0; + pps_kc_hardpps_dev = NULL; + spin_unlock_irq(&pps_kc_hardpps_lock); +- dev_info(pps->dev, "unbound kernel" ++ dev_info(&pps->dev, "unbound kernel" + " consumer\n"); + } else { + spin_unlock_irq(&pps_kc_hardpps_lock); +- dev_err(pps->dev, "selected kernel consumer" ++ dev_err(&pps->dev, "selected kernel consumer" + " is not bound\n"); + return -EINVAL; + } +@@ -57,11 +57,11 @@ int pps_kc_bind(struct pps_device *pps, + pps_kc_hardpps_mode = bind_args->edge; + pps_kc_hardpps_dev = pps; + spin_unlock_irq(&pps_kc_hardpps_lock); +- dev_info(pps->dev, "bound kernel consumer: " ++ dev_info(&pps->dev, "bound kernel consumer: " + "edge=0x%x\n", bind_args->edge); + } else { + spin_unlock_irq(&pps_kc_hardpps_lock); +- dev_err(pps->dev, "another kernel consumer" ++ dev_err(&pps->dev, "another kernel consumer" + " is already bound\n"); + return -EINVAL; + } +@@ -83,7 +83,7 @@ void pps_kc_remove(struct pps_device *pp + pps_kc_hardpps_mode = 0; + pps_kc_hardpps_dev = NULL; + spin_unlock_irq(&pps_kc_hardpps_lock); +- dev_info(pps->dev, "unbound kernel consumer" ++ dev_info(&pps->dev, "unbound kernel consumer" + " on device removal\n"); + } else + spin_unlock_irq(&pps_kc_hardpps_lock); +--- a/drivers/pps/pps.c ++++ b/drivers/pps/pps.c +@@ -25,7 +25,7 @@ + * Local variables + */ + +-static dev_t pps_devt; ++static int pps_major; + static struct class *pps_class; + + static DEFINE_MUTEX(pps_idr_lock); +@@ -62,7 +62,7 @@ static int pps_cdev_pps_fetch(struct pps + else { + unsigned long ticks; + +- dev_dbg(pps->dev, "timeout %lld.%09d\n", ++ dev_dbg(&pps->dev, "timeout %lld.%09d\n", + (long long) fdata->timeout.sec, + fdata->timeout.nsec); + ticks = fdata->timeout.sec * HZ; +@@ -80,7 +80,7 @@ static int pps_cdev_pps_fetch(struct pps + + /* Check for pending signals */ + if (err == -ERESTARTSYS) { +- dev_dbg(pps->dev, "pending signal caught\n"); ++ dev_dbg(&pps->dev, "pending signal caught\n"); + return -EINTR; + } + +@@ -98,7 +98,7 @@ static long pps_cdev_ioctl(struct file * + + switch (cmd) { + case PPS_GETPARAMS: +- dev_dbg(pps->dev, "PPS_GETPARAMS\n"); ++ dev_dbg(&pps->dev, "PPS_GETPARAMS\n"); + + spin_lock_irq(&pps->lock); + +@@ -114,7 +114,7 @@ static long pps_cdev_ioctl(struct file * + break; + + case PPS_SETPARAMS: +- dev_dbg(pps->dev, "PPS_SETPARAMS\n"); ++ dev_dbg(&pps->dev, "PPS_SETPARAMS\n"); + + /* Check the capabilities */ + if (!capable(CAP_SYS_TIME)) +@@ -124,14 +124,14 @@ static long pps_cdev_ioctl(struct file * + if (err) + return -EFAULT; + if (!(params.mode & (PPS_CAPTUREASSERT | PPS_CAPTURECLEAR))) { +- dev_dbg(pps->dev, "capture mode unspecified (%x)\n", ++ dev_dbg(&pps->dev, "capture mode unspecified (%x)\n", + params.mode); + return -EINVAL; + } + + /* Check for supported capabilities */ + if ((params.mode & ~pps->info.mode) != 0) { +- dev_dbg(pps->dev, "unsupported capabilities (%x)\n", ++ dev_dbg(&pps->dev, "unsupported capabilities (%x)\n", + params.mode); + return -EINVAL; + } +@@ -144,7 +144,7 @@ static long pps_cdev_ioctl(struct file * + /* Restore the read only parameters */ + if ((params.mode & (PPS_TSFMT_TSPEC | PPS_TSFMT_NTPFP)) == 0) { + /* section 3.3 of RFC 2783 interpreted */ +- dev_dbg(pps->dev, "time format unspecified (%x)\n", ++ dev_dbg(&pps->dev, "time format unspecified (%x)\n", + params.mode); + pps->params.mode |= PPS_TSFMT_TSPEC; + } +@@ -165,7 +165,7 @@ static long pps_cdev_ioctl(struct file * + break; + + case PPS_GETCAP: +- dev_dbg(pps->dev, "PPS_GETCAP\n"); ++ dev_dbg(&pps->dev, "PPS_GETCAP\n"); + + err = put_user(pps->info.mode, iuarg); + if (err) +@@ -176,7 +176,7 @@ static long pps_cdev_ioctl(struct file * + case PPS_FETCH: { + struct pps_fdata fdata; + +- dev_dbg(pps->dev, "PPS_FETCH\n"); ++ dev_dbg(&pps->dev, "PPS_FETCH\n"); + + err = copy_from_user(&fdata, uarg, sizeof(struct pps_fdata)); + if (err) +@@ -206,7 +206,7 @@ static long pps_cdev_ioctl(struct file * + case PPS_KC_BIND: { + struct pps_bind_args bind_args; + +- dev_dbg(pps->dev, "PPS_KC_BIND\n"); ++ dev_dbg(&pps->dev, "PPS_KC_BIND\n"); + + /* Check the capabilities */ + if (!capable(CAP_SYS_TIME)) +@@ -218,7 +218,7 @@ static long pps_cdev_ioctl(struct file * + + /* Check for supported capabilities */ + if ((bind_args.edge & ~pps->info.mode) != 0) { +- dev_err(pps->dev, "unsupported capabilities (%x)\n", ++ dev_err(&pps->dev, "unsupported capabilities (%x)\n", + bind_args.edge); + return -EINVAL; + } +@@ -227,7 +227,7 @@ static long pps_cdev_ioctl(struct file * + if (bind_args.tsformat != PPS_TSFMT_TSPEC || + (bind_args.edge & ~PPS_CAPTUREBOTH) != 0 || + bind_args.consumer != PPS_KC_HARDPPS) { +- dev_err(pps->dev, "invalid kernel consumer bind" ++ dev_err(&pps->dev, "invalid kernel consumer bind" + " parameters (%x)\n", bind_args.edge); + return -EINVAL; + } +@@ -259,7 +259,7 @@ static long pps_cdev_compat_ioctl(struct + struct pps_fdata fdata; + int err; + +- dev_dbg(pps->dev, "PPS_FETCH\n"); ++ dev_dbg(&pps->dev, "PPS_FETCH\n"); + + err = copy_from_user(&compat, uarg, sizeof(struct pps_fdata_compat)); + if (err) +@@ -296,20 +296,36 @@ static long pps_cdev_compat_ioctl(struct + #define pps_cdev_compat_ioctl NULL + #endif + ++static struct pps_device *pps_idr_get(unsigned long id) ++{ ++ struct pps_device *pps; ++ ++ mutex_lock(&pps_idr_lock); ++ pps = idr_find(&pps_idr, id); ++ if (pps) ++ get_device(&pps->dev); ++ ++ mutex_unlock(&pps_idr_lock); ++ return pps; ++} ++ + static int pps_cdev_open(struct inode *inode, struct file *file) + { +- struct pps_device *pps = container_of(inode->i_cdev, +- struct pps_device, cdev); ++ struct pps_device *pps = pps_idr_get(iminor(inode)); ++ ++ if (!pps) ++ return -ENODEV; ++ + file->private_data = pps; +- kobject_get(&pps->dev->kobj); + return 0; + } + + static int pps_cdev_release(struct inode *inode, struct file *file) + { +- struct pps_device *pps = container_of(inode->i_cdev, +- struct pps_device, cdev); +- kobject_put(&pps->dev->kobj); ++ struct pps_device *pps = file->private_data; ++ ++ WARN_ON(pps->id != iminor(inode)); ++ put_device(&pps->dev); + return 0; + } + +@@ -331,22 +347,13 @@ static void pps_device_destruct(struct d + { + struct pps_device *pps = dev_get_drvdata(dev); + +- cdev_del(&pps->cdev); +- +- /* Now we can release the ID for re-use */ + pr_debug("deallocating pps%d\n", pps->id); +- mutex_lock(&pps_idr_lock); +- idr_remove(&pps_idr, pps->id); +- mutex_unlock(&pps_idr_lock); +- +- kfree(dev); + kfree(pps); + } + + int pps_register_cdev(struct pps_device *pps) + { + int err; +- dev_t devt; + + mutex_lock(&pps_idr_lock); + /* +@@ -363,40 +370,29 @@ int pps_register_cdev(struct pps_device + goto out_unlock; + } + pps->id = err; +- mutex_unlock(&pps_idr_lock); +- +- devt = MKDEV(MAJOR(pps_devt), pps->id); +- +- cdev_init(&pps->cdev, &pps_cdev_fops); +- pps->cdev.owner = pps->info.owner; + +- err = cdev_add(&pps->cdev, devt, 1); +- if (err) { +- pr_err("%s: failed to add char device %d:%d\n", +- pps->info.name, MAJOR(pps_devt), pps->id); ++ pps->dev.class = pps_class; ++ pps->dev.parent = pps->info.dev; ++ pps->dev.devt = MKDEV(pps_major, pps->id); ++ dev_set_drvdata(&pps->dev, pps); ++ dev_set_name(&pps->dev, "pps%d", pps->id); ++ err = device_register(&pps->dev); ++ if (err) + goto free_idr; +- } +- pps->dev = device_create(pps_class, pps->info.dev, devt, pps, +- "pps%d", pps->id); +- if (IS_ERR(pps->dev)) { +- err = PTR_ERR(pps->dev); +- goto del_cdev; +- } + + /* Override the release function with our own */ +- pps->dev->release = pps_device_destruct; ++ pps->dev.release = pps_device_destruct; + +- pr_debug("source %s got cdev (%d:%d)\n", pps->info.name, +- MAJOR(pps_devt), pps->id); ++ pr_debug("source %s got cdev (%d:%d)\n", pps->info.name, pps_major, ++ pps->id); + ++ get_device(&pps->dev); ++ mutex_unlock(&pps_idr_lock); + return 0; + +-del_cdev: +- cdev_del(&pps->cdev); +- + free_idr: +- mutex_lock(&pps_idr_lock); + idr_remove(&pps_idr, pps->id); ++ put_device(&pps->dev); + out_unlock: + mutex_unlock(&pps_idr_lock); + return err; +@@ -406,7 +402,13 @@ void pps_unregister_cdev(struct pps_devi + { + pr_debug("unregistering pps%d\n", pps->id); + pps->lookup_cookie = NULL; +- device_destroy(pps_class, pps->dev->devt); ++ device_destroy(pps_class, pps->dev.devt); ++ ++ /* Now we can release the ID for re-use */ ++ mutex_lock(&pps_idr_lock); ++ idr_remove(&pps_idr, pps->id); ++ put_device(&pps->dev); ++ mutex_unlock(&pps_idr_lock); + } + + /* +@@ -426,6 +428,11 @@ void pps_unregister_cdev(struct pps_devi + * so that it will not be used again, even if the pps device cannot + * be removed from the idr due to pending references holding the minor + * number in use. ++ * ++ * Since pps_idr holds a reference to the device, the returned ++ * pps_device is guaranteed to be valid until pps_unregister_cdev() is ++ * called on it. But after calling pps_unregister_cdev(), it may be ++ * freed at any time. + */ + struct pps_device *pps_lookup_dev(void const *cookie) + { +@@ -448,13 +455,11 @@ EXPORT_SYMBOL(pps_lookup_dev); + static void __exit pps_exit(void) + { + class_destroy(pps_class); +- unregister_chrdev_region(pps_devt, PPS_MAX_SOURCES); ++ __unregister_chrdev(pps_major, 0, PPS_MAX_SOURCES, "pps"); + } + + static int __init pps_init(void) + { +- int err; +- + pps_class = class_create("pps"); + if (IS_ERR(pps_class)) { + pr_err("failed to allocate class\n"); +@@ -462,8 +467,9 @@ static int __init pps_init(void) + } + pps_class->dev_groups = pps_groups; + +- err = alloc_chrdev_region(&pps_devt, 0, PPS_MAX_SOURCES, "pps"); +- if (err < 0) { ++ pps_major = __register_chrdev(0, 0, PPS_MAX_SOURCES, "pps", ++ &pps_cdev_fops); ++ if (pps_major < 0) { + pr_err("failed to allocate char device region\n"); + goto remove_class; + } +@@ -476,8 +482,7 @@ static int __init pps_init(void) + + remove_class: + class_destroy(pps_class); +- +- return err; ++ return pps_major; + } + + subsys_initcall(pps_init); +--- a/drivers/ptp/ptp_ocp.c ++++ b/drivers/ptp/ptp_ocp.c +@@ -4420,7 +4420,7 @@ ptp_ocp_complete(struct ptp_ocp *bp) + + pps = pps_lookup_dev(bp->ptp); + if (pps) +- ptp_ocp_symlink(bp, pps->dev, "pps"); ++ ptp_ocp_symlink(bp, &pps->dev, "pps"); + + ptp_ocp_debugfs_add_device(bp); + +--- a/include/linux/pps_kernel.h ++++ b/include/linux/pps_kernel.h +@@ -56,8 +56,7 @@ struct pps_device { + + unsigned int id; /* PPS source unique ID */ + void const *lookup_cookie; /* For pps_lookup_dev() only */ +- struct cdev cdev; +- struct device *dev; ++ struct device dev; + struct fasync_struct *async_queue; /* fasync method */ + spinlock_t lock; + }; diff --git a/queue-6.12/rdma-mlx5-fix-implicit-odp-use-after-free.patch b/queue-6.12/rdma-mlx5-fix-implicit-odp-use-after-free.patch new file mode 100644 index 0000000000..ea55dcba7d --- /dev/null +++ b/queue-6.12/rdma-mlx5-fix-implicit-odp-use-after-free.patch @@ -0,0 +1,115 @@ +From d3d930411ce390e532470194296658a960887773 Mon Sep 17 00:00:00 2001 +From: Patrisious Haddad +Date: Sun, 19 Jan 2025 10:21:41 +0200 +Subject: RDMA/mlx5: Fix implicit ODP use after free + +From: Patrisious Haddad + +commit d3d930411ce390e532470194296658a960887773 upstream. + +Prevent double queueing of implicit ODP mr destroy work by using +__xa_cmpxchg() to make sure this is the only time we are destroying this +specific mr. + +Without this change, we could try to invalidate this mr twice, which in +turn could result in queuing a MR work destroy twice, and eventually the +second work could execute after the MR was freed due to the first work, +causing a user after free and trace below. + + refcount_t: underflow; use-after-free. + WARNING: CPU: 2 PID: 12178 at lib/refcount.c:28 refcount_warn_saturate+0x12b/0x130 + Modules linked in: bonding ib_ipoib vfio_pci ip_gre geneve nf_tables ip6_gre gre ip6_tunnel tunnel6 ipip tunnel4 ib_umad rdma_ucm mlx5_vfio_pci vfio_pci_core vfio_iommu_type1 mlx5_ib vfio ib_uverbs mlx5_core iptable_raw openvswitch nsh rpcrdma ib_iser libiscsi scsi_transport_iscsi rdma_cm iw_cm ib_cm ib_core xt_conntrack xt_MASQUERADE nf_conntrack_netlink nfnetlink xt_addrtype iptable_nat nf_nat br_netfilter rpcsec_gss_krb5 auth_rpcgss oid_registry overlay zram zsmalloc fuse [last unloaded: ib_uverbs] + CPU: 2 PID: 12178 Comm: kworker/u20:5 Not tainted 6.5.0-rc1_net_next_mlx5_58c644e #1 + Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS rel-1.13.0-0-gf21b5a4aeb02-prebuilt.qemu.org 04/01/2014 + Workqueue: events_unbound free_implicit_child_mr_work [mlx5_ib] + RIP: 0010:refcount_warn_saturate+0x12b/0x130 + Code: 48 c7 c7 38 95 2a 82 c6 05 bc c6 fe 00 01 e8 0c 66 aa ff 0f 0b 5b c3 48 c7 c7 e0 94 2a 82 c6 05 a7 c6 fe 00 01 e8 f5 65 aa ff <0f> 0b 5b c3 90 8b 07 3d 00 00 00 c0 74 12 83 f8 01 74 13 8d 50 ff + RSP: 0018:ffff8881008e3e40 EFLAGS: 00010286 + RAX: 0000000000000000 RBX: 0000000000000000 RCX: 0000000000000027 + RDX: ffff88852c91b5c8 RSI: 0000000000000001 RDI: ffff88852c91b5c0 + RBP: ffff8881dacd4e00 R08: 00000000ffffffff R09: 0000000000000019 + R10: 000000000000072e R11: 0000000063666572 R12: ffff88812bfd9e00 + R13: ffff8881c792d200 R14: ffff88810011c005 R15: ffff8881002099c0 + FS: 0000000000000000(0000) GS:ffff88852c900000(0000) knlGS:0000000000000000 + CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 + CR2: 00007f5694b5e000 CR3: 00000001153f6003 CR4: 0000000000370ea0 + DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 + DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 + Call Trace: + + ? refcount_warn_saturate+0x12b/0x130 + free_implicit_child_mr_work+0x180/0x1b0 [mlx5_ib] + process_one_work+0x1cc/0x3c0 + worker_thread+0x218/0x3c0 + kthread+0xc6/0xf0 + ret_from_fork+0x1f/0x30 + + +Fixes: 5256edcb98a1 ("RDMA/mlx5: Rework implicit ODP destroy") +Cc: stable@vger.kernel.org +Link: https://patch.msgid.link/r/c96b8645a81085abff739e6b06e286a350d1283d.1737274283.git.leon@kernel.org +Signed-off-by: Patrisious Haddad +Signed-off-by: Leon Romanovsky +Signed-off-by: Jason Gunthorpe +Signed-off-by: Greg Kroah-Hartman +--- + drivers/infiniband/hw/mlx5/odp.c | 30 ++++++++++++++++++++++-------- + 1 file changed, 22 insertions(+), 8 deletions(-) + +--- a/drivers/infiniband/hw/mlx5/odp.c ++++ b/drivers/infiniband/hw/mlx5/odp.c +@@ -228,13 +228,27 @@ static void destroy_unused_implicit_chil + unsigned long idx = ib_umem_start(odp) >> MLX5_IMR_MTT_SHIFT; + struct mlx5_ib_mr *imr = mr->parent; + ++ /* ++ * If userspace is racing freeing the parent implicit ODP MR then we can ++ * loose the race with parent destruction. In this case ++ * mlx5_ib_free_odp_mr() will free everything in the implicit_children ++ * xarray so NOP is fine. This child MR cannot be destroyed here because ++ * we are under its umem_mutex. ++ */ + if (!refcount_inc_not_zero(&imr->mmkey.usecount)) + return; + +- xa_erase(&imr->implicit_children, idx); ++ xa_lock(&imr->implicit_children); ++ if (__xa_cmpxchg(&imr->implicit_children, idx, mr, NULL, GFP_KERNEL) != ++ mr) { ++ xa_unlock(&imr->implicit_children); ++ return; ++ } ++ + if (MLX5_CAP_ODP(mr_to_mdev(mr)->mdev, mem_page_fault)) +- xa_erase(&mr_to_mdev(mr)->odp_mkeys, +- mlx5_base_mkey(mr->mmkey.key)); ++ __xa_erase(&mr_to_mdev(mr)->odp_mkeys, ++ mlx5_base_mkey(mr->mmkey.key)); ++ xa_unlock(&imr->implicit_children); + + /* Freeing a MR is a sleeping operation, so bounce to a work queue */ + INIT_WORK(&mr->odp_destroy.work, free_implicit_child_mr_work); +@@ -500,18 +514,18 @@ static struct mlx5_ib_mr *implicit_get_c + refcount_inc(&ret->mmkey.usecount); + goto out_lock; + } +- xa_unlock(&imr->implicit_children); + + if (MLX5_CAP_ODP(dev->mdev, mem_page_fault)) { +- ret = xa_store(&dev->odp_mkeys, mlx5_base_mkey(mr->mmkey.key), +- &mr->mmkey, GFP_KERNEL); ++ ret = __xa_store(&dev->odp_mkeys, mlx5_base_mkey(mr->mmkey.key), ++ &mr->mmkey, GFP_KERNEL); + if (xa_is_err(ret)) { + ret = ERR_PTR(xa_err(ret)); +- xa_erase(&imr->implicit_children, idx); +- goto out_mr; ++ __xa_erase(&imr->implicit_children, idx); ++ goto out_lock; + } + mr->mmkey.type = MLX5_MKEY_IMPLICIT_CHILD; + } ++ xa_unlock(&imr->implicit_children); + mlx5_ib_dbg(mr_to_mdev(imr), "key %x mr %p\n", mr->mmkey.key, mr); + return mr; + diff --git a/queue-6.12/remoteproc-core-fix-ida_free-call-while-not-allocated.patch b/queue-6.12/remoteproc-core-fix-ida_free-call-while-not-allocated.patch new file mode 100644 index 0000000000..8443d720f7 --- /dev/null +++ b/queue-6.12/remoteproc-core-fix-ida_free-call-while-not-allocated.patch @@ -0,0 +1,81 @@ +From 7378aeb664e5ebc396950b36a1f2dedf5aabec20 Mon Sep 17 00:00:00 2001 +From: Arnaud Pouliquen +Date: Fri, 22 Nov 2024 18:51:27 +0100 +Subject: remoteproc: core: Fix ida_free call while not allocated + +From: Arnaud Pouliquen + +commit 7378aeb664e5ebc396950b36a1f2dedf5aabec20 upstream. + +In the rproc_alloc() function, on error, put_device(&rproc->dev) is +called, leading to the call of the rproc_type_release() function. +An error can occurs before ida_alloc is called. + +In such case in rproc_type_release(), the condition (rproc->index >= 0) is +true as rproc->index has been initialized to 0. +ida_free() is called reporting a warning: +[ 4.181906] WARNING: CPU: 1 PID: 24 at lib/idr.c:525 ida_free+0x100/0x164 +[ 4.186378] stm32-display-dsi 5a000000.dsi: Fixed dependency cycle(s) with /soc/dsi@5a000000/panel@0 +[ 4.188854] ida_free called for id=0 which is not allocated. +[ 4.198256] mipi-dsi 5a000000.dsi.0: Fixed dependency cycle(s) with /soc/dsi@5a000000 +[ 4.203556] Modules linked in: panel_orisetech_otm8009a dw_mipi_dsi_stm(+) gpu_sched dw_mipi_dsi stm32_rproc stm32_crc32 stm32_ipcc(+) optee(+) +[ 4.224307] CPU: 1 UID: 0 PID: 24 Comm: kworker/u10:0 Not tainted 6.12.0 #442 +[ 4.231481] Hardware name: STM32 (Device Tree Support) +[ 4.236627] Workqueue: events_unbound deferred_probe_work_func +[ 4.242504] Call trace: +[ 4.242522] unwind_backtrace from show_stack+0x10/0x14 +[ 4.250218] show_stack from dump_stack_lvl+0x50/0x64 +[ 4.255274] dump_stack_lvl from __warn+0x80/0x12c +[ 4.260134] __warn from warn_slowpath_fmt+0x114/0x188 +[ 4.265199] warn_slowpath_fmt from ida_free+0x100/0x164 +[ 4.270565] ida_free from rproc_type_release+0x38/0x60 +[ 4.275832] rproc_type_release from device_release+0x30/0xa0 +[ 4.281601] device_release from kobject_put+0xc4/0x294 +[ 4.286762] kobject_put from rproc_alloc.part.0+0x208/0x28c +[ 4.292430] rproc_alloc.part.0 from devm_rproc_alloc+0x80/0xc4 +[ 4.298393] devm_rproc_alloc from stm32_rproc_probe+0xd0/0x844 [stm32_rproc] +[ 4.305575] stm32_rproc_probe [stm32_rproc] from platform_probe+0x5c/0xbc + +Calling ida_alloc earlier in rproc_alloc ensures that the rproc->index is +properly set. + +Fixes: 08333b911f01 ("remoteproc: Directly use ida_alloc()/free()") +Signed-off-by: Arnaud Pouliquen +Cc: stable@vger.kernel.org +Link: https://lore.kernel.org/r/20241122175127.2188037-1-arnaud.pouliquen@foss.st.com +Signed-off-by: Mathieu Poirier +Signed-off-by: Greg Kroah-Hartman +--- + drivers/remoteproc/remoteproc_core.c | 14 +++++++------- + 1 file changed, 7 insertions(+), 7 deletions(-) + +--- a/drivers/remoteproc/remoteproc_core.c ++++ b/drivers/remoteproc/remoteproc_core.c +@@ -2486,6 +2486,13 @@ struct rproc *rproc_alloc(struct device + rproc->dev.driver_data = rproc; + idr_init(&rproc->notifyids); + ++ /* Assign a unique device index and name */ ++ rproc->index = ida_alloc(&rproc_dev_index, GFP_KERNEL); ++ if (rproc->index < 0) { ++ dev_err(dev, "ida_alloc failed: %d\n", rproc->index); ++ goto put_device; ++ } ++ + rproc->name = kstrdup_const(name, GFP_KERNEL); + if (!rproc->name) + goto put_device; +@@ -2496,13 +2503,6 @@ struct rproc *rproc_alloc(struct device + if (rproc_alloc_ops(rproc, ops)) + goto put_device; + +- /* Assign a unique device index and name */ +- rproc->index = ida_alloc(&rproc_dev_index, GFP_KERNEL); +- if (rproc->index < 0) { +- dev_err(dev, "ida_alloc failed: %d\n", rproc->index); +- goto put_device; +- } +- + dev_set_name(&rproc->dev, "remoteproc%d", rproc->index); + + atomic_set(&rproc->power, 0); diff --git a/queue-6.12/series b/queue-6.12/series index 2ec4b644dd..ca35d6dc9c 100644 --- a/queue-6.12/series +++ b/queue-6.12/series @@ -559,3 +559,17 @@ usb-dwc3-skip-resume-if-pm_runtime_set_active-fails.patch usb-typec-tcpm-set-src_send_capabilities-timeout-to-pd_t_sender_response.patch usb-typec-tcpci-prevent-sink-disconnection-before-vppsshutdown-in-spr-pps.patch clk-qcom-gcc-x1e80100-do-not-turn-off-usb_2-controller-gdsc.patch +mptcp-consolidate-suboption-status.patch +mptcp-pm-only-set-fullmesh-for-subflow-endp.patch +mptcp-handle-fastopen-disconnect-correctly.patch +mptcp-blackhole-only-if-1st-syn-retrans-w-o-mpc-is-accepted.patch +rdma-mlx5-fix-implicit-odp-use-after-free.patch +remoteproc-core-fix-ida_free-call-while-not-allocated.patch +media-uvcvideo-fix-double-free-in-error-path.patch +pps-fix-a-use-after-free.patch +usb-gadget-f_tcm-don-t-free-command-immediately.patch +staging-media-max96712-fix-kernel-oops-when-removing-module.patch +media-imx-jpeg-fix-potential-error-pointer-dereference-in-detach_pm.patch +powerpc-pseries-iommu-don-t-unset-window-if-it-was-never-set.patch +md-md-bitmap-synchronize-bitmap_get_stats-with-bitmap-lifetime.patch +btrfs-output-the-reason-for-open_ctree-failure.patch diff --git a/queue-6.12/staging-media-max96712-fix-kernel-oops-when-removing-module.patch b/queue-6.12/staging-media-max96712-fix-kernel-oops-when-removing-module.patch new file mode 100644 index 0000000000..139146356e --- /dev/null +++ b/queue-6.12/staging-media-max96712-fix-kernel-oops-when-removing-module.patch @@ -0,0 +1,113 @@ +From ee1b5046d5cd892a0754ab982aeaaad3702083a5 Mon Sep 17 00:00:00 2001 +From: Laurentiu Palcu +Date: Tue, 17 Dec 2024 08:51:50 +0200 +Subject: staging: media: max96712: fix kernel oops when removing module +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Laurentiu Palcu + +commit ee1b5046d5cd892a0754ab982aeaaad3702083a5 upstream. + +The following kernel oops is thrown when trying to remove the max96712 +module: + +Unable to handle kernel paging request at virtual address 00007375746174db +Mem abort info: + ESR = 0x0000000096000004 + EC = 0x25: DABT (current EL), IL = 32 bits + SET = 0, FnV = 0 + EA = 0, S1PTW = 0 + FSC = 0x04: level 0 translation fault +Data abort info: + ISV = 0, ISS = 0x00000004, ISS2 = 0x00000000 + CM = 0, WnR = 0, TnD = 0, TagAccess = 0 + GCS = 0, Overlay = 0, DirtyBit = 0, Xs = 0 +user pgtable: 4k pages, 48-bit VAs, pgdp=000000010af89000 +[00007375746174db] pgd=0000000000000000, p4d=0000000000000000 +Internal error: Oops: 0000000096000004 [#1] PREEMPT SMP +Modules linked in: crct10dif_ce polyval_ce mxc_jpeg_encdec flexcan + snd_soc_fsl_sai snd_soc_fsl_asoc_card snd_soc_fsl_micfil dwc_mipi_csi2 + imx_csi_formatter polyval_generic v4l2_jpeg imx_pcm_dma can_dev + snd_soc_imx_audmux snd_soc_wm8962 snd_soc_imx_card snd_soc_fsl_utils + max96712(C-) rpmsg_ctrl rpmsg_char pwm_fan fuse + [last unloaded: imx8_isi] +CPU: 0 UID: 0 PID: 754 Comm: rmmod + Tainted: G C 6.12.0-rc6-06364-g327fec852c31 #17 +Tainted: [C]=CRAP +Hardware name: NXP i.MX95 19X19 board (DT) +pstate: 60400009 (nZCv daif +PAN -UAO -TCO -DIT -SSBS BTYPE=--) +pc : led_put+0x1c/0x40 +lr : v4l2_subdev_put_privacy_led+0x48/0x58 +sp : ffff80008699bbb0 +x29: ffff80008699bbb0 x28: ffff00008ac233c0 x27: 0000000000000000 +x26: 0000000000000000 x25: 0000000000000000 x24: 0000000000000000 +x23: ffff000080cf1170 x22: ffff00008b53bd00 x21: ffff8000822ad1c8 +x20: ffff000080ff5c00 x19: ffff00008b53be40 x18: 0000000000000000 +x17: 0000000000000000 x16: 0000000000000000 x15: 0000000000000000 +x14: 0000000000000004 x13: ffff0000800f8010 x12: 0000000000000000 +x11: ffff000082acf5c0 x10: ffff000082acf478 x9 : ffff0000800f8010 +x8 : 0101010101010101 x7 : 7f7f7f7f7f7f7f7f x6 : fefefeff6364626d +x5 : 8080808000000000 x4 : 0000000000000020 x3 : 00000000553a3dc1 +x2 : ffff00008ac233c0 x1 : ffff00008ac233c0 x0 : ff00737574617473 +Call trace: + led_put+0x1c/0x40 + v4l2_subdev_put_privacy_led+0x48/0x58 + v4l2_async_unregister_subdev+0x2c/0x1a4 + max96712_remove+0x1c/0x38 [max96712] + i2c_device_remove+0x2c/0x9c + device_remove+0x4c/0x80 + device_release_driver_internal+0x1cc/0x228 + driver_detach+0x4c/0x98 + bus_remove_driver+0x6c/0xbc + driver_unregister+0x30/0x60 + i2c_del_driver+0x54/0x64 + max96712_i2c_driver_exit+0x18/0x1d0 [max96712] + __arm64_sys_delete_module+0x1a4/0x290 + invoke_syscall+0x48/0x10c + el0_svc_common.constprop.0+0xc0/0xe0 + do_el0_svc+0x1c/0x28 + el0_svc+0x34/0xd8 + el0t_64_sync_handler+0x120/0x12c + el0t_64_sync+0x190/0x194 +Code: f9000bf3 aa0003f3 f9402800 f9402000 (f9403400) +---[ end trace 0000000000000000 ]--- + +This happens because in v4l2_i2c_subdev_init(), the i2c_set_cliendata() +is called again and the data is overwritten to point to sd, instead of +priv. So, in remove(), the wrong pointer is passed to +v4l2_async_unregister_subdev(), leading to a crash. + +Fixes: 5814f32fef13 ("media: staging: max96712: Add basic support for MAX96712 GMSL2 deserializer") +Signed-off-by: Laurentiu Palcu +Cc: stable@vger.kernel.org +Reviewed-by: Niklas Söderlund +Reviewed-by: Ricardo Ribalda +Signed-off-by: Sakari Ailus +Signed-off-by: Mauro Carvalho Chehab +Signed-off-by: Greg Kroah-Hartman +--- + drivers/staging/media/max96712/max96712.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/drivers/staging/media/max96712/max96712.c ++++ b/drivers/staging/media/max96712/max96712.c +@@ -421,7 +421,6 @@ static int max96712_probe(struct i2c_cli + return -ENOMEM; + + priv->client = client; +- i2c_set_clientdata(client, priv); + + priv->regmap = devm_regmap_init_i2c(client, &max96712_i2c_regmap); + if (IS_ERR(priv->regmap)) +@@ -454,7 +453,8 @@ static int max96712_probe(struct i2c_cli + + static void max96712_remove(struct i2c_client *client) + { +- struct max96712_priv *priv = i2c_get_clientdata(client); ++ struct v4l2_subdev *sd = i2c_get_clientdata(client); ++ struct max96712_priv *priv = container_of(sd, struct max96712_priv, sd); + + v4l2_async_unregister_subdev(&priv->sd); + diff --git a/queue-6.12/usb-gadget-f_tcm-don-t-free-command-immediately.patch b/queue-6.12/usb-gadget-f_tcm-don-t-free-command-immediately.patch new file mode 100644 index 0000000000..c6e95575eb --- /dev/null +++ b/queue-6.12/usb-gadget-f_tcm-don-t-free-command-immediately.patch @@ -0,0 +1,40 @@ +From c225d006a31949d673e646d585d9569bc28feeb9 Mon Sep 17 00:00:00 2001 +From: Thinh Nguyen +Date: Wed, 11 Dec 2024 00:31:36 +0000 +Subject: usb: gadget: f_tcm: Don't free command immediately + +From: Thinh Nguyen + +commit c225d006a31949d673e646d585d9569bc28feeb9 upstream. + +Don't prematurely free the command. Wait for the status completion of +the sense status. It can be freed then. Otherwise we will double-free +the command. + +Fixes: cff834c16d23 ("usb-gadget/tcm: Convert to TARGET_SCF_ACK_KREF I/O krefs") +Cc: stable@vger.kernel.org +Signed-off-by: Thinh Nguyen +Link: https://lore.kernel.org/r/ae919ac431f16275e05ec819bdffb3ac5f44cbe1.1733876548.git.Thinh.Nguyen@synopsys.com +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/gadget/function/f_tcm.c | 2 -- + 1 file changed, 2 deletions(-) + +--- a/drivers/usb/gadget/function/f_tcm.c ++++ b/drivers/usb/gadget/function/f_tcm.c +@@ -1066,7 +1066,6 @@ static void usbg_cmd_work(struct work_st + out: + transport_send_check_condition_and_sense(se_cmd, + TCM_UNSUPPORTED_SCSI_OPCODE, 1); +- transport_generic_free_cmd(&cmd->se_cmd, 0); + } + + static struct usbg_cmd *usbg_get_cmd(struct f_uas *fu, +@@ -1195,7 +1194,6 @@ static void bot_cmd_work(struct work_str + out: + transport_send_check_condition_and_sense(se_cmd, + TCM_UNSUPPORTED_SCSI_OPCODE, 1); +- transport_generic_free_cmd(&cmd->se_cmd, 0); + } + + static int bot_submit_command(struct f_uas *fu,