From: Sasha Levin Date: Wed, 8 Apr 2026 10:50:49 +0000 (-0400) Subject: Fixes for all trees X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=5bd1a325eca1fde5ca67146dcdc3cd0de430d076;p=thirdparty%2Fkernel%2Fstable-queue.git Fixes for all trees Signed-off-by: Sasha Levin --- diff --git a/queue-5.10/nvmet-tcp-fix-use-before-check-of-sg-in-bounds-valid.patch b/queue-5.10/nvmet-tcp-fix-use-before-check-of-sg-in-bounds-valid.patch new file mode 100644 index 0000000000..52823e72c2 --- /dev/null +++ b/queue-5.10/nvmet-tcp-fix-use-before-check-of-sg-in-bounds-valid.patch @@ -0,0 +1,75 @@ +From 00ff96f03c38fe8c2e1ce1e458ec3340918a6b8d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 5 Apr 2026 00:23:44 +0300 +Subject: nvmet-tcp: fix use-before-check of sg in bounds validation + +From: Cengiz Can + +The stable backport of commit 52a0a9854934 ("nvmet-tcp: add bounds +checks in nvmet_tcp_build_pdu_iovec") placed the bounds checks after +the iov_len calculation: + + while (length) { + u32 iov_len = min_t(u32, length, sg->length - sg_offset); + + if (!sg_remaining) { /* too late: sg already dereferenced */ + +In mainline, the checks come first because C99 allows mid-block variable +declarations. The stable backport moved the declaration to the top of the +loop to satisfy C89 declaration rules, but this ended up placing the +sg->length dereference before the sg_remaining and sg->length guards. + +If sg_next() returns NULL at the end of the scatterlist, the next +iteration dereferences a NULL pointer in the iov_len calculation before +the sg_remaining check can prevent it. + +Fix this by moving the iov_len declaration to function scope and +keeping the assignment after the bounds checks, matching the ordering +in mainline. + +Fixes: 043b4307a99f ("nvmet-tcp: add bounds checks in nvmet_tcp_build_pdu_iovec") +Cc: stable@vger.kernel.org +Cc: YunJe Shin +Cc: Sagi Grimberg +Cc: Keith Busch +Cc: linux-nvme@lists.infradead.org +Signed-off-by: Cengiz Can +Signed-off-by: Sasha Levin +--- + drivers/nvme/target/tcp.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/drivers/nvme/target/tcp.c b/drivers/nvme/target/tcp.c +index 5d8e57e5fdb18..6db9dcdbb3c34 100644 +--- a/drivers/nvme/target/tcp.c ++++ b/drivers/nvme/target/tcp.c +@@ -300,7 +300,7 @@ static void nvmet_tcp_build_pdu_iovec(struct nvmet_tcp_cmd *cmd) + { + struct bio_vec *iov = cmd->iov; + struct scatterlist *sg; +- u32 length, offset, sg_offset; ++ u32 length, offset, sg_offset, iov_len; + unsigned int sg_remaining; + int nr_pages; + +@@ -317,8 +317,6 @@ static void nvmet_tcp_build_pdu_iovec(struct nvmet_tcp_cmd *cmd) + sg_remaining = cmd->req.sg_cnt - cmd->sg_idx; + + while (length) { +- u32 iov_len = min_t(u32, length, sg->length - sg_offset); +- + if (!sg_remaining) { + nvmet_tcp_fatal_error(cmd->queue); + return; +@@ -328,6 +326,8 @@ static void nvmet_tcp_build_pdu_iovec(struct nvmet_tcp_cmd *cmd) + return; + } + ++ iov_len = min_t(u32, length, sg->length - sg_offset); ++ + iov->bv_page = sg_page(sg); + iov->bv_len = iov_len; + iov->bv_offset = sg->offset + sg_offset; +-- +2.53.0 + diff --git a/queue-5.10/series b/queue-5.10/series index b55e1c9e8f..2eca946167 100644 --- a/queue-5.10/series +++ b/queue-5.10/series @@ -409,3 +409,4 @@ net-ftgmac100-fix-ring-allocation-unwind-on-open-failure.patch thunderbolt-fix-property-read-in-nhi_wake_supported.patch usb-dummy-hcd-fix-locking-synchronization-error.patch usb-gadget-dummy_hcd-fix-premature-urb-completion-when-zlp-follows-partial-transfer.patch +nvmet-tcp-fix-use-before-check-of-sg-in-bounds-valid.patch diff --git a/queue-5.15/can-gs_usb-gs_usb_receive_bulk_callback-fix-error-me.patch b/queue-5.15/can-gs_usb-gs_usb_receive_bulk_callback-fix-error-me.patch new file mode 100644 index 0000000000..0af80a0560 --- /dev/null +++ b/queue-5.15/can-gs_usb-gs_usb_receive_bulk_callback-fix-error-me.patch @@ -0,0 +1,53 @@ +From eb637770fe96fd9172c5927ea9bb6ec5b3118d6f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 3 Apr 2026 09:36:15 +0800 +Subject: can: gs_usb: gs_usb_receive_bulk_callback(): fix error message + +From: Marc Kleine-Budde + +[ Upstream commit 494fc029f662c331e06b7c2031deff3c64200eed ] + +Sinc commit 79a6d1bfe114 ("can: gs_usb: gs_usb_receive_bulk_callback(): +unanchor URL on usb_submit_urb() error") a failing resubmit URB will print +an info message. + +In the case of a short read where netdev has not yet been assigned, +initialize as NULL to avoid dereferencing an undefined value. Also report +the error value of the failed resubmit. + +Fixes: 79a6d1bfe114 ("can: gs_usb: gs_usb_receive_bulk_callback(): unanchor URL on usb_submit_urb() error") +Reported-by: Jakub Kicinski +Closes: https://lore.kernel.org/all/20260119181904.1209979-1-kuba@kernel.org/ +Link: https://patch.msgid.link/20260120-gs_usb-fix-error-message-v1-1-6be04de572bc@pengutronix.de +Signed-off-by: Marc Kleine-Budde +Signed-off-by: Ruohan Lan +Signed-off-by: Sasha Levin +--- + drivers/net/can/usb/gs_usb.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/net/can/usb/gs_usb.c b/drivers/net/can/usb/gs_usb.c +index 134f830508d9f..fd9a06850c950 100644 +--- a/drivers/net/can/usb/gs_usb.c ++++ b/drivers/net/can/usb/gs_usb.c +@@ -297,7 +297,7 @@ static void gs_usb_receive_bulk_callback(struct urb *urb) + { + struct gs_usb *usbcan = urb->context; + struct gs_can *dev; +- struct net_device *netdev; ++ struct net_device *netdev = NULL; + int rc; + struct net_device_stats *stats; + struct gs_host_frame *hf = urb->transfer_buffer; +@@ -419,7 +419,7 @@ static void gs_usb_receive_bulk_callback(struct urb *urb) + } + } else if (rc != -ESHUTDOWN && net_ratelimit()) { + netdev_info(netdev, "failed to re-submit IN URB: %pe\n", +- ERR_PTR(urb->status)); ++ ERR_PTR(rc)); + } + } + +-- +2.53.0 + diff --git a/queue-5.15/can-gs_usb-gs_usb_receive_bulk_callback-fix-urb-memo.patch b/queue-5.15/can-gs_usb-gs_usb_receive_bulk_callback-fix-urb-memo.patch new file mode 100644 index 0000000000..cf073bd045 --- /dev/null +++ b/queue-5.15/can-gs_usb-gs_usb_receive_bulk_callback-fix-urb-memo.patch @@ -0,0 +1,53 @@ +From 8cd221e7bc18c56a6da7d57e9c51c240f994ead9 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 3 Apr 2026 09:36:13 +0800 +Subject: can: gs_usb: gs_usb_receive_bulk_callback(): fix URB memory leak + +From: Marc Kleine-Budde + +[ Upstream commit 7352e1d5932a0e777e39fa4b619801191f57e603 ] + +In gs_can_open(), the URBs for USB-in transfers are allocated, added to the +parent->rx_submitted anchor and submitted. In the complete callback +gs_usb_receive_bulk_callback(), the URB is processed and resubmitted. In +gs_can_close() the URBs are freed by calling +usb_kill_anchored_urbs(parent->rx_submitted). + +However, this does not take into account that the USB framework unanchors +the URB before the complete function is called. This means that once an +in-URB has been completed, it is no longer anchored and is ultimately not +released in gs_can_close(). + +Fix the memory leak by anchoring the URB in the +gs_usb_receive_bulk_callback() to the parent->rx_submitted anchor. + +[ The variable usbcan was renamed to parent in +commit b6980ad3a90c ("can: gs_usb: uniformly use "parent" as variable name for struct gs_usb") +introduced in v6.6. To backport to v5.15, replace parent with usbcan. ] + +Fixes: d08e973a77d1 ("can: gs_usb: Added support for the GS_USB CAN devices") +Cc: stable@vger.kernel.org +Link: https://patch.msgid.link/20260105-gs_usb-fix-memory-leak-v2-1-cc6ed6438034@pengutronix.de +Signed-off-by: Marc Kleine-Budde +Signed-off-by: Ruohan Lan +Signed-off-by: Sasha Levin +--- + drivers/net/can/usb/gs_usb.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/drivers/net/can/usb/gs_usb.c b/drivers/net/can/usb/gs_usb.c +index ffa2a4d92d010..acffe11a0ae13 100644 +--- a/drivers/net/can/usb/gs_usb.c ++++ b/drivers/net/can/usb/gs_usb.c +@@ -402,6 +402,8 @@ static void gs_usb_receive_bulk_callback(struct urb *urb) + usbcan + ); + ++ usb_anchor_urb(urb, &usbcan->rx_submitted); ++ + rc = usb_submit_urb(urb, GFP_ATOMIC); + + /* USB failure take down all interfaces */ +-- +2.53.0 + diff --git a/queue-5.15/can-gs_usb-gs_usb_receive_bulk_callback-unanchor-url.patch b/queue-5.15/can-gs_usb-gs_usb_receive_bulk_callback-unanchor-url.patch new file mode 100644 index 0000000000..a41cb29d77 --- /dev/null +++ b/queue-5.15/can-gs_usb-gs_usb_receive_bulk_callback-unanchor-url.patch @@ -0,0 +1,62 @@ +From 8c065ae108f3efe67ad63836f68ef55343c4dc90 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 3 Apr 2026 09:36:14 +0800 +Subject: can: gs_usb: gs_usb_receive_bulk_callback(): unanchor URL on + usb_submit_urb() error + +From: Marc Kleine-Budde + +[ Upstream commit 79a6d1bfe1148bc921b8d7f3371a7fbce44e30f7 ] + +In commit 7352e1d5932a ("can: gs_usb: gs_usb_receive_bulk_callback(): fix +URB memory leak"), the URB was re-anchored before usb_submit_urb() in +gs_usb_receive_bulk_callback() to prevent a leak of this URB during +cleanup. + +However, this patch did not take into account that usb_submit_urb() could +fail. The URB remains anchored and +usb_kill_anchored_urbs(&parent->rx_submitted) in gs_can_close() loops +infinitely since the anchor list never becomes empty. + +To fix the bug, unanchor the URB when an usb_submit_urb() error occurs, +also print an info message. + +Fixes: 7352e1d5932a ("can: gs_usb: gs_usb_receive_bulk_callback(): fix URB memory leak") +Reported-by: Jakub Kicinski +Closes: https://lore.kernel.org/all/20260110223836.3890248-1-kuba@kernel.org/ +Link: https://patch.msgid.link/20260116-can_usb-fix-reanchor-v1-1-9d74e7289225@pengutronix.de +Signed-off-by: Marc Kleine-Budde +Signed-off-by: Ruohan Lan +Signed-off-by: Sasha Levin +--- + drivers/net/can/usb/gs_usb.c | 7 +++++++ + 1 file changed, 7 insertions(+) + +diff --git a/drivers/net/can/usb/gs_usb.c b/drivers/net/can/usb/gs_usb.c +index acffe11a0ae13..134f830508d9f 100644 +--- a/drivers/net/can/usb/gs_usb.c ++++ b/drivers/net/can/usb/gs_usb.c +@@ -405,6 +405,10 @@ static void gs_usb_receive_bulk_callback(struct urb *urb) + usb_anchor_urb(urb, &usbcan->rx_submitted); + + rc = usb_submit_urb(urb, GFP_ATOMIC); ++ if (!rc) ++ return; ++ ++ usb_unanchor_urb(urb); + + /* USB failure take down all interfaces */ + if (rc == -ENODEV) { +@@ -413,6 +417,9 @@ static void gs_usb_receive_bulk_callback(struct urb *urb) + if (usbcan->canch[rc]) + netif_device_detach(usbcan->canch[rc]->netdev); + } ++ } else if (rc != -ESHUTDOWN && net_ratelimit()) { ++ netdev_info(netdev, "failed to re-submit IN URB: %pe\n", ++ ERR_PTR(urb->status)); + } + } + +-- +2.53.0 + diff --git a/queue-5.15/fbcon-set-fb_display-i-mode-to-null-when-the-mode-is.patch b/queue-5.15/fbcon-set-fb_display-i-mode-to-null-when-the-mode-is.patch new file mode 100644 index 0000000000..52456596ab --- /dev/null +++ b/queue-5.15/fbcon-set-fb_display-i-mode-to-null-when-the-mode-is.patch @@ -0,0 +1,129 @@ +From a6e4bdf755d2db9e3bec814140fd17555e592c8e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 31 Mar 2026 11:01:48 +0800 +Subject: fbcon: Set fb_display[i]->mode to NULL when the mode is released + +From: Quanmin Yan + +[ Upstream commit a1f3058930745d2b938b6b4f5bd9630dc74b26b7 ] + +Recently, we discovered the following issue through syzkaller: + +BUG: KASAN: slab-use-after-free in fb_mode_is_equal+0x285/0x2f0 +Read of size 4 at addr ff11000001b3c69c by task syz.xxx +... +Call Trace: + + dump_stack_lvl+0xab/0xe0 + print_address_description.constprop.0+0x2c/0x390 + print_report+0xb9/0x280 + kasan_report+0xb8/0xf0 + fb_mode_is_equal+0x285/0x2f0 + fbcon_mode_deleted+0x129/0x180 + fb_set_var+0xe7f/0x11d0 + do_fb_ioctl+0x6a0/0x750 + fb_ioctl+0xe0/0x140 + __x64_sys_ioctl+0x193/0x210 + do_syscall_64+0x5f/0x9c0 + entry_SYSCALL_64_after_hwframe+0x76/0x7e + +Based on experimentation and analysis, during framebuffer unregistration, +only the memory of fb_info->modelist is freed, without setting the +corresponding fb_display[i]->mode to NULL for the freed modes. This leads +to UAF issues during subsequent accesses. Here's an example of reproduction +steps: +1. With /dev/fb0 already registered in the system, load a kernel module + to register a new device /dev/fb1; +2. Set fb1's mode to the global fb_display[] array (via FBIOPUT_CON2FBMAP); +3. Switch console from fb to VGA (to allow normal rmmod of the ko); +4. Unload the kernel module, at this point fb1's modelist is freed, leaving + a wild pointer in fb_display[]; +5. Trigger the bug via system calls through fb0 attempting to delete a mode + from fb0. + +Add a check in do_unregister_framebuffer(): if the mode to be freed exists +in fb_display[], set the corresponding mode pointer to NULL. + +[ The context change is due to the commit 2c0c19b681d5 +("fbdev: fbmem: Fix double free of 'fb_info->pixmap.addr'") in v5.16 +which is irrelevant to the logic of this patch. ] + +Signed-off-by: Quanmin Yan +Reviewed-by: Thomas Zimmermann +Signed-off-by: Helge Deller +Cc: stable@vger.kernel.org +Signed-off-by: Johnny Hao +Signed-off-by: Sasha Levin +--- + drivers/video/fbdev/core/fbcon.c | 20 ++++++++++++++++++++ + drivers/video/fbdev/core/fbmem.c | 2 ++ + include/linux/fbcon.h | 2 ++ + 3 files changed, 24 insertions(+) + +diff --git a/drivers/video/fbdev/core/fbcon.c b/drivers/video/fbdev/core/fbcon.c +index f4584681fa43d..7dce023c2fb34 100644 +--- a/drivers/video/fbdev/core/fbcon.c ++++ b/drivers/video/fbdev/core/fbcon.c +@@ -2797,6 +2797,26 @@ int fbcon_mode_deleted(struct fb_info *info, + return found; + } + ++static void fbcon_delete_mode(struct fb_videomode *m) ++{ ++ struct fbcon_display *p; ++ int i; ++ ++ for (i = first_fb_vc; i <= last_fb_vc; i++) { ++ p = &fb_display[i]; ++ if (p->mode == m) ++ p->mode = NULL; ++ } ++} ++ ++void fbcon_delete_modelist(struct list_head *head) ++{ ++ struct fb_modelist *modelist; ++ ++ list_for_each_entry(modelist, head, list) ++ fbcon_delete_mode(&modelist->mode); ++} ++ + #ifdef CONFIG_VT_HW_CONSOLE_BINDING + static void fbcon_unbind(void) + { +diff --git a/drivers/video/fbdev/core/fbmem.c b/drivers/video/fbdev/core/fbmem.c +index 3b52ddfe03506..03a7a7e2a670e 100644 +--- a/drivers/video/fbdev/core/fbmem.c ++++ b/drivers/video/fbdev/core/fbmem.c +@@ -1750,6 +1750,8 @@ static void do_unregister_framebuffer(struct fb_info *fb_info) + if (fb_info->pixmap.addr && + (fb_info->pixmap.flags & FB_PIXMAP_DEFAULT)) + kfree(fb_info->pixmap.addr); ++ ++ fbcon_delete_modelist(&fb_info->modelist); + fb_destroy_modelist(&fb_info->modelist); + registered_fb[fb_info->node] = NULL; + num_registered_fb--; +diff --git a/include/linux/fbcon.h b/include/linux/fbcon.h +index 2382dec6d6ab8..fb0fc2736b801 100644 +--- a/include/linux/fbcon.h ++++ b/include/linux/fbcon.h +@@ -11,6 +11,7 @@ void fbcon_suspended(struct fb_info *info); + void fbcon_resumed(struct fb_info *info); + int fbcon_mode_deleted(struct fb_info *info, + struct fb_videomode *mode); ++void fbcon_delete_modelist(struct list_head *head); + void fbcon_new_modelist(struct fb_info *info); + void fbcon_get_requirement(struct fb_info *info, + struct fb_blit_caps *caps); +@@ -31,6 +32,7 @@ static inline void fbcon_suspended(struct fb_info *info) {} + static inline void fbcon_resumed(struct fb_info *info) {} + static inline int fbcon_mode_deleted(struct fb_info *info, + struct fb_videomode *mode) { return 0; } ++static inline void fbcon_delete_modelist(struct list_head *head) {} + static inline void fbcon_new_modelist(struct fb_info *info) {} + static inline void fbcon_get_requirement(struct fb_info *info, + struct fb_blit_caps *caps) {} +-- +2.53.0 + diff --git a/queue-5.15/media-uvcvideo-mark-invalid-entities-with-id-uvc_inv.patch b/queue-5.15/media-uvcvideo-mark-invalid-entities-with-id-uvc_inv.patch new file mode 100644 index 0000000000..dd63e9cf0f --- /dev/null +++ b/queue-5.15/media-uvcvideo-mark-invalid-entities-with-id-uvc_inv.patch @@ -0,0 +1,317 @@ +From c00bc51ae203f02a86b8e4fae6901f4f9bec6ea9 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 1 Apr 2026 16:10:48 +0800 +Subject: media: uvcvideo: Mark invalid entities with id UVC_INVALID_ENTITY_ID + +From: Thadeu Lima de Souza Cascardo + +[ Upstream commit 0e2ee70291e64a30fe36960c85294726d34a103e ] + +Per UVC 1.1+ specification 3.7.2, units and terminals must have a non-zero +unique ID. + +``` +Each Unit and Terminal within the video function is assigned a unique +identification number, the Unit ID (UID) or Terminal ID (TID), contained in +the bUnitID or bTerminalID field of the descriptor. The value 0x00 is +reserved for undefined ID, +``` + +If we add a new entity with id 0 or a duplicated ID, it will be marked +as UVC_INVALID_ENTITY_ID. + +In a previous attempt commit 3dd075fe8ebb ("media: uvcvideo: Require +entities to have a non-zero unique ID"), we ignored all the invalid units, +this broke a lot of non-compatible cameras. Hopefully we are more lucky +this time. + +This also prevents some syzkaller reproducers from triggering warnings due +to a chain of entities referring to themselves. In one particular case, an +Output Unit is connected to an Input Unit, both with the same ID of 1. But +when looking up for the source ID of the Output Unit, that same entity is +found instead of the input entity, which leads to such warnings. + +In another case, a backward chain was considered finished as the source ID +was 0. Later on, that entity was found, but its pads were not valid. + +Here is a sample stack trace for one of those cases. + +[ 20.650953] usb 1-1: new high-speed USB device number 2 using dummy_hcd +[ 20.830206] usb 1-1: Using ep0 maxpacket: 8 +[ 20.833501] usb 1-1: config 0 descriptor?? +[ 21.038518] usb 1-1: string descriptor 0 read error: -71 +[ 21.038893] usb 1-1: Found UVC 0.00 device (2833:0201) +[ 21.039299] uvcvideo 1-1:0.0: Entity type for entity Output 1 was not initialized! +[ 21.041583] uvcvideo 1-1:0.0: Entity type for entity Input 1 was not initialized! +[ 21.042218] ------------[ cut here ]------------ +[ 21.042536] WARNING: CPU: 0 PID: 9 at drivers/media/mc/mc-entity.c:1147 media_create_pad_link+0x2c4/0x2e0 +[ 21.043195] Modules linked in: +[ 21.043535] CPU: 0 UID: 0 PID: 9 Comm: kworker/0:1 Not tainted 6.11.0-rc7-00030-g3480e43aeccf #444 +[ 21.044101] Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.15.0-1 04/01/2014 +[ 21.044639] Workqueue: usb_hub_wq hub_event +[ 21.045100] RIP: 0010:media_create_pad_link+0x2c4/0x2e0 +[ 21.045508] Code: fe e8 20 01 00 00 b8 f4 ff ff ff 48 83 c4 30 5b 41 5c 41 5d 41 5e 41 5f 5d c3 cc cc cc cc 0f 0b eb e9 0f 0b eb 0a 0f 0b eb 06 <0f> 0b eb 02 0f 0b b8 ea ff ff ff eb d4 66 2e 0f 1f 84 00 00 00 00 +[ 21.046801] RSP: 0018:ffffc9000004b318 EFLAGS: 00010246 +[ 21.047227] RAX: ffff888004e5d458 RBX: 0000000000000000 RCX: ffffffff818fccf1 +[ 21.047719] RDX: 000000000000007b RSI: 0000000000000000 RDI: ffff888004313290 +[ 21.048241] RBP: ffff888004313290 R08: 0001ffffffffffff R09: 0000000000000000 +[ 21.048701] R10: 0000000000000013 R11: 0001888004313290 R12: 0000000000000003 +[ 21.049138] R13: ffff888004313080 R14: ffff888004313080 R15: 0000000000000000 +[ 21.049648] FS: 0000000000000000(0000) GS:ffff88803ec00000(0000) knlGS:0000000000000000 +[ 21.050271] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 +[ 21.050688] CR2: 0000592cc27635b0 CR3: 000000000431c000 CR4: 0000000000750ef0 +[ 21.051136] PKRU: 55555554 +[ 21.051331] Call Trace: +[ 21.051480] +[ 21.051611] ? __warn+0xc4/0x210 +[ 21.051861] ? media_create_pad_link+0x2c4/0x2e0 +[ 21.052252] ? report_bug+0x11b/0x1a0 +[ 21.052540] ? trace_hardirqs_on+0x31/0x40 +[ 21.052901] ? handle_bug+0x3d/0x70 +[ 21.053197] ? exc_invalid_op+0x1a/0x50 +[ 21.053511] ? asm_exc_invalid_op+0x1a/0x20 +[ 21.053924] ? media_create_pad_link+0x91/0x2e0 +[ 21.054364] ? media_create_pad_link+0x2c4/0x2e0 +[ 21.054834] ? media_create_pad_link+0x91/0x2e0 +[ 21.055131] ? _raw_spin_unlock+0x1e/0x40 +[ 21.055441] ? __v4l2_device_register_subdev+0x202/0x210 +[ 21.055837] uvc_mc_register_entities+0x358/0x400 +[ 21.056144] uvc_register_chains+0x1fd/0x290 +[ 21.056413] uvc_probe+0x380e/0x3dc0 +[ 21.056676] ? __lock_acquire+0x5aa/0x26e0 +[ 21.056946] ? find_held_lock+0x33/0xa0 +[ 21.057196] ? kernfs_activate+0x70/0x80 +[ 21.057533] ? usb_match_dynamic_id+0x1b/0x70 +[ 21.057811] ? find_held_lock+0x33/0xa0 +[ 21.058047] ? usb_match_dynamic_id+0x55/0x70 +[ 21.058330] ? lock_release+0x124/0x260 +[ 21.058657] ? usb_match_one_id_intf+0xa2/0x100 +[ 21.058997] usb_probe_interface+0x1ba/0x330 +[ 21.059399] really_probe+0x1ba/0x4c0 +[ 21.059662] __driver_probe_device+0xb2/0x180 +[ 21.059944] driver_probe_device+0x5a/0x100 +[ 21.060170] __device_attach_driver+0xe9/0x160 +[ 21.060427] ? __pfx___device_attach_driver+0x10/0x10 +[ 21.060872] bus_for_each_drv+0xa9/0x100 +[ 21.061312] __device_attach+0xed/0x190 +[ 21.061812] device_initial_probe+0xe/0x20 +[ 21.062229] bus_probe_device+0x4d/0xd0 +[ 21.062590] device_add+0x308/0x590 +[ 21.062912] usb_set_configuration+0x7b6/0xaf0 +[ 21.063403] usb_generic_driver_probe+0x36/0x80 +[ 21.063714] usb_probe_device+0x7b/0x130 +[ 21.063936] really_probe+0x1ba/0x4c0 +[ 21.064111] __driver_probe_device+0xb2/0x180 +[ 21.064577] driver_probe_device+0x5a/0x100 +[ 21.065019] __device_attach_driver+0xe9/0x160 +[ 21.065403] ? __pfx___device_attach_driver+0x10/0x10 +[ 21.065820] bus_for_each_drv+0xa9/0x100 +[ 21.066094] __device_attach+0xed/0x190 +[ 21.066535] device_initial_probe+0xe/0x20 +[ 21.066992] bus_probe_device+0x4d/0xd0 +[ 21.067250] device_add+0x308/0x590 +[ 21.067501] usb_new_device+0x347/0x610 +[ 21.067817] hub_event+0x156b/0x1e30 +[ 21.068060] ? process_scheduled_works+0x48b/0xaf0 +[ 21.068337] process_scheduled_works+0x5a3/0xaf0 +[ 21.068668] worker_thread+0x3cf/0x560 +[ 21.068932] ? kthread+0x109/0x1b0 +[ 21.069133] kthread+0x197/0x1b0 +[ 21.069343] ? __pfx_worker_thread+0x10/0x10 +[ 21.069598] ? __pfx_kthread+0x10/0x10 +[ 21.069908] ret_from_fork+0x32/0x40 +[ 21.070169] ? __pfx_kthread+0x10/0x10 +[ 21.070424] ret_from_fork_asm+0x1a/0x30 +[ 21.070737] + +Reported-by: syzbot+0584f746fde3d52b4675@syzkaller.appspotmail.com +Closes: https://syzkaller.appspot.com/bug?extid=0584f746fde3d52b4675 +Reported-by: syzbot+dd320d114deb3f5bb79b@syzkaller.appspotmail.com +Closes: https://syzkaller.appspot.com/bug?extid=dd320d114deb3f5bb79b +Reported-by: Youngjun Lee +Fixes: a3fbc2e6bb05 ("media: mc-entity.c: use WARN_ON, validate link pads") +Cc: stable@vger.kernel.org +Signed-off-by: Thadeu Lima de Souza Cascardo +Co-developed-by: Ricardo Ribalda +Signed-off-by: Ricardo Ribalda +Reviewed-by: Laurent Pinchart +Reviewed-by: Hans de Goede +Signed-off-by: Hans de Goede +Signed-off-by: Laurent Pinchart +Signed-off-by: Hans Verkuil +Signed-off-by: Johnny Hao +Signed-off-by: Sasha Levin +--- + drivers/media/usb/uvc/uvc_driver.c | 73 +++++++++++++++++++----------- + drivers/media/usb/uvc/uvcvideo.h | 2 + + 2 files changed, 48 insertions(+), 27 deletions(-) + +diff --git a/drivers/media/usb/uvc/uvc_driver.c b/drivers/media/usb/uvc/uvc_driver.c +index 858fc5b26a5e5..c39c1f237d10e 100644 +--- a/drivers/media/usb/uvc/uvc_driver.c ++++ b/drivers/media/usb/uvc/uvc_driver.c +@@ -413,6 +413,9 @@ struct uvc_entity *uvc_entity_by_id(struct uvc_device *dev, int id) + { + struct uvc_entity *entity; + ++ if (id == UVC_INVALID_ENTITY_ID) ++ return NULL; ++ + list_for_each_entry(entity, &dev->entities, list) { + if (entity->id == id) + return entity; +@@ -1029,14 +1032,27 @@ static const u8 uvc_media_transport_input_guid[16] = + UVC_GUID_UVC_MEDIA_TRANSPORT_INPUT; + static const u8 uvc_processing_guid[16] = UVC_GUID_UVC_PROCESSING; + +-static struct uvc_entity *uvc_alloc_entity(u16 type, u16 id, +- unsigned int num_pads, unsigned int extra_size) ++static struct uvc_entity *uvc_alloc_new_entity(struct uvc_device *dev, u16 type, ++ u16 id, unsigned int num_pads, ++ unsigned int extra_size) + { + struct uvc_entity *entity; + unsigned int num_inputs; + unsigned int size; + unsigned int i; + ++ /* Per UVC 1.1+ spec 3.7.2, the ID should be non-zero. */ ++ if (id == 0) { ++ dev_err(&dev->intf->dev, "Found Unit with invalid ID 0\n"); ++ id = UVC_INVALID_ENTITY_ID; ++ } ++ ++ /* Per UVC 1.1+ spec 3.7.2, the ID is unique. */ ++ if (uvc_entity_by_id(dev, id)) { ++ dev_err(&dev->intf->dev, "Found multiple Units with ID %u\n", id); ++ id = UVC_INVALID_ENTITY_ID; ++ } ++ + extra_size = roundup(extra_size, sizeof(*entity->pads)); + if (num_pads) + num_inputs = type & UVC_TERM_OUTPUT ? num_pads : num_pads - 1; +@@ -1046,7 +1062,7 @@ static struct uvc_entity *uvc_alloc_entity(u16 type, u16 id, + + num_inputs; + entity = kzalloc(size, GFP_KERNEL); + if (entity == NULL) +- return NULL; ++ return ERR_PTR(-ENOMEM); + + entity->id = id; + entity->type = type; +@@ -1136,10 +1152,10 @@ static int uvc_parse_vendor_control(struct uvc_device *dev, + break; + } + +- unit = uvc_alloc_entity(UVC_VC_EXTENSION_UNIT, buffer[3], +- p + 1, 2*n); +- if (unit == NULL) +- return -ENOMEM; ++ unit = uvc_alloc_new_entity(dev, UVC_VC_EXTENSION_UNIT, ++ buffer[3], p + 1, 2 * n); ++ if (IS_ERR(unit)) ++ return PTR_ERR(unit); + + memcpy(unit->guid, &buffer[4], 16); + unit->extension.bNumControls = buffer[20]; +@@ -1249,10 +1265,10 @@ static int uvc_parse_standard_control(struct uvc_device *dev, + return -EINVAL; + } + +- term = uvc_alloc_entity(type | UVC_TERM_INPUT, buffer[3], +- 1, n + p); +- if (term == NULL) +- return -ENOMEM; ++ term = uvc_alloc_new_entity(dev, type | UVC_TERM_INPUT, ++ buffer[3], 1, n + p); ++ if (IS_ERR(term)) ++ return PTR_ERR(term); + + if (UVC_ENTITY_TYPE(term) == UVC_ITT_CAMERA) { + term->camera.bControlSize = n; +@@ -1308,10 +1324,10 @@ static int uvc_parse_standard_control(struct uvc_device *dev, + return 0; + } + +- term = uvc_alloc_entity(type | UVC_TERM_OUTPUT, buffer[3], +- 1, 0); +- if (term == NULL) +- return -ENOMEM; ++ term = uvc_alloc_new_entity(dev, type | UVC_TERM_OUTPUT, ++ buffer[3], 1, 0); ++ if (IS_ERR(term)) ++ return PTR_ERR(term); + + memcpy(term->baSourceID, &buffer[7], 1); + +@@ -1332,9 +1348,10 @@ static int uvc_parse_standard_control(struct uvc_device *dev, + return -EINVAL; + } + +- unit = uvc_alloc_entity(buffer[2], buffer[3], p + 1, 0); +- if (unit == NULL) +- return -ENOMEM; ++ unit = uvc_alloc_new_entity(dev, buffer[2], buffer[3], ++ p + 1, 0); ++ if (IS_ERR(unit)) ++ return PTR_ERR(unit); + + memcpy(unit->baSourceID, &buffer[5], p); + +@@ -1356,9 +1373,9 @@ static int uvc_parse_standard_control(struct uvc_device *dev, + return -EINVAL; + } + +- unit = uvc_alloc_entity(buffer[2], buffer[3], 2, n); +- if (unit == NULL) +- return -ENOMEM; ++ unit = uvc_alloc_new_entity(dev, buffer[2], buffer[3], 2, n); ++ if (IS_ERR(unit)) ++ return PTR_ERR(unit); + + memcpy(unit->baSourceID, &buffer[4], 1); + unit->processing.wMaxMultiplier = +@@ -1387,9 +1404,10 @@ static int uvc_parse_standard_control(struct uvc_device *dev, + return -EINVAL; + } + +- unit = uvc_alloc_entity(buffer[2], buffer[3], p + 1, n); +- if (unit == NULL) +- return -ENOMEM; ++ unit = uvc_alloc_new_entity(dev, buffer[2], buffer[3], ++ p + 1, n); ++ if (IS_ERR(unit)) ++ return PTR_ERR(unit); + + memcpy(unit->guid, &buffer[4], 16); + unit->extension.bNumControls = buffer[20]; +@@ -1528,9 +1546,10 @@ static int uvc_gpio_parse(struct uvc_device *dev) + return dev_err_probe(&dev->intf->dev, irq, + "No IRQ for privacy GPIO\n"); + +- unit = uvc_alloc_entity(UVC_EXT_GPIO_UNIT, UVC_EXT_GPIO_UNIT_ID, 0, 1); +- if (!unit) +- return -ENOMEM; ++ unit = uvc_alloc_new_entity(dev, UVC_EXT_GPIO_UNIT, ++ UVC_EXT_GPIO_UNIT_ID, 0, 1); ++ if (IS_ERR(unit)) ++ return PTR_ERR(unit); + + unit->gpio.gpio_privacy = gpio_privacy; + unit->gpio.irq = irq; +diff --git a/drivers/media/usb/uvc/uvcvideo.h b/drivers/media/usb/uvc/uvcvideo.h +index 95af1591f1059..be4b746d902c6 100644 +--- a/drivers/media/usb/uvc/uvcvideo.h ++++ b/drivers/media/usb/uvc/uvcvideo.h +@@ -41,6 +41,8 @@ + #define UVC_EXT_GPIO_UNIT 0x7ffe + #define UVC_EXT_GPIO_UNIT_ID 0x100 + ++#define UVC_INVALID_ENTITY_ID 0xffff ++ + /* ------------------------------------------------------------------------ + * GUIDs + */ +-- +2.53.0 + diff --git a/queue-5.15/net-mctp-don-t-access-ifa_index-when-missing.patch b/queue-5.15/net-mctp-don-t-access-ifa_index-when-missing.patch new file mode 100644 index 0000000000..8ecc134fdd --- /dev/null +++ b/queue-5.15/net-mctp-don-t-access-ifa_index-when-missing.patch @@ -0,0 +1,75 @@ +From 6d629405579603c24ab9acf03170b803e78c67c5 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 1 Apr 2026 08:44:41 +0800 +Subject: net: mctp: Don't access ifa_index when missing + +From: Matt Johnston + +[ Upstream commit f11cf946c0a92c560a890d68e4775723353599e1 ] + +In mctp_dump_addrinfo, ifa_index can be used to filter interfaces, but +only when the struct ifaddrmsg is provided. Otherwise it will be +comparing to uninitialised memory - reproducible in the syzkaller case from +dhcpd, or busybox "ip addr show". + +The kernel MCTP implementation has always filtered by ifa_index, so +existing userspace programs expecting to dump MCTP addresses must +already be passing a valid ifa_index value (either 0 or a real index). + +BUG: KMSAN: uninit-value in mctp_dump_addrinfo+0x208/0xac0 net/mctp/device.c:128 + mctp_dump_addrinfo+0x208/0xac0 net/mctp/device.c:128 + rtnl_dump_all+0x3ec/0x5b0 net/core/rtnetlink.c:4380 + rtnl_dumpit+0xd5/0x2f0 net/core/rtnetlink.c:6824 + netlink_dump+0x97b/0x1690 net/netlink/af_netlink.c:2309 + +[ The context change is due to the commit 2d45eeb7d5d7 +("mctp: no longer rely on net->dev_index_head[]") in v6.14 +which is irrelevant to the logic of this patch. ] + +Fixes: 583be982d934 ("mctp: Add device handling and netlink interface") +Reported-by: syzbot+e76d52dadc089b9d197f@syzkaller.appspotmail.com +Closes: https://lore.kernel.org/all/68135815.050a0220.3a872c.000e.GAE@google.com/ +Reported-by: syzbot+1065a199625a388fce60@syzkaller.appspotmail.com +Closes: https://lore.kernel.org/all/681357d6.050a0220.14dd7d.000d.GAE@google.com/ +Signed-off-by: Matt Johnston +Link: https://patch.msgid.link/20250508-mctp-addr-dump-v2-1-c8a53fd2dd66@codeconstruct.com.au +Signed-off-by: Jakub Kicinski +Signed-off-by: Johnny Hao +Signed-off-by: Sasha Levin +--- + net/mctp/device.c | 19 +++++++++++++------ + 1 file changed, 13 insertions(+), 6 deletions(-) + +diff --git a/net/mctp/device.c b/net/mctp/device.c +index c00a2550e2e0e..aec7ffad2666a 100644 +--- a/net/mctp/device.c ++++ b/net/mctp/device.c +@@ -99,12 +99,19 @@ static int mctp_dump_addrinfo(struct sk_buff *skb, struct netlink_callback *cb) + struct net_device *dev; + struct ifaddrmsg *hdr; + struct mctp_dev *mdev; +- int ifindex; +- int idx, rc; +- +- hdr = nlmsg_data(cb->nlh); +- // filter by ifindex if requested +- ifindex = hdr->ifa_index; ++ int idx; ++ int ifindex = 0, rc; ++ ++ /* Filter by ifindex if a header is provided */ ++ if (cb->nlh->nlmsg_len >= nlmsg_msg_size(sizeof(*hdr))) { ++ hdr = nlmsg_data(cb->nlh); ++ ifindex = hdr->ifa_index; ++ } else { ++ if (cb->strict_check) { ++ NL_SET_ERR_MSG(cb->extack, "mctp: Invalid header for addr dump request"); ++ return -EINVAL; ++ } ++ } + + rcu_read_lock(); + for (; mcb->h < NETDEV_HASHENTRIES; mcb->h++, mcb->idx = 0) { +-- +2.53.0 + diff --git a/queue-5.15/series b/queue-5.15/series index 27d4162923..12fde6b5a6 100644 --- a/queue-5.15/series +++ b/queue-5.15/series @@ -489,3 +489,11 @@ thunderbolt-fix-property-read-in-nhi_wake_supported.patch usb-dummy-hcd-fix-locking-synchronization-error.patch usb-dummy-hcd-fix-interrupt-synchronization-error.patch usb-gadget-dummy_hcd-fix-premature-urb-completion-when-zlp-follows-partial-transfer.patch +can-gs_usb-gs_usb_receive_bulk_callback-fix-urb-memo.patch +can-gs_usb-gs_usb_receive_bulk_callback-unanchor-url.patch +can-gs_usb-gs_usb_receive_bulk_callback-fix-error-me.patch +fbcon-set-fb_display-i-mode-to-null-when-the-mode-is.patch +media-uvcvideo-mark-invalid-entities-with-id-uvc_inv.patch +net-mctp-don-t-access-ifa_index-when-missing.patch +smb-client-fix-refcount-leak-for-cifs_sb_tlink.patch +staging-rtl8723bs-fix-out-of-bounds-read-in-rtw_get_.patch diff --git a/queue-5.15/smb-client-fix-refcount-leak-for-cifs_sb_tlink.patch b/queue-5.15/smb-client-fix-refcount-leak-for-cifs_sb_tlink.patch new file mode 100644 index 0000000000..16ab972a6f --- /dev/null +++ b/queue-5.15/smb-client-fix-refcount-leak-for-cifs_sb_tlink.patch @@ -0,0 +1,88 @@ +From 0871260bd16f5d75650a4a7c742793d444a692cf Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 31 Mar 2026 15:00:54 +0800 +Subject: smb: client: Fix refcount leak for cifs_sb_tlink + +From: Shuhao Fu + +[ Upstream commit c2b77f42205ef485a647f62082c442c1cd69d3fc ] + +Fix three refcount inconsistency issues related to `cifs_sb_tlink`. + +Comments for `cifs_sb_tlink` state that `cifs_put_tlink()` needs to be +called after successful calls to `cifs_sb_tlink()`. Three calls fail to +update refcount accordingly, leading to possible resource leaks. + +Fixes: 8ceb98437946 ("CIFS: Move rename to ops struct") +Fixes: 2f1afe25997f ("cifs: Use smb 2 - 3 and cifsacl mount options getacl functions") +Fixes: 366ed846df60 ("cifs: Use smb 2 - 3 and cifsacl mount options setacl function") +Cc: stable@vger.kernel.org +Signed-off-by: Shuhao Fu +Signed-off-by: Steve French +Signed-off-by: Johnny Hao +Signed-off-by: Sasha Levin +--- + fs/cifs/inode.c | 6 ++++-- + fs/cifs/smb2ops.c | 8 ++++---- + 2 files changed, 8 insertions(+), 6 deletions(-) + +diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c +index 30a9a89c141bb..bb0b172c5a74d 100644 +--- a/fs/cifs/inode.c ++++ b/fs/cifs/inode.c +@@ -2023,8 +2023,10 @@ cifs_do_rename(const unsigned int xid, struct dentry *from_dentry, + tcon = tlink_tcon(tlink); + server = tcon->ses->server; + +- if (!server->ops->rename) +- return -ENOSYS; ++ if (!server->ops->rename) { ++ rc = -ENOSYS; ++ goto do_rename_exit; ++ } + + /* try path-based rename first */ + rc = server->ops->rename(xid, tcon, from_path, to_path, cifs_sb); +diff --git a/fs/cifs/smb2ops.c b/fs/cifs/smb2ops.c +index 619905fc694e4..0a62720590daf 100644 +--- a/fs/cifs/smb2ops.c ++++ b/fs/cifs/smb2ops.c +@@ -3437,8 +3437,7 @@ get_smb2_acl_by_path(struct cifs_sb_info *cifs_sb, + utf16_path = cifs_convert_path_to_utf16(path, cifs_sb); + if (!utf16_path) { + rc = -ENOMEM; +- free_xid(xid); +- return ERR_PTR(rc); ++ goto put_tlink; + } + + oparms.tcon = tcon; +@@ -3466,6 +3465,7 @@ get_smb2_acl_by_path(struct cifs_sb_info *cifs_sb, + SMB2_close(xid, tcon, fid.persistent_fid, fid.volatile_fid); + } + ++put_tlink: + cifs_put_tlink(tlink); + free_xid(xid); + +@@ -3506,8 +3506,7 @@ set_smb2_acl(struct cifs_ntsd *pnntsd, __u32 acllen, + utf16_path = cifs_convert_path_to_utf16(path, cifs_sb); + if (!utf16_path) { + rc = -ENOMEM; +- free_xid(xid); +- return rc; ++ goto put_tlink; + } + + oparms.tcon = tcon; +@@ -3527,6 +3526,7 @@ set_smb2_acl(struct cifs_ntsd *pnntsd, __u32 acllen, + SMB2_close(xid, tcon, fid.persistent_fid, fid.volatile_fid); + } + ++put_tlink: + cifs_put_tlink(tlink); + free_xid(xid); + return rc; +-- +2.53.0 + diff --git a/queue-5.15/staging-rtl8723bs-fix-out-of-bounds-read-in-rtw_get_.patch b/queue-5.15/staging-rtl8723bs-fix-out-of-bounds-read-in-rtw_get_.patch new file mode 100644 index 0000000000..73ae7c41bf --- /dev/null +++ b/queue-5.15/staging-rtl8723bs-fix-out-of-bounds-read-in-rtw_get_.patch @@ -0,0 +1,73 @@ +From 547f8c4fcb2c0150cc098ecc97bf2dd9175ad9ba Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 30 Mar 2026 11:12:31 +0800 +Subject: staging: rtl8723bs: fix out-of-bounds read in rtw_get_ie() parser + +From: Navaneeth K + +[ Upstream commit 154828bf9559b9c8421fc2f0d7f7f76b3683aaed ] + +The Information Element (IE) parser rtw_get_ie() trusted the length +byte of each IE without validating that the IE body (len bytes after +the 2-byte header) fits inside the remaining frame buffer. A malformed +frame can advertise an IE length larger than the available data, causing +the parser to increment its pointer beyond the buffer end. This results +in out-of-bounds reads or, depending on the pattern, an infinite loop. + +Fix by validating that (offset + 2 + len) does not exceed the limit +before accepting the IE or advancing to the next element. + +This prevents OOB reads and ensures the parser terminates safely on +malformed frames. + +[ The context change is due to the commit 4610e57a7d2e +("staging: rtl8723bs: Remove redundant else branches.") in v5.19 +which is irrelevant to the logic of this patch. ] + +Signed-off-by: Navaneeth K +Cc: stable +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Johnny Hao +Signed-off-by: Sasha Levin +--- + drivers/staging/rtl8723bs/core/rtw_ieee80211.c | 13 +++++++------ + 1 file changed, 7 insertions(+), 6 deletions(-) + +diff --git a/drivers/staging/rtl8723bs/core/rtw_ieee80211.c b/drivers/staging/rtl8723bs/core/rtw_ieee80211.c +index c01f7da9d025c..666ce2f9c5270 100644 +--- a/drivers/staging/rtl8723bs/core/rtw_ieee80211.c ++++ b/drivers/staging/rtl8723bs/core/rtw_ieee80211.c +@@ -141,23 +141,24 @@ u8 *rtw_get_ie(u8 *pbuf, signed int index, signed int *len, signed int limit) + signed int tmp, i; + u8 *p; + +- if (limit < 1) ++ if (limit < 2) + return NULL; + + p = pbuf; + i = 0; + *len = 0; +- while (1) { ++ while (i + 2 <= limit) { ++ tmp = *(p + 1); ++ if (i + 2 + tmp > limit) ++ break; ++ + if (*p == index) { +- *len = *(p + 1); ++ *len = tmp; + return p; + } else { +- tmp = *(p + 1); + p += (tmp + 2); + i += (tmp + 2); + } +- if (i >= limit) +- break; + } + return NULL; + } +-- +2.53.0 + diff --git a/queue-6.1/blk-mq-move-the-call-to-blk_put_queue-out-of-blk_mq_.patch b/queue-6.1/blk-mq-move-the-call-to-blk_put_queue-out-of-blk_mq_.patch new file mode 100644 index 0000000000..91529762c0 --- /dev/null +++ b/queue-6.1/blk-mq-move-the-call-to-blk_put_queue-out-of-blk_mq_.patch @@ -0,0 +1,172 @@ +From d4e944fdfcacae6a3fa5adc519593cc428be8356 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 2 Apr 2026 13:57:15 +0000 +Subject: blk-mq: move the call to blk_put_queue out of blk_mq_destroy_queue + +From: Christoph Hellwig + +[ Upstream commit 2b3f056f72e56fa07df69b4705e0b46a6c08e77c ] + +The fact that blk_mq_destroy_queue also drops a queue reference leads +to various places having to grab an extra reference. Move the call to +blk_put_queue into the callers to allow removing the extra references. + +Signed-off-by: Christoph Hellwig +Reviewed-by: Sagi Grimberg +Reviewed-by: Chaitanya Kulkarni +Reviewed-by: Keith Busch +Link: https://lore.kernel.org/r/20221018135720.670094-2-hch@lst.de +[axboe: fix fabrics_q vs admin_q conflict in nvme core.c] +Signed-off-by: Jens Axboe +Stable-dep-of: 03b3bcd319b3 ("nvme: fix admin request_queue lifetime") +Signed-off-by: Maximilian Heyne +Tested-by: Fedor Pchelkin +Signed-off-by: Sasha Levin +--- + block/blk-mq.c | 4 +--- + block/bsg-lib.c | 2 ++ + drivers/nvme/host/apple.c | 1 + + drivers/nvme/host/core.c | 10 ++++++++-- + drivers/nvme/host/pci.c | 1 + + drivers/scsi/scsi_sysfs.c | 1 + + drivers/ufs/core/ufshcd.c | 2 ++ + 7 files changed, 16 insertions(+), 5 deletions(-) + +diff --git a/block/blk-mq.c b/block/blk-mq.c +index a9697541d67f9..8b9e5ca398242 100644 +--- a/block/blk-mq.c ++++ b/block/blk-mq.c +@@ -4194,9 +4194,6 @@ void blk_mq_destroy_queue(struct request_queue *q) + blk_sync_queue(q); + blk_mq_cancel_work_sync(q); + blk_mq_exit_queue(q); +- +- /* @q is and will stay empty, shutdown and put */ +- blk_put_queue(q); + } + EXPORT_SYMBOL(blk_mq_destroy_queue); + +@@ -4213,6 +4210,7 @@ struct gendisk *__blk_mq_alloc_disk(struct blk_mq_tag_set *set, void *queuedata, + disk = __alloc_disk_node(q, set->numa_node, lkclass); + if (!disk) { + blk_mq_destroy_queue(q); ++ blk_put_queue(q); + return ERR_PTR(-ENOMEM); + } + set_bit(GD_OWNS_QUEUE, &disk->state); +diff --git a/block/bsg-lib.c b/block/bsg-lib.c +index d6f5dcdce748c..435c32373cd68 100644 +--- a/block/bsg-lib.c ++++ b/block/bsg-lib.c +@@ -325,6 +325,7 @@ void bsg_remove_queue(struct request_queue *q) + + bsg_unregister_queue(bset->bd); + blk_mq_destroy_queue(q); ++ blk_put_queue(q); + blk_mq_free_tag_set(&bset->tag_set); + kfree(bset); + } +@@ -400,6 +401,7 @@ struct request_queue *bsg_setup_queue(struct device *dev, const char *name, + return q; + out_cleanup_queue: + blk_mq_destroy_queue(q); ++ blk_put_queue(q); + out_queue: + blk_mq_free_tag_set(set); + out_tag_set: +diff --git a/drivers/nvme/host/apple.c b/drivers/nvme/host/apple.c +index 262d2b60ac6dd..c5fc293c22123 100644 +--- a/drivers/nvme/host/apple.c ++++ b/drivers/nvme/host/apple.c +@@ -1510,6 +1510,7 @@ static int apple_nvme_probe(struct platform_device *pdev) + if (!blk_get_queue(anv->ctrl.admin_q)) { + nvme_start_admin_queue(&anv->ctrl); + blk_mq_destroy_queue(anv->ctrl.admin_q); ++ blk_put_queue(anv->ctrl.admin_q); + anv->ctrl.admin_q = NULL; + ret = -ENODEV; + goto put_dev; +diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c +index 938af571dc13e..044e1a9c099b3 100644 +--- a/drivers/nvme/host/core.c ++++ b/drivers/nvme/host/core.c +@@ -5031,6 +5031,7 @@ int nvme_alloc_admin_tag_set(struct nvme_ctrl *ctrl, struct blk_mq_tag_set *set, + + out_cleanup_admin_q: + blk_mq_destroy_queue(ctrl->admin_q); ++ blk_put_queue(ctrl->admin_q); + out_free_tagset: + blk_mq_free_tag_set(set); + ctrl->admin_q = NULL; +@@ -5042,8 +5043,11 @@ EXPORT_SYMBOL_GPL(nvme_alloc_admin_tag_set); + void nvme_remove_admin_tag_set(struct nvme_ctrl *ctrl) + { + blk_mq_destroy_queue(ctrl->admin_q); +- if (ctrl->ops->flags & NVME_F_FABRICS) ++ blk_put_queue(ctrl->admin_q); ++ if (ctrl->ops->flags & NVME_F_FABRICS) { + blk_mq_destroy_queue(ctrl->fabrics_q); ++ blk_put_queue(ctrl->fabrics_q); ++ } + blk_mq_free_tag_set(ctrl->admin_tagset); + } + EXPORT_SYMBOL_GPL(nvme_remove_admin_tag_set); +@@ -5099,8 +5103,10 @@ EXPORT_SYMBOL_GPL(nvme_alloc_io_tag_set); + + void nvme_remove_io_tag_set(struct nvme_ctrl *ctrl) + { +- if (ctrl->ops->flags & NVME_F_FABRICS) ++ if (ctrl->ops->flags & NVME_F_FABRICS) { + blk_mq_destroy_queue(ctrl->connect_q); ++ blk_put_queue(ctrl->connect_q); ++ } + blk_mq_free_tag_set(ctrl->tagset); + } + EXPORT_SYMBOL_GPL(nvme_remove_io_tag_set); +diff --git a/drivers/nvme/host/pci.c b/drivers/nvme/host/pci.c +index 15bc7d81df4bd..27a4706bc9131 100644 +--- a/drivers/nvme/host/pci.c ++++ b/drivers/nvme/host/pci.c +@@ -1783,6 +1783,7 @@ static void nvme_dev_remove_admin(struct nvme_dev *dev) + */ + nvme_start_admin_queue(&dev->ctrl); + blk_mq_destroy_queue(dev->ctrl.admin_q); ++ blk_put_queue(dev->ctrl.admin_q); + blk_mq_free_tag_set(&dev->admin_tagset); + } + } +diff --git a/drivers/scsi/scsi_sysfs.c b/drivers/scsi/scsi_sysfs.c +index 456b92c3a7811..af81b2ba0c9b3 100644 +--- a/drivers/scsi/scsi_sysfs.c ++++ b/drivers/scsi/scsi_sysfs.c +@@ -1486,6 +1486,7 @@ void __scsi_remove_device(struct scsi_device *sdev) + mutex_unlock(&sdev->state_mutex); + + blk_mq_destroy_queue(sdev->request_queue); ++ blk_put_queue(sdev->request_queue); + kref_put(&sdev->host->tagset_refcnt, scsi_mq_free_tags); + cancel_work_sync(&sdev->requeue_work); + +diff --git a/drivers/ufs/core/ufshcd.c b/drivers/ufs/core/ufshcd.c +index f72ba0b206437..a39ffc62d88a1 100644 +--- a/drivers/ufs/core/ufshcd.c ++++ b/drivers/ufs/core/ufshcd.c +@@ -9651,6 +9651,7 @@ void ufshcd_remove(struct ufs_hba *hba) + ufshpb_remove(hba); + ufs_sysfs_remove_nodes(hba->dev); + blk_mq_destroy_queue(hba->tmf_queue); ++ blk_put_queue(hba->tmf_queue); + blk_mq_free_tag_set(&hba->tmf_tag_set); + scsi_remove_host(hba->host); + /* disable interrupts */ +@@ -9953,6 +9954,7 @@ int ufshcd_init(struct ufs_hba *hba, void __iomem *mmio_base, unsigned int irq) + + free_tmf_queue: + blk_mq_destroy_queue(hba->tmf_queue); ++ blk_put_queue(hba->tmf_queue); + free_tmf_tag_set: + blk_mq_free_tag_set(&hba->tmf_tag_set); + out_remove_scsi_host: +-- +2.53.0 + diff --git a/queue-6.1/btrfs-do-not-free-data-reservation-in-fallback-from-.patch b/queue-6.1/btrfs-do-not-free-data-reservation-in-fallback-from-.patch new file mode 100644 index 0000000000..c7a280e7e3 --- /dev/null +++ b/queue-6.1/btrfs-do-not-free-data-reservation-in-fallback-from-.patch @@ -0,0 +1,47 @@ +From c4af4ab46ec7945b44c98ed4572a894c0b56488d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 12 Dec 2025 17:10:10 +0000 +Subject: btrfs: do not free data reservation in fallback from inline due to + -ENOSPC + +From: Filipe Manana + +[ Upstream commit f8da41de0bff9eb1d774a7253da0c9f637c4470a ] + +If we fail to create an inline extent due to -ENOSPC, we will attempt to +go through the normal COW path, reserve an extent, create an ordered +extent, etc. However we were always freeing the reserved qgroup data, +which is wrong since we will use data. Fix this by freeing the reserved +qgroup data in __cow_file_range_inline() only if we are not doing the +fallback (ret is <= 0). + +Reviewed-by: Qu Wenruo +Signed-off-by: Filipe Manana +Reviewed-by: David Sterba +Signed-off-by: David Sterba +Signed-off-by: Sasha Levin +--- + fs/btrfs/inode.c | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c +index 45c6cbbd686fd..6a5364b466be1 100644 +--- a/fs/btrfs/inode.c ++++ b/fs/btrfs/inode.c +@@ -468,8 +468,12 @@ static noinline int cow_file_range_inline(struct btrfs_inode *inode, u64 size, + * it won't count as data extent, free them directly here. + * And at reserve time, it's always aligned to page size, so + * just free one page here. ++ * ++ * If we fallback to non-inline (ret == 1) due to -ENOSPC, then we need ++ * to keep the data reservation. + */ +- btrfs_qgroup_free_data(inode, NULL, 0, fs_info->sectorsize, NULL); ++ if (ret <= 0) ++ btrfs_qgroup_free_data(inode, NULL, 0, fs_info->sectorsize, NULL); + btrfs_free_path(path); + if (trans) + btrfs_end_transaction(trans); +-- +2.53.0 + diff --git a/queue-6.1/btrfs-fix-the-qgroup-data-free-range-for-inline-data.patch b/queue-6.1/btrfs-fix-the-qgroup-data-free-range-for-inline-data.patch new file mode 100644 index 0000000000..969825460b --- /dev/null +++ b/queue-6.1/btrfs-fix-the-qgroup-data-free-range-for-inline-data.patch @@ -0,0 +1,57 @@ +From 18590fc9a4247854888dae5498e7261ebe4586f3 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 15 Nov 2024 16:33:43 +1030 +Subject: btrfs: fix the qgroup data free range for inline data extents + +From: Qu Wenruo + +[ Upstream commit 0bb067ca64e35536f1f5d9ef6aaafc40f4833623 ] + +Inside function __cow_file_range_inline() since the inlined data no +longer take any data space, we need to free up the reserved space. + +However the code is still using the old page size == sector size +assumption, and will not handle subpage case well. + +Thankfully it is not going to cause any problems because we have two extra +safe nets: + +- Inline data extents creation is disabled for sector size < page size + cases for now + But it won't stay that for long. + +- btrfs_qgroup_free_data() will only clear ranges which have been already + reserved + So even if we pass a range larger than what we need, it should still + be fine, especially there is only reserved space for a single block at + file offset 0 of an inline data extent. + +But just for the sake of consistency, fix the call site to use +sectorsize instead of page size. + +Reviewed-by: Filipe Manana +Signed-off-by: Qu Wenruo +Reviewed-by: David Sterba +Signed-off-by: David Sterba +Stable-dep-of: f8da41de0bff ("btrfs: do not free data reservation in fallback from inline due to -ENOSPC") +Signed-off-by: Sasha Levin +--- + fs/btrfs/inode.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c +index 2b4a667367225..45c6cbbd686fd 100644 +--- a/fs/btrfs/inode.c ++++ b/fs/btrfs/inode.c +@@ -469,7 +469,7 @@ static noinline int cow_file_range_inline(struct btrfs_inode *inode, u64 size, + * And at reserve time, it's always aligned to page size, so + * just free one page here. + */ +- btrfs_qgroup_free_data(inode, NULL, 0, PAGE_SIZE, NULL); ++ btrfs_qgroup_free_data(inode, NULL, 0, fs_info->sectorsize, NULL); + btrfs_free_path(path); + if (trans) + btrfs_end_transaction(trans); +-- +2.53.0 + diff --git a/queue-6.1/mm-damon-sysfs-check-contexts-nr-before-accessing-co.patch b/queue-6.1/mm-damon-sysfs-check-contexts-nr-before-accessing-co.patch new file mode 100644 index 0000000000..ead3c6e8b7 --- /dev/null +++ b/queue-6.1/mm-damon-sysfs-check-contexts-nr-before-accessing-co.patch @@ -0,0 +1,64 @@ +From 6ed8008293e59341d41113a9959a8624a265b806 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 30 Mar 2026 22:29:59 -0700 +Subject: mm/damon/sysfs: check contexts->nr before accessing contexts_arr[0] + +From: Josh Law + +Multiple sysfs command paths dereference contexts_arr[0] without first +verifying that kdamond->contexts->nr == 1. A user can set nr_contexts to +0 via sysfs while DAMON is running, causing NULL pointer dereferences. + +In more detail, the issue can be triggered by privileged users like +below. + +First, start DAMON and make contexts directory empty +(kdamond->contexts->nr == 0). + + # damo start + # cd /sys/kernel/mm/damon/admin/kdamonds/0 + # echo 0 > contexts/nr_contexts + +Then, each of below commands will cause the NULL pointer dereference. + + # echo update_schemes_stats > state + # echo update_schemes_tried_regions > state + # echo update_schemes_tried_bytes > state + # echo update_schemes_effective_quotas > state + # echo update_tuned_intervals > state + +Guard all commands (except OFF) at the entry point of +damon_sysfs_handle_cmd(). + +(cherry picked from commit 1bfe9fb5ed2667fb075682408b776b5273162615) + +Link: https://lkml.kernel.org/r/20260321175427.86000-3-sj@kernel.org +Fixes: 0ac32b8affb5 ("mm/damon/sysfs: support DAMOS stats") +Signed-off-by: Josh Law +Reviewed-by: SeongJae Park +Signed-off-by: SeongJae Park +Cc: [5.18+] +Signed-off-by: Andrew Morton +Signed-off-by: SeongJae Park +Signed-off-by: Sasha Levin +--- + mm/damon/sysfs.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/mm/damon/sysfs.c b/mm/damon/sysfs.c +index a5a1e90e53e74..bdcf895a29a78 100644 +--- a/mm/damon/sysfs.c ++++ b/mm/damon/sysfs.c +@@ -2576,6 +2576,9 @@ static int damon_sysfs_handle_cmd(enum damon_sysfs_cmd cmd, + { + bool need_wait = true; + ++ if (cmd != DAMON_SYSFS_CMD_OFF && kdamond->contexts->nr != 1) ++ return -EINVAL; ++ + /* Handle commands that doesn't access DAMON context-internal data */ + switch (cmd) { + case DAMON_SYSFS_CMD_ON: +-- +2.53.0 + diff --git a/queue-6.1/net-enetc-fix-pf-of_device_is_available-teardown-pat.patch b/queue-6.1/net-enetc-fix-pf-of_device_is_available-teardown-pat.patch new file mode 100644 index 0000000000..0a421014e1 --- /dev/null +++ b/queue-6.1/net-enetc-fix-pf-of_device_is_available-teardown-pat.patch @@ -0,0 +1,60 @@ +From 2c9e5a02098f12a3ed7814e688cb17c0052fa870 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 30 Mar 2026 11:19:44 +0300 +Subject: net: enetc: fix PF !of_device_is_available() teardown path + +From: Vladimir Oltean + +Upstream commit e15c5506dd39 ("net: enetc: allocate vf_state during PF +probes") was backported incorrectly to kernels where enetc_pf_probe() +still has to manually check whether the OF node of the PCI device is +enabled. + +In kernels which contain commit bfce089ddd0e ("net: enetc: remove +of_device_is_available() handling") and its dependent change, commit +6fffbc7ae137 ("PCI: Honor firmware's device disabled status"), the +"err_device_disabled" label has disappeared. Yet, linux-6.1.y and +earlier still contains it. + +The trouble is that upstream commit e15c5506dd39 ("net: enetc: allocate +vf_state during PF probes"), backported as 35668e29e979 in linux-6.1.y, +introduces new code for the err_setup_mac_addresses and err_alloc_netdev +labels which calls kfree(pf->vf_state). This code must not execute for +the err_device_disabled label, because at that stage, the pf structure +has not yet been allocated, and is an uninitialized pointer. + +By moving the err_device_disabled label to undo just the previous +operation, i.e. a successful enetc_psi_create() call with +enetc_psi_destroy(), the dereference of uninitialized pf->vf_state is +avoided. + +Fixes: 35668e29e979 ("net: enetc: allocate vf_state during PF probes") +Reported-by: Nathan Chancellor +Closes: https://lore.kernel.org/linux-patches/20260330073356.GA1017537@ax162/ +Signed-off-by: Vladimir Oltean +Reviewed-by: Nathan Chancellor +Tested-by: Nathan Chancellor # build +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/freescale/enetc/enetc_pf.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/net/ethernet/freescale/enetc/enetc_pf.c b/drivers/net/ethernet/freescale/enetc/enetc_pf.c +index 99422c0b4a265..8cb4c759b165e 100644 +--- a/drivers/net/ethernet/freescale/enetc/enetc_pf.c ++++ b/drivers/net/ethernet/freescale/enetc/enetc_pf.c +@@ -1393,10 +1393,10 @@ static int enetc_pf_probe(struct pci_dev *pdev, + si->ndev = NULL; + free_netdev(ndev); + err_alloc_netdev: +-err_device_disabled: + err_setup_mac_addresses: + kfree(pf->vf_state); + err_alloc_vf_state: ++err_device_disabled: + enetc_psi_destroy(pdev); + err_psi_create: + return err; +-- +2.53.0 + diff --git a/queue-6.1/nvme-fix-admin-queue-leak-on-controller-reset.patch b/queue-6.1/nvme-fix-admin-queue-leak-on-controller-reset.patch new file mode 100644 index 0000000000..862b579031 --- /dev/null +++ b/queue-6.1/nvme-fix-admin-queue-leak-on-controller-reset.patch @@ -0,0 +1,73 @@ +From 7a0120a30775577eb10798c974337040ab8b3fde Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 2 Apr 2026 13:57:21 +0000 +Subject: nvme: fix admin queue leak on controller reset + +From: Ming Lei + +[ Upstream commit b84bb7bd913d8ca2f976ee6faf4a174f91c02b8d ] + +When nvme_alloc_admin_tag_set() is called during a controller reset, +a previous admin queue may still exist. Release it properly before +allocating a new one to avoid orphaning the old queue. + +This fixes a regression introduced by commit 03b3bcd319b3 ("nvme: fix +admin request_queue lifetime"). + +[ Have to do analogous work in nvme_pci_alloc_admin_tag_set in pci.c due + to missing upstream commit 0da7feaa5913 ("nvme-pci: use the tagset + alloc/free helpers") ] + +Cc: Keith Busch +Fixes: 03b3bcd319b3 ("nvme: fix admin request_queue lifetime"). +Reported-and-tested-by: Yi Zhang +Closes: https://lore.kernel.org/linux-block/CAHj4cs9wv3SdPo+N01Fw2SHBYDs9tj2M_e1-GdQOkRy=DsBB1w@mail.gmail.com/ +Signed-off-by: Ming Lei +Signed-off-by: Keith Busch +Signed-off-by: Maximilian Heyne +Tested-by: Fedor Pchelkin +Signed-off-by: Sasha Levin +--- + drivers/nvme/host/core.c | 7 +++++++ + drivers/nvme/host/pci.c | 7 +++++++ + 2 files changed, 14 insertions(+) + +diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c +index f17318f6c82b0..09439fa7d083a 100644 +--- a/drivers/nvme/host/core.c ++++ b/drivers/nvme/host/core.c +@@ -5012,6 +5012,13 @@ int nvme_alloc_admin_tag_set(struct nvme_ctrl *ctrl, struct blk_mq_tag_set *set, + if (ret) + return ret; + ++ /* ++ * If a previous admin queue exists (e.g., from before a reset), ++ * put it now before allocating a new one to avoid orphaning it. ++ */ ++ if (ctrl->admin_q) ++ blk_put_queue(ctrl->admin_q); ++ + ctrl->admin_q = blk_mq_init_queue(set); + if (IS_ERR(ctrl->admin_q)) { + ret = PTR_ERR(ctrl->admin_q); +diff --git a/drivers/nvme/host/pci.c b/drivers/nvme/host/pci.c +index 2a74668739919..91f3ed726e700 100644 +--- a/drivers/nvme/host/pci.c ++++ b/drivers/nvme/host/pci.c +@@ -1805,6 +1805,13 @@ static int nvme_pci_alloc_admin_tag_set(struct nvme_dev *dev) + return -ENOMEM; + dev->ctrl.admin_tagset = set; + ++ /* ++ * If a previous admin queue exists (e.g., from before a reset), ++ * put it now before allocating a new one to avoid orphaning it. ++ */ ++ if (dev->ctrl.admin_q) ++ blk_put_queue(dev->ctrl.admin_q); ++ + dev->ctrl.admin_q = blk_mq_init_queue(set); + if (IS_ERR(dev->ctrl.admin_q)) { + blk_mq_free_tag_set(set); +-- +2.53.0 + diff --git a/queue-6.1/nvme-fix-admin-request_queue-lifetime.patch-5284 b/queue-6.1/nvme-fix-admin-request_queue-lifetime.patch-5284 new file mode 100644 index 0000000000..3a24bdb8bb --- /dev/null +++ b/queue-6.1/nvme-fix-admin-request_queue-lifetime.patch-5284 @@ -0,0 +1,117 @@ +From 0a9bf307cef078f3698efbdc832f3d6d876f459b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 2 Apr 2026 13:57:19 +0000 +Subject: nvme: fix admin request_queue lifetime + +From: Keith Busch + +[ Upstream commit 03b3bcd319b3ab5182bc9aaa0421351572c78ac0] + +The namespaces can access the controller's admin request_queue, and +stale references on the namespaces may exist after tearing down the +controller. Ensure the admin request_queue is active by moving the +controller's 'put' to after all controller references have been released +to ensure no one is can access the request_queue. This fixes a reported +use-after-free bug: + + BUG: KASAN: slab-use-after-free in blk_queue_enter+0x41c/0x4a0 + Read of size 8 at addr ffff88c0a53819f8 by task nvme/3287 + CPU: 67 UID: 0 PID: 3287 Comm: nvme Tainted: G E 6.13.2-ga1582f1a031e #15 + Tainted: [E]=UNSIGNED_MODULE + Hardware name: Jabil /EGS 2S MB1, BIOS 1.00 06/18/2025 + Call Trace: + + dump_stack_lvl+0x4f/0x60 + print_report+0xc4/0x620 + ? _raw_spin_lock_irqsave+0x70/0xb0 + ? _raw_read_unlock_irqrestore+0x30/0x30 + ? blk_queue_enter+0x41c/0x4a0 + kasan_report+0xab/0xe0 + ? blk_queue_enter+0x41c/0x4a0 + blk_queue_enter+0x41c/0x4a0 + ? __irq_work_queue_local+0x75/0x1d0 + ? blk_queue_start_drain+0x70/0x70 + ? irq_work_queue+0x18/0x20 + ? vprintk_emit.part.0+0x1cc/0x350 + ? wake_up_klogd_work_func+0x60/0x60 + blk_mq_alloc_request+0x2b7/0x6b0 + ? __blk_mq_alloc_requests+0x1060/0x1060 + ? __switch_to+0x5b7/0x1060 + nvme_submit_user_cmd+0xa9/0x330 + nvme_user_cmd.isra.0+0x240/0x3f0 + ? force_sigsegv+0xe0/0xe0 + ? nvme_user_cmd64+0x400/0x400 + ? vfs_fileattr_set+0x9b0/0x9b0 + ? cgroup_update_frozen_flag+0x24/0x1c0 + ? cgroup_leave_frozen+0x204/0x330 + ? nvme_ioctl+0x7c/0x2c0 + blkdev_ioctl+0x1a8/0x4d0 + ? blkdev_common_ioctl+0x1930/0x1930 + ? fdget+0x54/0x380 + __x64_sys_ioctl+0x129/0x190 + do_syscall_64+0x5b/0x160 + entry_SYSCALL_64_after_hwframe+0x4b/0x53 + RIP: 0033:0x7f765f703b0b + Code: ff ff ff 85 c0 79 9b 49 c7 c4 ff ff ff ff 5b 5d 4c 89 e0 41 5c c3 66 0f 1f 84 00 00 00 00 00 f3 0f 1e fa b8 10 00 00 00 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 8b 0d dd 52 0f 00 f7 d8 64 89 01 48 + RSP: 002b:00007ffe2cefe808 EFLAGS: 00000202 ORIG_RAX: 0000000000000010 + RAX: ffffffffffffffda RBX: 00007ffe2cefe860 RCX: 00007f765f703b0b + RDX: 00007ffe2cefe860 RSI: 00000000c0484e41 RDI: 0000000000000003 + RBP: 0000000000000000 R08: 0000000000000003 R09: 0000000000000000 + R10: 00007f765f611d50 R11: 0000000000000202 R12: 0000000000000003 + R13: 00000000c0484e41 R14: 0000000000000001 R15: 00007ffe2cefea60 + + +[ Because we're missing commit 0da7feaa5913 ("nvme-pci: use the tagset + alloc/free helpers") we need to additionally remove the blk_put_queue + from nvme_dev_remove_admin in pci.c to properly fix the UAF ] + +Reported-by: Casey Chen +Reviewed-by: Christoph Hellwig +Reviewed-by: Hannes Reinecke +Reviewed-by: Ming Lei +Reviewed-by: Chaitanya Kulkarni +Signed-off-by: Keith Busch +Signed-off-by: Maximilian Heyne +Tested-by: Fedor Pchelkin +Signed-off-by: Sasha Levin +--- + drivers/nvme/host/core.c | 3 ++- + drivers/nvme/host/pci.c | 1 - + 2 files changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c +index 044e1a9c099b3..f17318f6c82b0 100644 +--- a/drivers/nvme/host/core.c ++++ b/drivers/nvme/host/core.c +@@ -5043,7 +5043,6 @@ EXPORT_SYMBOL_GPL(nvme_alloc_admin_tag_set); + void nvme_remove_admin_tag_set(struct nvme_ctrl *ctrl) + { + blk_mq_destroy_queue(ctrl->admin_q); +- blk_put_queue(ctrl->admin_q); + if (ctrl->ops->flags & NVME_F_FABRICS) { + blk_mq_destroy_queue(ctrl->fabrics_q); + blk_put_queue(ctrl->fabrics_q); +@@ -5186,6 +5185,8 @@ static void nvme_free_ctrl(struct device *dev) + container_of(dev, struct nvme_ctrl, ctrl_device); + struct nvme_subsystem *subsys = ctrl->subsys; + ++ if (ctrl->admin_q) ++ blk_put_queue(ctrl->admin_q); + if (!subsys || ctrl->instance != subsys->instance) + ida_free(&nvme_instance_ida, ctrl->instance); + +diff --git a/drivers/nvme/host/pci.c b/drivers/nvme/host/pci.c +index 8adce45f666c8..2a74668739919 100644 +--- a/drivers/nvme/host/pci.c ++++ b/drivers/nvme/host/pci.c +@@ -1783,7 +1783,6 @@ static void nvme_dev_remove_admin(struct nvme_dev *dev) + */ + nvme_start_admin_queue(&dev->ctrl); + blk_mq_destroy_queue(dev->ctrl.admin_q); +- blk_put_queue(dev->ctrl.admin_q); + blk_mq_free_tag_set(&dev->admin_tagset); + } + } +-- +2.53.0 + diff --git a/queue-6.1/nvme-pci-put-the-admin-queue-in-nvme_dev_remove_admi.patch b/queue-6.1/nvme-pci-put-the-admin-queue-in-nvme_dev_remove_admi.patch new file mode 100644 index 0000000000..3ade9e6aa2 --- /dev/null +++ b/queue-6.1/nvme-pci-put-the-admin-queue-in-nvme_dev_remove_admi.patch @@ -0,0 +1,53 @@ +From d1acbaf971dc19568335f1bbc7928e64eac15d5a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 2 Apr 2026 13:57:18 +0000 +Subject: nvme-pci: put the admin queue in nvme_dev_remove_admin + +From: Christoph Hellwig + +[ Upstream commit 96ef1be53663a9343dffcf106e2f1b59da4b8799 ] + +Once the controller is shutdown no one can access the admin queue. Tear +it down in nvme_dev_remove_admin, which matches the flow in the other +drivers. + +Tested-by Gerd Bayer +[ Context change due to missing commit 94cc781f69f4 ("nvme: move OPAL + setup from PCIe to core")] + +Signed-off-by: Christoph Hellwig +Reviewed-by: Keith Busch +Reviewed-by: Sagi Grimberg +Reviewed-by: Chaitanya Kulkarni +Stable-dep-of: 03b3bcd319b3 ("nvme: fix admin request_queue lifetime") +Signed-off-by: Maximilian Heyne +Tested-by: Fedor Pchelkin +Signed-off-by: Sasha Levin +--- + drivers/nvme/host/pci.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +diff --git a/drivers/nvme/host/pci.c b/drivers/nvme/host/pci.c +index 04f7db2ff9cc2..8adce45f666c8 100644 +--- a/drivers/nvme/host/pci.c ++++ b/drivers/nvme/host/pci.c +@@ -1783,6 +1783,7 @@ static void nvme_dev_remove_admin(struct nvme_dev *dev) + */ + nvme_start_admin_queue(&dev->ctrl); + blk_mq_destroy_queue(dev->ctrl.admin_q); ++ blk_put_queue(dev->ctrl.admin_q); + blk_mq_free_tag_set(&dev->admin_tagset); + } + } +@@ -2838,8 +2839,6 @@ static void nvme_pci_free_ctrl(struct nvme_ctrl *ctrl) + + nvme_dbbuf_dma_free(dev); + nvme_free_tagset(dev); +- if (dev->ctrl.admin_q) +- blk_put_queue(dev->ctrl.admin_q); + free_opal_dev(dev->ctrl.opal_dev); + mempool_destroy(dev->iod_mempool); + put_device(dev->dev); +-- +2.53.0 + diff --git a/queue-6.1/nvme-pci-remove-an-extra-queue-reference.patch b/queue-6.1/nvme-pci-remove-an-extra-queue-reference.patch new file mode 100644 index 0000000000..f58451f469 --- /dev/null +++ b/queue-6.1/nvme-pci-remove-an-extra-queue-reference.patch @@ -0,0 +1,53 @@ +From 638d716caeba40dba06aee9474333deef640eff2 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 2 Apr 2026 13:57:16 +0000 +Subject: nvme-pci: remove an extra queue reference + +From: Christoph Hellwig + +[ Upstream commit 7dcebef90d35de13a326f765dd787538880566f9 ] + +Now that blk_mq_destroy_queue does not release the queue reference, there +is no need for a second admin queue reference to be held by the nvme_dev. + +Signed-off-by: Christoph Hellwig +Reviewed-by: Sagi Grimberg +Reviewed-by: Chaitanya Kulkarni +Reviewed-by: Keith Busch +Link: https://lore.kernel.org/r/20221018135720.670094-4-hch@lst.de +Signed-off-by: Jens Axboe +Stable-dep-of: 03b3bcd319b3 ("nvme: fix admin request_queue lifetime") +Signed-off-by: Maximilian Heyne +Tested-by: Fedor Pchelkin +Signed-off-by: Sasha Levin +--- + drivers/nvme/host/pci.c | 6 ------ + 1 file changed, 6 deletions(-) + +diff --git a/drivers/nvme/host/pci.c b/drivers/nvme/host/pci.c +index 27a4706bc9131..04f7db2ff9cc2 100644 +--- a/drivers/nvme/host/pci.c ++++ b/drivers/nvme/host/pci.c +@@ -1783,7 +1783,6 @@ static void nvme_dev_remove_admin(struct nvme_dev *dev) + */ + nvme_start_admin_queue(&dev->ctrl); + blk_mq_destroy_queue(dev->ctrl.admin_q); +- blk_put_queue(dev->ctrl.admin_q); + blk_mq_free_tag_set(&dev->admin_tagset); + } + } +@@ -1812,11 +1811,6 @@ static int nvme_pci_alloc_admin_tag_set(struct nvme_dev *dev) + dev->ctrl.admin_q = NULL; + return -ENOMEM; + } +- if (!blk_get_queue(dev->ctrl.admin_q)) { +- nvme_dev_remove_admin(dev); +- dev->ctrl.admin_q = NULL; +- return -ENODEV; +- } + return 0; + } + +-- +2.53.0 + diff --git a/queue-6.1/revert-nvme-fix-admin-request_queue-lifetime.patch b/queue-6.1/revert-nvme-fix-admin-request_queue-lifetime.patch new file mode 100644 index 0000000000..477c02f0d2 --- /dev/null +++ b/queue-6.1/revert-nvme-fix-admin-request_queue-lifetime.patch @@ -0,0 +1,89 @@ +From 32f55d449cd3c51f9b4b6f71a6e1c46982322e34 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 2 Apr 2026 13:57:13 +0000 +Subject: Revert "nvme: fix admin request_queue lifetime" + +From: Heyne, Maximilian + +This reverts commit ff037b5f47eeccc1636c03f84cd47db094eb73c9. + +The backport of upstream commit 03b3bcd319b3 ("nvme: fix admin +request_queue lifetime") to 6.1 is broken in 2 ways. First of all it +doesn't actually fix the issue because blk_put_queue will still be +called as part of blk_mq_destroy_queue in nvme_remove_admin_tag_set +leading to the UAF. +Second, the backport leads to a refcount underflow when unbinding a pci +nvme device: + + refcount_t: underflow; use-after-free. + WARNING: CPU: 2 PID: 1486 at lib/refcount.c:28 refcount_warn_saturate+0xba/0x110 + Modules linked in: bochs drm_vram_helper simpledrm skx_edac_common drm_shmem_helper drm_kms_helper kvm_intel cfbfillrect syscopyarea cfbimgblt sysfillrect sysimgblt fb_sys_fops cfbcopyarea drm_ttm_helper fb ttm kvm fbdev drm mousedev nls_ascii psmouse irqbypass nls_cp437 atkbd crc32_pclmul crc32c_intel libps2 vfat fat sunrpc virtio_net ata_piix vivaldi_fmap drm_panel_orientation_quirks libata backlight i2c_piix4 net_failover i8042 ghash_clmulni_intel failover serio i2c_core button sch_fq_codel + CPU: 2 PID: 1486 Comm: bash Not tainted 6.1.167 #2 + Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS edk2-20240813-306.amzn2 08/13/2024 + RIP: 0010:refcount_warn_saturate+0xba/0x110 + Code: 01 01 e8 89 79 ad ff 0f 0b e9 82 f4 7e 00 80 3d 73 03 cc 01 00 75 85 48 c7 c7 e0 5d 3b 8e c6 05 63 03 cc 01 01 e8 66 79 ad ff <0f> 0b c3 cc cc cc cc 80 3d 4e 03 cc 01 00 0f 85 5e ff ff ff 48 c7 + RSP: 0018:ffffd0cc011bfd18 EFLAGS: 00010286 + RAX: 0000000000000000 RBX: ffff8ada07b33210 RCX: 0000000000000027 + RDX: ffff8adb37d1f728 RSI: 0000000000000001 RDI: ffff8adb37d1f720 + RBP: ffff8ada07b33000 R08: 0000000000000000 R09: 00000000fffeffff + R10: ffffd0cc011bfba8 R11: ffffffff8f1781a8 R12: ffffd0cc011bfd38 + R13: ffff8ada03080800 R14: ffff8ada07b33210 R15: ffff8ada07b33b10 + FS: 00007f50f6964740(0000) GS:ffff8adb37d00000(0000) knlGS:0000000000000000 + CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 + CR2: 000055cdb54e6ae0 CR3: 000000010224e001 CR4: 0000000000770ee0 + DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 + DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 + PKRU: 55555554 + Call Trace: + + nvme_pci_free_ctrl+0x45/0x80 + nvme_free_ctrl+0x1aa/0x2b0 + device_release+0x34/0x90 + kobject_cleanup+0x3a/0x130 + pci_device_remove+0x3e/0xb0 + device_release_driver_internal+0x1aa/0x230 + unbind_store+0x11f/0x130 + kernfs_fop_write_iter+0x13a/0x1d0 + vfs_write+0x2a6/0x3b0 + ksys_write+0x5f/0xe0 + do_syscall_64+0x35/0x80 + entry_SYSCALL_64_after_hwframe+0x6e/0xd8 + RIP: 0033:0x7f50f66ff897 + Code: 0f 00 f7 d8 64 89 02 48 c7 c0 ff ff ff ff eb b7 0f 1f 00 f3 0f 1e fa 64 8b 04 25 18 00 00 00 85 c0 75 10 b8 01 00 00 00 0f 05 <48> 3d 00 f0 ff ff 77 51 c3 48 83 ec 28 48 89 54 24 18 48 89 74 24 + RSP: 002b:00007fffaef903d8 EFLAGS: 00000246 ORIG_RAX: 0000000000000001 + RAX: ffffffffffffffda RBX: 00007f50f67fd780 RCX: 00007f50f66ff897 + RDX: 000000000000000d RSI: 0000557f72ef6b90 RDI: 0000000000000001 + RBP: 000000000000000d R08: 0000000000000000 R09: 00007f50f67b2d20 + R10: 00007f50f67b2c20 R11: 0000000000000246 R12: 000000000000000d + R13: 0000557f72ef6b90 R14: 000000000000000d R15: 00007f50f67f89c0 + + +The reason for this is that nvme_free_ctrl calls ->free_ctrl which +resolves to nvme_pci_free_ctrl in aforementioned case which also has a +blk_put_queue, so the admin queue is put twice. This is because on 6.1 +we're missing the commit 96ef1be53663 ("nvme-pci: put the admin queue in +nvme_dev_remove_admin"). + +Signed-off-by: Maximilian Heyne +Tested-by: Fedor Pchelkin +Signed-off-by: Sasha Levin +--- + drivers/nvme/host/core.c | 2 -- + 1 file changed, 2 deletions(-) + +diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c +index 9df33b293ee3e..938af571dc13e 100644 +--- a/drivers/nvme/host/core.c ++++ b/drivers/nvme/host/core.c +@@ -5180,8 +5180,6 @@ static void nvme_free_ctrl(struct device *dev) + container_of(dev, struct nvme_ctrl, ctrl_device); + struct nvme_subsystem *subsys = ctrl->subsys; + +- if (ctrl->admin_q) +- blk_put_queue(ctrl->admin_q); + if (!subsys || ctrl->instance != subsys->instance) + ida_free(&nvme_instance_ida, ctrl->instance); + +-- +2.53.0 + diff --git a/queue-6.1/series b/queue-6.1/series index fce29b38c3..cf078d3d30 100644 --- a/queue-6.1/series +++ b/queue-6.1/series @@ -255,3 +255,13 @@ thunderbolt-fix-property-read-in-nhi_wake_supported.patch usb-dummy-hcd-fix-locking-synchronization-error.patch usb-dummy-hcd-fix-interrupt-synchronization-error.patch usb-gadget-dummy_hcd-fix-premature-urb-completion-when-zlp-follows-partial-transfer.patch +btrfs-fix-the-qgroup-data-free-range-for-inline-data.patch +btrfs-do-not-free-data-reservation-in-fallback-from-.patch +revert-nvme-fix-admin-request_queue-lifetime.patch +blk-mq-move-the-call-to-blk_put_queue-out-of-blk_mq_.patch +nvme-pci-remove-an-extra-queue-reference.patch +nvme-pci-put-the-admin-queue-in-nvme_dev_remove_admi.patch +nvme-fix-admin-request_queue-lifetime.patch-5284 +nvme-fix-admin-queue-leak-on-controller-reset.patch +mm-damon-sysfs-check-contexts-nr-before-accessing-co.patch +net-enetc-fix-pf-of_device_is_available-teardown-pat.patch diff --git a/queue-6.12/btrfs-do-not-free-data-reservation-in-fallback-from-.patch b/queue-6.12/btrfs-do-not-free-data-reservation-in-fallback-from-.patch new file mode 100644 index 0000000000..2f1ecea7f7 --- /dev/null +++ b/queue-6.12/btrfs-do-not-free-data-reservation-in-fallback-from-.patch @@ -0,0 +1,47 @@ +From 06d29856f57437ba2671f84abe7c35db1b531cc6 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 12 Dec 2025 17:10:10 +0000 +Subject: btrfs: do not free data reservation in fallback from inline due to + -ENOSPC + +From: Filipe Manana + +[ Upstream commit f8da41de0bff9eb1d774a7253da0c9f637c4470a ] + +If we fail to create an inline extent due to -ENOSPC, we will attempt to +go through the normal COW path, reserve an extent, create an ordered +extent, etc. However we were always freeing the reserved qgroup data, +which is wrong since we will use data. Fix this by freeing the reserved +qgroup data in __cow_file_range_inline() only if we are not doing the +fallback (ret is <= 0). + +Reviewed-by: Qu Wenruo +Signed-off-by: Filipe Manana +Reviewed-by: David Sterba +Signed-off-by: David Sterba +Signed-off-by: Sasha Levin +--- + fs/btrfs/inode.c | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c +index fae4e8ac33844..28024c827b756 100644 +--- a/fs/btrfs/inode.c ++++ b/fs/btrfs/inode.c +@@ -717,8 +717,12 @@ static noinline int __cow_file_range_inline(struct btrfs_inode *inode, u64 offse + * it won't count as data extent, free them directly here. + * And at reserve time, it's always aligned to page size, so + * just free one page here. ++ * ++ * If we fallback to non-inline (ret == 1) due to -ENOSPC, then we need ++ * to keep the data reservation. + */ +- btrfs_qgroup_free_data(inode, NULL, 0, fs_info->sectorsize, NULL); ++ if (ret <= 0) ++ btrfs_qgroup_free_data(inode, NULL, 0, fs_info->sectorsize, NULL); + btrfs_free_path(path); + if (trans) + btrfs_end_transaction(trans); +-- +2.53.0 + diff --git a/queue-6.12/btrfs-fix-the-qgroup-data-free-range-for-inline-data.patch b/queue-6.12/btrfs-fix-the-qgroup-data-free-range-for-inline-data.patch new file mode 100644 index 0000000000..271fd1bb01 --- /dev/null +++ b/queue-6.12/btrfs-fix-the-qgroup-data-free-range-for-inline-data.patch @@ -0,0 +1,57 @@ +From ccb501d7bec792f653531278f07fe5221b0cb375 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 15 Nov 2024 16:33:43 +1030 +Subject: btrfs: fix the qgroup data free range for inline data extents + +From: Qu Wenruo + +[ Upstream commit 0bb067ca64e35536f1f5d9ef6aaafc40f4833623 ] + +Inside function __cow_file_range_inline() since the inlined data no +longer take any data space, we need to free up the reserved space. + +However the code is still using the old page size == sector size +assumption, and will not handle subpage case well. + +Thankfully it is not going to cause any problems because we have two extra +safe nets: + +- Inline data extents creation is disabled for sector size < page size + cases for now + But it won't stay that for long. + +- btrfs_qgroup_free_data() will only clear ranges which have been already + reserved + So even if we pass a range larger than what we need, it should still + be fine, especially there is only reserved space for a single block at + file offset 0 of an inline data extent. + +But just for the sake of consistency, fix the call site to use +sectorsize instead of page size. + +Reviewed-by: Filipe Manana +Signed-off-by: Qu Wenruo +Reviewed-by: David Sterba +Signed-off-by: David Sterba +Stable-dep-of: f8da41de0bff ("btrfs: do not free data reservation in fallback from inline due to -ENOSPC") +Signed-off-by: Sasha Levin +--- + fs/btrfs/inode.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c +index 4bff5d5953ed8..fae4e8ac33844 100644 +--- a/fs/btrfs/inode.c ++++ b/fs/btrfs/inode.c +@@ -718,7 +718,7 @@ static noinline int __cow_file_range_inline(struct btrfs_inode *inode, u64 offse + * And at reserve time, it's always aligned to page size, so + * just free one page here. + */ +- btrfs_qgroup_free_data(inode, NULL, 0, PAGE_SIZE, NULL); ++ btrfs_qgroup_free_data(inode, NULL, 0, fs_info->sectorsize, NULL); + btrfs_free_path(path); + if (trans) + btrfs_end_transaction(trans); +-- +2.53.0 + diff --git a/queue-6.12/ice-fix-memory-leak-in-ice_set_ringparam.patch b/queue-6.12/ice-fix-memory-leak-in-ice_set_ringparam.patch new file mode 100644 index 0000000000..50eb0168cf --- /dev/null +++ b/queue-6.12/ice-fix-memory-leak-in-ice_set_ringparam.patch @@ -0,0 +1,73 @@ +From 38642bde68980cd0706445b151e8f03fd40e9d6f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 22 Jan 2026 03:26:44 +0000 +Subject: ice: Fix memory leak in ice_set_ringparam() + +From: Zilin Guan + +[ Upstream commit fe868b499d16f55bbeea89992edb98043c9de416 ] + +In ice_set_ringparam, tx_rings and xdp_rings are allocated before +rx_rings. If the allocation of rx_rings fails, the code jumps to +the done label leaking both tx_rings and xdp_rings. Furthermore, if +the setup of an individual Rx ring fails during the loop, the code jumps +to the free_tx label which releases tx_rings but leaks xdp_rings. + +Fix this by introducing a free_xdp label and updating the error paths to +ensure both xdp_rings and tx_rings are properly freed if rx_rings +allocation or setup fails. + +Compile tested only. Issue found using a prototype static analysis tool +and code review. + +Fixes: fcea6f3da546 ("ice: Add stats and ethtool support") +Fixes: efc2214b6047 ("ice: Add support for XDP") +Signed-off-by: Zilin Guan +Reviewed-by: Paul Menzel +Reviewed-by: Aleksandr Loktionov +Tested-by: Rinitha S (A Contingent worker at Intel) +Signed-off-by: Tony Nguyen +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/intel/ice/ice_ethtool.c | 11 +++++++++-- + 1 file changed, 9 insertions(+), 2 deletions(-) + +diff --git a/drivers/net/ethernet/intel/ice/ice_ethtool.c b/drivers/net/ethernet/intel/ice/ice_ethtool.c +index 606994fa99da9..c0bf93b38cbd8 100644 +--- a/drivers/net/ethernet/intel/ice/ice_ethtool.c ++++ b/drivers/net/ethernet/intel/ice/ice_ethtool.c +@@ -3331,7 +3331,7 @@ ice_set_ringparam(struct net_device *netdev, struct ethtool_ringparam *ring, + rx_rings = kcalloc(vsi->num_rxq, sizeof(*rx_rings), GFP_KERNEL); + if (!rx_rings) { + err = -ENOMEM; +- goto done; ++ goto free_xdp; + } + + ice_for_each_rxq(vsi, i) { +@@ -3361,7 +3361,7 @@ ice_set_ringparam(struct net_device *netdev, struct ethtool_ringparam *ring, + } + kfree(rx_rings); + err = -ENOMEM; +- goto free_tx; ++ goto free_xdp; + } + } + +@@ -3412,6 +3412,13 @@ ice_set_ringparam(struct net_device *netdev, struct ethtool_ringparam *ring, + } + goto done; + ++free_xdp: ++ if (xdp_rings) { ++ ice_for_each_xdp_txq(vsi, i) ++ ice_free_tx_ring(&xdp_rings[i]); ++ kfree(xdp_rings); ++ } ++ + free_tx: + /* error cleanup if the Rx allocations failed after getting Tx */ + if (tx_rings) { +-- +2.53.0 + diff --git a/queue-6.12/series b/queue-6.12/series index 7ab4077409..a092681683 100644 --- a/queue-6.12/series +++ b/queue-6.12/series @@ -201,3 +201,6 @@ usb-dummy-hcd-fix-locking-synchronization-error.patch usb-dummy-hcd-fix-interrupt-synchronization-error.patch usb-gadget-dummy_hcd-fix-premature-urb-completion-when-zlp-follows-partial-transfer.patch usb-typec-ucsi-validate-connector-number-in-ucsi_notify_common.patch +ice-fix-memory-leak-in-ice_set_ringparam.patch +btrfs-fix-the-qgroup-data-free-range-for-inline-data.patch +btrfs-do-not-free-data-reservation-in-fallback-from-.patch diff --git a/queue-6.18/hid-appletb-kbd-add-.resume-method-in-pm.patch b/queue-6.18/hid-appletb-kbd-add-.resume-method-in-pm.patch new file mode 100644 index 0000000000..9e0029f452 --- /dev/null +++ b/queue-6.18/hid-appletb-kbd-add-.resume-method-in-pm.patch @@ -0,0 +1,47 @@ +From e9f148264b4848126d23b27c843b1031a5f310be Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 7 Apr 2026 16:38:01 +0530 +Subject: HID: appletb-kbd: add .resume method in PM + +From: Aditya Garg + +commit 1965445e13c09b79932ca8154977b4408cb9610c upstream. + +Upon resuming from suspend, the Touch Bar driver was missing a resume +method in order to restore the original mode the Touch Bar was on before +suspending. It is the same as the reset_resume method. + +Cc: stable@vger.kernel.org +Signed-off-by: Aditya Garg +Signed-off-by: Jiri Kosina +Signed-off-by: Sasha Levin +--- + drivers/hid/hid-appletb-kbd.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +diff --git a/drivers/hid/hid-appletb-kbd.c b/drivers/hid/hid-appletb-kbd.c +index b00687e67ce8e..0b10cff465e17 100644 +--- a/drivers/hid/hid-appletb-kbd.c ++++ b/drivers/hid/hid-appletb-kbd.c +@@ -477,7 +477,7 @@ static int appletb_kbd_suspend(struct hid_device *hdev, pm_message_t msg) + return 0; + } + +-static int appletb_kbd_reset_resume(struct hid_device *hdev) ++static int appletb_kbd_resume(struct hid_device *hdev) + { + struct appletb_kbd *kbd = hid_get_drvdata(hdev); + +@@ -503,7 +503,8 @@ static struct hid_driver appletb_kbd_hid_driver = { + .input_configured = appletb_kbd_input_configured, + #ifdef CONFIG_PM + .suspend = appletb_kbd_suspend, +- .reset_resume = appletb_kbd_reset_resume, ++ .resume = appletb_kbd_resume, ++ .reset_resume = appletb_kbd_resume, + #endif + .driver.dev_groups = appletb_kbd_groups, + }; +-- +2.53.0 + diff --git a/queue-6.18/ice-fix-memory-leak-in-ice_set_ringparam.patch b/queue-6.18/ice-fix-memory-leak-in-ice_set_ringparam.patch new file mode 100644 index 0000000000..96477ac5e2 --- /dev/null +++ b/queue-6.18/ice-fix-memory-leak-in-ice_set_ringparam.patch @@ -0,0 +1,73 @@ +From 335c57a07d9cebf261f602885324507124a973c6 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 22 Jan 2026 03:26:44 +0000 +Subject: ice: Fix memory leak in ice_set_ringparam() + +From: Zilin Guan + +[ Upstream commit fe868b499d16f55bbeea89992edb98043c9de416 ] + +In ice_set_ringparam, tx_rings and xdp_rings are allocated before +rx_rings. If the allocation of rx_rings fails, the code jumps to +the done label leaking both tx_rings and xdp_rings. Furthermore, if +the setup of an individual Rx ring fails during the loop, the code jumps +to the free_tx label which releases tx_rings but leaks xdp_rings. + +Fix this by introducing a free_xdp label and updating the error paths to +ensure both xdp_rings and tx_rings are properly freed if rx_rings +allocation or setup fails. + +Compile tested only. Issue found using a prototype static analysis tool +and code review. + +Fixes: fcea6f3da546 ("ice: Add stats and ethtool support") +Fixes: efc2214b6047 ("ice: Add support for XDP") +Signed-off-by: Zilin Guan +Reviewed-by: Paul Menzel +Reviewed-by: Aleksandr Loktionov +Tested-by: Rinitha S (A Contingent worker at Intel) +Signed-off-by: Tony Nguyen +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/intel/ice/ice_ethtool.c | 11 +++++++++-- + 1 file changed, 9 insertions(+), 2 deletions(-) + +diff --git a/drivers/net/ethernet/intel/ice/ice_ethtool.c b/drivers/net/ethernet/intel/ice/ice_ethtool.c +index b52fcf7b899f7..912bcf9fce52d 100644 +--- a/drivers/net/ethernet/intel/ice/ice_ethtool.c ++++ b/drivers/net/ethernet/intel/ice/ice_ethtool.c +@@ -3320,7 +3320,7 @@ ice_set_ringparam(struct net_device *netdev, struct ethtool_ringparam *ring, + rx_rings = kcalloc(vsi->num_rxq, sizeof(*rx_rings), GFP_KERNEL); + if (!rx_rings) { + err = -ENOMEM; +- goto done; ++ goto free_xdp; + } + + ice_for_each_rxq(vsi, i) { +@@ -3350,7 +3350,7 @@ ice_set_ringparam(struct net_device *netdev, struct ethtool_ringparam *ring, + } + kfree(rx_rings); + err = -ENOMEM; +- goto free_tx; ++ goto free_xdp; + } + } + +@@ -3401,6 +3401,13 @@ ice_set_ringparam(struct net_device *netdev, struct ethtool_ringparam *ring, + } + goto done; + ++free_xdp: ++ if (xdp_rings) { ++ ice_for_each_xdp_txq(vsi, i) ++ ice_free_tx_ring(&xdp_rings[i]); ++ kfree(xdp_rings); ++ } ++ + free_tx: + /* error cleanup if the Rx allocations failed after getting Tx */ + if (tx_rings) { +-- +2.53.0 + diff --git a/queue-6.18/series b/queue-6.18/series index 5904ed82f9..3477ecff48 100644 --- a/queue-6.18/series +++ b/queue-6.18/series @@ -248,3 +248,5 @@ usb-dummy-hcd-fix-locking-synchronization-error.patch usb-dummy-hcd-fix-interrupt-synchronization-error.patch usb-gadget-dummy_hcd-fix-premature-urb-completion-when-zlp-follows-partial-transfer.patch usb-typec-ucsi-validate-connector-number-in-ucsi_notify_common.patch +hid-appletb-kbd-add-.resume-method-in-pm.patch +ice-fix-memory-leak-in-ice_set_ringparam.patch diff --git a/queue-6.19/hid-appletb-kbd-add-.resume-method-in-pm.patch b/queue-6.19/hid-appletb-kbd-add-.resume-method-in-pm.patch new file mode 100644 index 0000000000..68d224b6ba --- /dev/null +++ b/queue-6.19/hid-appletb-kbd-add-.resume-method-in-pm.patch @@ -0,0 +1,47 @@ +From 8dea2bcf0f47cc052146003469d2e2c4f86fea0b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 7 Apr 2026 16:38:22 +0530 +Subject: HID: appletb-kbd: add .resume method in PM + +From: Aditya Garg + +commit 1965445e13c09b79932ca8154977b4408cb9610c upstream. + +Upon resuming from suspend, the Touch Bar driver was missing a resume +method in order to restore the original mode the Touch Bar was on before +suspending. It is the same as the reset_resume method. + +Cc: stable@vger.kernel.org +Signed-off-by: Aditya Garg +Signed-off-by: Jiri Kosina +Signed-off-by: Sasha Levin +--- + drivers/hid/hid-appletb-kbd.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +diff --git a/drivers/hid/hid-appletb-kbd.c b/drivers/hid/hid-appletb-kbd.c +index b00687e67ce8e..0b10cff465e17 100644 +--- a/drivers/hid/hid-appletb-kbd.c ++++ b/drivers/hid/hid-appletb-kbd.c +@@ -477,7 +477,7 @@ static int appletb_kbd_suspend(struct hid_device *hdev, pm_message_t msg) + return 0; + } + +-static int appletb_kbd_reset_resume(struct hid_device *hdev) ++static int appletb_kbd_resume(struct hid_device *hdev) + { + struct appletb_kbd *kbd = hid_get_drvdata(hdev); + +@@ -503,7 +503,8 @@ static struct hid_driver appletb_kbd_hid_driver = { + .input_configured = appletb_kbd_input_configured, + #ifdef CONFIG_PM + .suspend = appletb_kbd_suspend, +- .reset_resume = appletb_kbd_reset_resume, ++ .resume = appletb_kbd_resume, ++ .reset_resume = appletb_kbd_resume, + #endif + .driver.dev_groups = appletb_kbd_groups, + }; +-- +2.53.0 + diff --git a/queue-6.19/series b/queue-6.19/series index 75b015ddbd..08bc0ea890 100644 --- a/queue-6.19/series +++ b/queue-6.19/series @@ -293,3 +293,4 @@ usb-dummy-hcd-fix-locking-synchronization-error.patch usb-dummy-hcd-fix-interrupt-synchronization-error.patch usb-gadget-dummy_hcd-fix-premature-urb-completion-when-zlp-follows-partial-transfer.patch usb-typec-ucsi-validate-connector-number-in-ucsi_notify_common.patch +hid-appletb-kbd-add-.resume-method-in-pm.patch diff --git a/queue-6.6/btrfs-do-not-free-data-reservation-in-fallback-from-.patch b/queue-6.6/btrfs-do-not-free-data-reservation-in-fallback-from-.patch new file mode 100644 index 0000000000..9da88c81d0 --- /dev/null +++ b/queue-6.6/btrfs-do-not-free-data-reservation-in-fallback-from-.patch @@ -0,0 +1,47 @@ +From 6a413698745a72b2bf41029d7fb6eca5958d1325 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 12 Dec 2025 17:10:10 +0000 +Subject: btrfs: do not free data reservation in fallback from inline due to + -ENOSPC + +From: Filipe Manana + +[ Upstream commit f8da41de0bff9eb1d774a7253da0c9f637c4470a ] + +If we fail to create an inline extent due to -ENOSPC, we will attempt to +go through the normal COW path, reserve an extent, create an ordered +extent, etc. However we were always freeing the reserved qgroup data, +which is wrong since we will use data. Fix this by freeing the reserved +qgroup data in __cow_file_range_inline() only if we are not doing the +fallback (ret is <= 0). + +Reviewed-by: Qu Wenruo +Signed-off-by: Filipe Manana +Reviewed-by: David Sterba +Signed-off-by: David Sterba +Signed-off-by: Sasha Levin +--- + fs/btrfs/inode.c | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c +index 28625e504972e..46df425ab7bae 100644 +--- a/fs/btrfs/inode.c ++++ b/fs/btrfs/inode.c +@@ -691,8 +691,12 @@ static noinline int cow_file_range_inline(struct btrfs_inode *inode, u64 size, + * it won't count as data extent, free them directly here. + * And at reserve time, it's always aligned to page size, so + * just free one page here. ++ * ++ * If we fallback to non-inline (ret == 1) due to -ENOSPC, then we need ++ * to keep the data reservation. + */ +- btrfs_qgroup_free_data(inode, NULL, 0, fs_info->sectorsize, NULL); ++ if (ret <= 0) ++ btrfs_qgroup_free_data(inode, NULL, 0, fs_info->sectorsize, NULL); + btrfs_free_path(path); + if (trans) + btrfs_end_transaction(trans); +-- +2.53.0 + diff --git a/queue-6.6/btrfs-fix-the-qgroup-data-free-range-for-inline-data.patch b/queue-6.6/btrfs-fix-the-qgroup-data-free-range-for-inline-data.patch new file mode 100644 index 0000000000..03ca07abd6 --- /dev/null +++ b/queue-6.6/btrfs-fix-the-qgroup-data-free-range-for-inline-data.patch @@ -0,0 +1,57 @@ +From e629db7f42766fea6c0f06777201651d79fbf893 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 15 Nov 2024 16:33:43 +1030 +Subject: btrfs: fix the qgroup data free range for inline data extents + +From: Qu Wenruo + +[ Upstream commit 0bb067ca64e35536f1f5d9ef6aaafc40f4833623 ] + +Inside function __cow_file_range_inline() since the inlined data no +longer take any data space, we need to free up the reserved space. + +However the code is still using the old page size == sector size +assumption, and will not handle subpage case well. + +Thankfully it is not going to cause any problems because we have two extra +safe nets: + +- Inline data extents creation is disabled for sector size < page size + cases for now + But it won't stay that for long. + +- btrfs_qgroup_free_data() will only clear ranges which have been already + reserved + So even if we pass a range larger than what we need, it should still + be fine, especially there is only reserved space for a single block at + file offset 0 of an inline data extent. + +But just for the sake of consistency, fix the call site to use +sectorsize instead of page size. + +Reviewed-by: Filipe Manana +Signed-off-by: Qu Wenruo +Reviewed-by: David Sterba +Signed-off-by: David Sterba +Stable-dep-of: f8da41de0bff ("btrfs: do not free data reservation in fallback from inline due to -ENOSPC") +Signed-off-by: Sasha Levin +--- + fs/btrfs/inode.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c +index cf39f52fc0484..28625e504972e 100644 +--- a/fs/btrfs/inode.c ++++ b/fs/btrfs/inode.c +@@ -692,7 +692,7 @@ static noinline int cow_file_range_inline(struct btrfs_inode *inode, u64 size, + * And at reserve time, it's always aligned to page size, so + * just free one page here. + */ +- btrfs_qgroup_free_data(inode, NULL, 0, PAGE_SIZE, NULL); ++ btrfs_qgroup_free_data(inode, NULL, 0, fs_info->sectorsize, NULL); + btrfs_free_path(path); + if (trans) + btrfs_end_transaction(trans); +-- +2.53.0 + diff --git a/queue-6.6/gfs2-improve-gfs2_consist_inode-usage.patch b/queue-6.6/gfs2-improve-gfs2_consist_inode-usage.patch new file mode 100644 index 0000000000..efd2deeb11 --- /dev/null +++ b/queue-6.6/gfs2-improve-gfs2_consist_inode-usage.patch @@ -0,0 +1,213 @@ +From 8708ad1a4c2afa3cfb31bf8f8a2b216525f4dc50 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 3 Apr 2026 13:51:53 +0800 +Subject: gfs2: Improve gfs2_consist_inode() usage + +From: Andrew Price + +[ Upstream commit 10398ef57aa189153406c110f5957145030f08fe ] + +gfs2_consist_inode() logs an error message with the source file and line +number. When we jump before calling it, the line number becomes less +useful as it no longer relates to the source of the error. To aid +troubleshooting, replace the gotos with the gfs2_consist_inode() calls +so that the error messages are more informative. + +Signed-off-by: Andrew Price +Signed-off-by: Andreas Gruenbacher +Signed-off-by: Ruohan Lan +Signed-off-by: Sasha Levin +--- + fs/gfs2/dir.c | 31 +++++++++++++++++-------------- + fs/gfs2/glops.c | 34 ++++++++++++++++++++-------------- + fs/gfs2/xattr.c | 28 ++++++++++++++++------------ + 3 files changed, 53 insertions(+), 40 deletions(-) + +diff --git a/fs/gfs2/dir.c b/fs/gfs2/dir.c +index 3a2a10d6d43d1..c252400e59994 100644 +--- a/fs/gfs2/dir.c ++++ b/fs/gfs2/dir.c +@@ -562,15 +562,18 @@ static struct gfs2_dirent *gfs2_dirent_scan(struct inode *inode, void *buf, + int ret = 0; + + ret = gfs2_dirent_offset(GFS2_SB(inode), buf); +- if (ret < 0) +- goto consist_inode; +- ++ if (ret < 0) { ++ gfs2_consist_inode(GFS2_I(inode)); ++ return ERR_PTR(-EIO); ++ } + offset = ret; + prev = NULL; + dent = buf + offset; + size = be16_to_cpu(dent->de_rec_len); +- if (gfs2_check_dirent(GFS2_SB(inode), dent, offset, size, len, 1)) +- goto consist_inode; ++ if (gfs2_check_dirent(GFS2_SB(inode), dent, offset, size, len, 1)) { ++ gfs2_consist_inode(GFS2_I(inode)); ++ return ERR_PTR(-EIO); ++ } + do { + ret = scan(dent, name, opaque); + if (ret) +@@ -582,8 +585,10 @@ static struct gfs2_dirent *gfs2_dirent_scan(struct inode *inode, void *buf, + dent = buf + offset; + size = be16_to_cpu(dent->de_rec_len); + if (gfs2_check_dirent(GFS2_SB(inode), dent, offset, size, +- len, 0)) +- goto consist_inode; ++ len, 0)) { ++ gfs2_consist_inode(GFS2_I(inode)); ++ return ERR_PTR(-EIO); ++ } + } while(1); + + switch(ret) { +@@ -597,10 +602,6 @@ static struct gfs2_dirent *gfs2_dirent_scan(struct inode *inode, void *buf, + BUG_ON(ret > 0); + return ERR_PTR(ret); + } +- +-consist_inode: +- gfs2_consist_inode(GFS2_I(inode)); +- return ERR_PTR(-EIO); + } + + static int dirent_check_reclen(struct gfs2_inode *dip, +@@ -609,14 +610,16 @@ static int dirent_check_reclen(struct gfs2_inode *dip, + const void *ptr = d; + u16 rec_len = be16_to_cpu(d->de_rec_len); + +- if (unlikely(rec_len < sizeof(struct gfs2_dirent))) +- goto broken; ++ if (unlikely(rec_len < sizeof(struct gfs2_dirent))) { ++ gfs2_consist_inode(dip); ++ return -EIO; ++ } + ptr += rec_len; + if (ptr < end_p) + return rec_len; + if (ptr == end_p) + return -ENOENT; +-broken: ++ + gfs2_consist_inode(dip); + return -EIO; + } +diff --git a/fs/gfs2/glops.c b/fs/gfs2/glops.c +index 4a169c60bce65..2ec0b6871ae94 100644 +--- a/fs/gfs2/glops.c ++++ b/fs/gfs2/glops.c +@@ -412,10 +412,14 @@ static int gfs2_dinode_in(struct gfs2_inode *ip, const void *buf) + struct inode *inode = &ip->i_inode; + bool is_new = inode->i_state & I_NEW; + +- if (unlikely(ip->i_no_addr != be64_to_cpu(str->di_num.no_addr))) +- goto corrupt; +- if (unlikely(!is_new && inode_wrong_type(inode, mode))) +- goto corrupt; ++ if (unlikely(ip->i_no_addr != be64_to_cpu(str->di_num.no_addr))) { ++ gfs2_consist_inode(ip); ++ return -EIO; ++ } ++ if (unlikely(!is_new && inode_wrong_type(inode, mode))) { ++ gfs2_consist_inode(ip); ++ return -EIO; ++ } + ip->i_no_formal_ino = be64_to_cpu(str->di_num.no_formal_ino); + inode->i_mode = mode; + if (is_new) { +@@ -451,26 +455,28 @@ static int gfs2_dinode_in(struct gfs2_inode *ip, const void *buf) + /* i_diskflags and i_eattr must be set before gfs2_set_inode_flags() */ + gfs2_set_inode_flags(inode); + height = be16_to_cpu(str->di_height); +- if (unlikely(height > sdp->sd_max_height)) +- goto corrupt; ++ if (unlikely(height > sdp->sd_max_height)) { ++ gfs2_consist_inode(ip); ++ return -EIO; ++ } + ip->i_height = (u8)height; + + depth = be16_to_cpu(str->di_depth); +- if (unlikely(depth > GFS2_DIR_MAX_DEPTH)) +- goto corrupt; ++ if (unlikely(depth > GFS2_DIR_MAX_DEPTH)) { ++ gfs2_consist_inode(ip); ++ return -EIO; ++ } + ip->i_depth = (u8)depth; + ip->i_entries = be32_to_cpu(str->di_entries); + +- if (gfs2_is_stuffed(ip) && inode->i_size > gfs2_max_stuffed_size(ip)) +- goto corrupt; +- ++ if (gfs2_is_stuffed(ip) && inode->i_size > gfs2_max_stuffed_size(ip)) { ++ gfs2_consist_inode(ip); ++ return -EIO; ++ } + if (S_ISREG(inode->i_mode)) + gfs2_set_aops(inode); + + return 0; +-corrupt: +- gfs2_consist_inode(ip); +- return -EIO; + } + + /** +diff --git a/fs/gfs2/xattr.c b/fs/gfs2/xattr.c +index 2117011c8c577..27b9dd1179c26 100644 +--- a/fs/gfs2/xattr.c ++++ b/fs/gfs2/xattr.c +@@ -96,30 +96,34 @@ static int ea_foreach_i(struct gfs2_inode *ip, struct buffer_head *bh, + return -EIO; + + for (ea = GFS2_EA_BH2FIRST(bh);; prev = ea, ea = GFS2_EA2NEXT(ea)) { +- if (!GFS2_EA_REC_LEN(ea)) +- goto fail; ++ if (!GFS2_EA_REC_LEN(ea)) { ++ gfs2_consist_inode(ip); ++ return -EIO; ++ } + if (!(bh->b_data <= (char *)ea && (char *)GFS2_EA2NEXT(ea) <= +- bh->b_data + bh->b_size)) +- goto fail; +- if (!gfs2_eatype_valid(sdp, ea->ea_type)) +- goto fail; ++ bh->b_data + bh->b_size)) { ++ gfs2_consist_inode(ip); ++ return -EIO; ++ } ++ if (!gfs2_eatype_valid(sdp, ea->ea_type)) { ++ gfs2_consist_inode(ip); ++ return -EIO; ++ } + error = ea_call(ip, bh, ea, prev, data); + if (error) + return error; + + if (GFS2_EA_IS_LAST(ea)) { + if ((char *)GFS2_EA2NEXT(ea) != +- bh->b_data + bh->b_size) +- goto fail; ++ bh->b_data + bh->b_size) { ++ gfs2_consist_inode(ip); ++ return -EIO; ++ } + break; + } + } + + return error; +- +-fail: +- gfs2_consist_inode(ip); +- return -EIO; + } + + static int ea_foreach(struct gfs2_inode *ip, ea_call_t ea_call, void *data) +-- +2.53.0 + diff --git a/queue-6.6/gfs2-validate-i_depth-for-exhash-directories.patch b/queue-6.6/gfs2-validate-i_depth-for-exhash-directories.patch new file mode 100644 index 0000000000..0d4bf378f0 --- /dev/null +++ b/queue-6.6/gfs2-validate-i_depth-for-exhash-directories.patch @@ -0,0 +1,106 @@ +From f48427cde0a7fafba929d3636a0508422b01a081 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 3 Apr 2026 13:51:54 +0800 +Subject: gfs2: Validate i_depth for exhash directories + +From: Andrew Price + +[ Upstream commit 557c024ca7250bb65ae60f16c02074106c2f197b ] + +A fuzzer test introduced corruption that ends up with a depth of 0 in +dir_e_read(), causing an undefined shift by 32 at: + + index = hash >> (32 - dip->i_depth); + +As calculated in an open-coded way in dir_make_exhash(), the minimum +depth for an exhash directory is ilog2(sdp->sd_hash_ptrs) and 0 is +invalid as sdp->sd_hash_ptrs is fixed as sdp->bsize / 16 at mount time. + +So we can avoid the undefined behaviour by checking for depth values +lower than the minimum in gfs2_dinode_in(). Values greater than the +maximum are already being checked for there. + +Also switch the calculation in dir_make_exhash() to use ilog2() to +clarify how the depth is calculated. + +Tested with the syzkaller repro.c and xfstests '-g quick'. + +Reported-by: syzbot+4708579bb230a0582a57@syzkaller.appspotmail.com +Signed-off-by: Andrew Price +Signed-off-by: Andreas Gruenbacher +Signed-off-by: Ruohan Lan +Tested-by: Hardik Garg +Tested-by: Ron Economos +Tested-by: Brett A C Sheffield +Tested-by: Shuah Khan +Tested-by: Peter Schneider +Tested-by: Pavel Machek (CIP) +Tested-by: Florian Fainelli +Tested-by: Jon Hunter +Tested-by: Markus Reichelt +Tested-by: Ronald Warsow +Tested-by: Takeshi Ogasawara +Signed-off-by: Sasha Levin +--- + fs/gfs2/dir.c | 6 ++---- + fs/gfs2/glops.c | 6 ++++++ + 2 files changed, 8 insertions(+), 4 deletions(-) + +diff --git a/fs/gfs2/dir.c b/fs/gfs2/dir.c +index c252400e59994..c4e9488483d90 100644 +--- a/fs/gfs2/dir.c ++++ b/fs/gfs2/dir.c +@@ -60,6 +60,7 @@ + #include + #include + #include ++#include + + #include "gfs2.h" + #include "incore.h" +@@ -912,7 +913,6 @@ static int dir_make_exhash(struct inode *inode) + struct qstr args; + struct buffer_head *bh, *dibh; + struct gfs2_leaf *leaf; +- int y; + u32 x; + __be64 *lp; + u64 bn; +@@ -979,9 +979,7 @@ static int dir_make_exhash(struct inode *inode) + i_size_write(inode, sdp->sd_sb.sb_bsize / 2); + gfs2_add_inode_blocks(&dip->i_inode, 1); + dip->i_diskflags |= GFS2_DIF_EXHASH; +- +- for (x = sdp->sd_hash_ptrs, y = -1; x; x >>= 1, y++) ; +- dip->i_depth = y; ++ dip->i_depth = ilog2(sdp->sd_hash_ptrs); + + gfs2_dinode_out(dip, dibh->b_data); + +diff --git a/fs/gfs2/glops.c b/fs/gfs2/glops.c +index 2ec0b6871ae94..f575cd8ff47c1 100644 +--- a/fs/gfs2/glops.c ++++ b/fs/gfs2/glops.c +@@ -11,6 +11,7 @@ + #include + #include + #include ++#include + + #include "gfs2.h" + #include "incore.h" +@@ -466,6 +467,11 @@ static int gfs2_dinode_in(struct gfs2_inode *ip, const void *buf) + gfs2_consist_inode(ip); + return -EIO; + } ++ if ((ip->i_diskflags & GFS2_DIF_EXHASH) && ++ depth < ilog2(sdp->sd_hash_ptrs)) { ++ gfs2_consist_inode(ip); ++ return -EIO; ++ } + ip->i_depth = (u8)depth; + ip->i_entries = be32_to_cpu(str->di_entries); + +-- +2.53.0 + diff --git a/queue-6.6/loongarch-vdso-emit-gnu_eh_frame-correctly.patch b/queue-6.6/loongarch-vdso-emit-gnu_eh_frame-correctly.patch new file mode 100644 index 0000000000..2cba7efc04 --- /dev/null +++ b/queue-6.6/loongarch-vdso-emit-gnu_eh_frame-correctly.patch @@ -0,0 +1,225 @@ +From 5e129c0331c9e644ff8a8fc59c5947d79e5b7799 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 1 Apr 2026 00:34:17 +0800 +Subject: LoongArch: vDSO: Emit GNU_EH_FRAME correctly + +From: Xi Ruoyao + +With -fno-asynchronous-unwind-tables and --no-eh-frame-hdr (the default +of the linker), the GNU_EH_FRAME segment (specified by vdso.lds.S) is +empty. This is not valid, as the current DWARF specification mandates +the first byte of the EH frame to be the version number 1. It causes +some unwinders to complain, for example the ClickHouse query profiler +spams the log with messages: + + clickhouse-server[365854]: libunwind: unsupported .eh_frame_hdr + version: 127 at 7ffffffb0000 + +Here "127" is just the byte located at the p_vaddr (0, i.e. the +beginning of the vDSO) of the empty GNU_EH_FRAME segment. Cross- +checking with /proc/365854/maps has also proven 7ffffffb0000 is the +start of vDSO in the process VM image. + +In LoongArch the -fno-asynchronous-unwind-tables option seems just a +MIPS legacy, and MIPS only uses this option to satisfy the MIPS-specific +"genvdso" program, per the commit cfd75c2db17e ("MIPS: VDSO: Explicitly +use -fno-asynchronous-unwind-tables"). IIRC it indicates some inherent +limitation of the MIPS ELF ABI and has nothing to do with LoongArch. So +we can simply flip it over to -fasynchronous-unwind-tables and pass +--eh-frame-hdr for linking the vDSO, allowing the profilers to unwind the +stack for statistics even if the sample point is taken when the PC is in +the vDSO. + +However simply adjusting the options above would exploit an issue: when +the libgcc unwinder saw the invalid GNU_EH_FRAME segment, it silently +falled back to a machine-specific routine to match the code pattern of +rt_sigreturn() and extract the registers saved in the sigframe if the +code pattern is matched. As unwinding from signal handlers is vital for +libgcc to support pthread cancellation etc., the fall-back routine had +been silently keeping the LoongArch Linux systems functioning since +Linux 5.19. But when we start to emit GNU_EH_FRAME with the correct +format, fall-back routine will no longer be used and libgcc will fail +to unwind the sigframe, and unwinding from signal handlers will no +longer work, causing dozens of glibc test failures. To make it possible +to unwind from signal handlers again, it's necessary to code the unwind +info in __vdso_rt_sigreturn via .cfi_* directives. + +The offsets in the .cfi_* directives depend on the layout of struct +sigframe, notably the offset of sigcontext in the sigframe. To use the +offset in the assembly file, factor out struct sigframe into a header to +allow asm-offsets.c to output the offset for assembly. + +To work around a long-term issue in the libgcc unwinder (the pc is +unconditionally substracted by 1: doing so is technically incorrect for +a signal frame), a nop instruction is included with the two real +instructions in __vdso_rt_sigreturn in the same FDE PC range. The same +hack has been used on x86 for a long time. + +(cherry picked from commit e4878c37f6679fdea91b27a0f4e60a871f0b7bad) + +Cc: stable@vger.kernel.org +Fixes: c6b99bed6b8f ("LoongArch: Add VDSO and VSYSCALL support") +Signed-off-by: Xi Ruoyao +Signed-off-by: Huacai Chen +Signed-off-by: Xi Ruoyao +Signed-off-by: Sasha Levin +--- + arch/loongarch/include/asm/linkage.h | 36 +++++++++++++++++++++++++++ + arch/loongarch/include/asm/sigframe.h | 9 +++++++ + arch/loongarch/kernel/asm-offsets.c | 2 ++ + arch/loongarch/kernel/signal.c | 6 +---- + arch/loongarch/vdso/Makefile | 4 +-- + arch/loongarch/vdso/sigreturn.S | 6 ++--- + 6 files changed, 53 insertions(+), 10 deletions(-) + create mode 100644 arch/loongarch/include/asm/sigframe.h + +diff --git a/arch/loongarch/include/asm/linkage.h b/arch/loongarch/include/asm/linkage.h +index e2eca1a25b4ef..a1bd6a3ee03a1 100644 +--- a/arch/loongarch/include/asm/linkage.h ++++ b/arch/loongarch/include/asm/linkage.h +@@ -41,4 +41,40 @@ + .cfi_endproc; \ + SYM_END(name, SYM_T_NONE) + ++/* ++ * This is for the signal handler trampoline, which is used as the return ++ * address of the signal handlers in userspace instead of called normally. ++ * The long standing libgcc bug https://gcc.gnu.org/PR124050 requires a ++ * nop between .cfi_startproc and the actual address of the trampoline, so ++ * we cannot simply use SYM_FUNC_START. ++ * ++ * This wrapper also contains all the .cfi_* directives for recovering ++ * the content of the GPRs and the "return address" (where the rt_sigreturn ++ * syscall will jump to), assuming there is a struct rt_sigframe (where ++ * a struct sigcontext containing those information we need to recover) at ++ * $sp. The "DWARF for the LoongArch(TM) Architecture" manual states ++ * column 0 is for $zero, but it does not make too much sense to ++ * save/restore the hardware zero register. Repurpose this column here ++ * for the return address (here it's not the content of $ra we cannot use ++ * the default column 3). ++ */ ++#define SYM_SIGFUNC_START(name) \ ++ .cfi_startproc; \ ++ .cfi_signal_frame; \ ++ .cfi_def_cfa 3, RT_SIGFRAME_SC; \ ++ .cfi_return_column 0; \ ++ .cfi_offset 0, SC_PC; \ ++ \ ++ .irp num, 1, 2, 3, 4, 5, 6, 7, 8, \ ++ 9, 10, 11, 12, 13, 14, 15, 16, \ ++ 17, 18, 19, 20, 21, 22, 23, 24, \ ++ 25, 26, 27, 28, 29, 30, 31; \ ++ .cfi_offset \num, SC_REGS + \num * SZREG; \ ++ .endr; \ ++ \ ++ nop; \ ++ SYM_START(name, SYM_L_GLOBAL, SYM_A_ALIGN) ++ ++#define SYM_SIGFUNC_END(name) SYM_FUNC_END(name) ++ + #endif +diff --git a/arch/loongarch/include/asm/sigframe.h b/arch/loongarch/include/asm/sigframe.h +new file mode 100644 +index 0000000000000..109298b8d7e0b +--- /dev/null ++++ b/arch/loongarch/include/asm/sigframe.h +@@ -0,0 +1,9 @@ ++/* SPDX-License-Identifier: GPL-2.0+ */ ++ ++#include ++#include ++ ++struct rt_sigframe { ++ struct siginfo rs_info; ++ struct ucontext rs_uctx; ++}; +diff --git a/arch/loongarch/kernel/asm-offsets.c b/arch/loongarch/kernel/asm-offsets.c +index 110afd3cc8f34..10c66ec95fa19 100644 +--- a/arch/loongarch/kernel/asm-offsets.c ++++ b/arch/loongarch/kernel/asm-offsets.c +@@ -15,6 +15,7 @@ + #include + #include + #include ++#include + + void output_ptreg_defines(void) + { +@@ -218,6 +219,7 @@ void output_sc_defines(void) + COMMENT("Linux sigcontext offsets."); + OFFSET(SC_REGS, sigcontext, sc_regs); + OFFSET(SC_PC, sigcontext, sc_pc); ++ OFFSET(RT_SIGFRAME_SC, rt_sigframe, rs_uctx.uc_mcontext); + BLANK(); + } + +diff --git a/arch/loongarch/kernel/signal.c b/arch/loongarch/kernel/signal.c +index 0e90cd2df0ea3..c9a0fd40e8b57 100644 +--- a/arch/loongarch/kernel/signal.c ++++ b/arch/loongarch/kernel/signal.c +@@ -34,6 +34,7 @@ + #include + #include + #include ++#include + #include + #include + +@@ -71,11 +72,6 @@ extern asmlinkage int _save_ftop_context(void __user *ftop); + extern asmlinkage int _restore_ftop_context(void __user *ftop); + #endif + +-struct rt_sigframe { +- struct siginfo rs_info; +- struct ucontext rs_uctx; +-}; +- + struct _ctx_layout { + struct sctx_info *addr; + unsigned int size; +diff --git a/arch/loongarch/vdso/Makefile b/arch/loongarch/vdso/Makefile +index 1a0f6ca0247b4..ebf3b4d521727 100644 +--- a/arch/loongarch/vdso/Makefile ++++ b/arch/loongarch/vdso/Makefile +@@ -24,7 +24,7 @@ cflags-vdso := $(ccflags-vdso) \ + $(filter -W%,$(filter-out -Wa$(comma)%,$(KBUILD_CFLAGS))) \ + -std=gnu11 -O2 -g -fno-strict-aliasing -fno-common -fno-builtin \ + -fno-stack-protector -fno-jump-tables -DDISABLE_BRANCH_PROFILING \ +- $(call cc-option, -fno-asynchronous-unwind-tables) \ ++ $(call cc-option, -fasynchronous-unwind-tables) \ + $(call cc-option, -fno-stack-protector) + aflags-vdso := $(ccflags-vdso) \ + -D__ASSEMBLY__ -Wa,-gdwarf-2 +@@ -36,7 +36,7 @@ endif + # VDSO linker flags. + ldflags-y := -Bsymbolic --no-undefined -soname=linux-vdso.so.1 \ + $(filter -E%,$(KBUILD_CFLAGS)) -nostdlib -shared \ +- --hash-style=sysv --build-id -T ++ --hash-style=sysv --build-id --eh-frame-hdr -T + + GCOV_PROFILE := n + +diff --git a/arch/loongarch/vdso/sigreturn.S b/arch/loongarch/vdso/sigreturn.S +index 9cb3c58fad03b..59f940d928de7 100644 +--- a/arch/loongarch/vdso/sigreturn.S ++++ b/arch/loongarch/vdso/sigreturn.S +@@ -12,13 +12,13 @@ + + #include + #include ++#include + + .section .text +- .cfi_sections .debug_frame + +-SYM_FUNC_START(__vdso_rt_sigreturn) ++SYM_SIGFUNC_START(__vdso_rt_sigreturn) + + li.w a7, __NR_rt_sigreturn + syscall 0 + +-SYM_FUNC_END(__vdso_rt_sigreturn) ++SYM_SIGFUNC_END(__vdso_rt_sigreturn) +-- +2.53.0 + diff --git a/queue-6.6/series b/queue-6.6/series index 17f058d192..7f9b32cca6 100644 --- a/queue-6.6/series +++ b/queue-6.6/series @@ -134,3 +134,8 @@ thunderbolt-fix-property-read-in-nhi_wake_supported.patch usb-dummy-hcd-fix-locking-synchronization-error.patch usb-dummy-hcd-fix-interrupt-synchronization-error.patch usb-gadget-dummy_hcd-fix-premature-urb-completion-when-zlp-follows-partial-transfer.patch +btrfs-fix-the-qgroup-data-free-range-for-inline-data.patch +btrfs-do-not-free-data-reservation-in-fallback-from-.patch +gfs2-improve-gfs2_consist_inode-usage.patch +gfs2-validate-i_depth-for-exhash-directories.patch +loongarch-vdso-emit-gnu_eh_frame-correctly.patch