From: Greg Kroah-Hartman Date: Wed, 29 Jul 2026 13:19:26 +0000 (+0200) Subject: 5.15-stable patches X-Git-Tag: v6.1.179~27 X-Git-Url: http://git.ipfire.org/gitweb/?a=commitdiff_plain;h=4d3eceef367622c4ede3bf49a1624470efa8c106;p=thirdparty%2Fkernel%2Fstable-queue.git 5.15-stable patches added patches: binfmt_misc-set-have_execfd-only-once-the-interpreter-is-opened.patch bluetooth-rfcomm-fix-session-uaf-in-set_termios.patch exec-fix-unsigned-loop-counter-wrap-in-transfer_args_to_stack.patch media-pci-dm1105-free-allocated-workqueue.patch media-pwc-drain-fill_buf-on-start_streaming-failure.patch media-pwc-return-queued-buffers-on-start_streaming-failure.patch media-radio-si476x-unregister-v4l2_device-on-probe-failure.patch media-rtl2832-fix-use-after-free-in-rtl2832_remove.patch media-rtl2832_sdr-return-queued-buffers-on-start_streaming-failure.patch media-saa7134-fix-a-possible-memory-leak-in-saa7134_video_init1.patch media-sun4i-csi-return-queued-buffers-on-start_streaming-failure.patch media-tegra-video-vi-fix-invalid-u32-return-value-in-format-lookup.patch media-v4l2-ctrls-request-add-null-check-in-v4l2_ctrl_request_complete.patch media-vb2-use-ssize_t-for-vb2_read-vb2_write.patch media-vidtv-fix-reference-leak-on-failed-device-registration.patch media-vimc-fix-reference-leak-on-failed-device-registration.patch media-vivid-check-for-vb2_is_busy-when-toggling-caps.patch staging-rtl8723bs-fix-inverted-ht40-secondary-channel-offset.patch staging-rtl8723bs-fix-oob-reads-in-rtw_get_wps_ie.patch wifi-ath6kl-fix-oob-access-from-firmware-addba-window-size.patch wifi-brcmfmac-make-release_scratchbuffers-idempotent.patch wifi-mwifiex-fix-null-dereference-when-the-ap-has-ht-cap-but-no-ht-oper.patch wifi-wilc1000-validate-assoc-response-length-before-subtracting-header.patch --- diff --git a/queue-5.15/binfmt_misc-set-have_execfd-only-once-the-interpreter-is-opened.patch b/queue-5.15/binfmt_misc-set-have_execfd-only-once-the-interpreter-is-opened.patch new file mode 100644 index 0000000000..b18f8a6206 --- /dev/null +++ b/queue-5.15/binfmt_misc-set-have_execfd-only-once-the-interpreter-is-opened.patch @@ -0,0 +1,72 @@ +From bbf5f639918dc011aaf60aab8480218758ee68c5 Mon Sep 17 00:00:00 2001 +From: Christian Brauner +Date: Mon, 20 Jul 2026 14:36:49 +0200 +Subject: binfmt_misc: set have_execfd only once the interpreter is opened + +From: Christian Brauner + +commit bbf5f639918dc011aaf60aab8480218758ee68c5 upstream. + +load_misc_binary() raises bprm->have_execfd as soon as it sees the 'O' +(or 'C') flag. This happens well before it opens the interpreter. If +that open fails the flag stays set on the bprm. binfmt_misc is at the +head of the format list so an interpreter open failure that returns +-ENOEXEC lets the search fall through to a later format. This means it +runs the matched binary directly having never staged an interpreter. So +bprm->executable is NULL while have_execfd falsely claims a descriptor +is present. + +Consequently, begin_new_exec() dereferences the missing executable: + + would_dump(bprm, bprm->executable); + +and NULL derefs. Had it not, the hand-off later in the same function +would have failed anyway. FD_ADD(0, bprm->executable) rejects a NULL +file with -ENOMEM. Both sites are past the point of no return so the +exec cannot be unwound either way. + +This can be reached by unprivileged users as binfmt_misc can be mounted +in user namespaces. So a user can register an 'O' entry whose +interpreter lives on a FUSE mount, have the FUSE server fail the open +with -ENOEXEC and execute a native ELF file that matches the entry. + +have_execfd only means anything alongside the executable it describes +which is not set until the interpreter has been opened and staged. +So lets raise it there, next to execfd_creds, which is already set at +that point. An open failure now leaves it clear, so the fallback format +derives credentials from the binary and emits no AT_EXECFD, as it would +for any native exec. The argv rewrite load_misc_binary() performs before +the open is still not undone. This means the binary sees the interpreter +path in argv[0] and its own path in argv[1] but that predates this +change and only became observable once the exec stopped faulting. + +Link: https://patch.msgid.link/20260720-beglichen-kognitiv-organismus-5e1e55326c56@brauner +Fixes: bc2bf338d54b ("exec: Remove recursion from search_binary_handler") +Cc: stable@vger.kernel.org +Signed-off-by: Christian Brauner (Amutable) +Signed-off-by: Greg Kroah-Hartman +--- + fs/binfmt_misc.c | 5 ++--- + 1 file changed, 2 insertions(+), 3 deletions(-) + +--- a/fs/binfmt_misc.c ++++ b/fs/binfmt_misc.c +@@ -199,9 +199,6 @@ static int load_misc_binary(struct linux + goto ret; + } + +- if (fmt->flags & MISC_FMT_OPEN_BINARY) +- bprm->have_execfd = 1; +- + /* make argv[1] be the path to the binary */ + retval = copy_string_kernel(bprm->interp, bprm); + if (retval < 0) +@@ -231,6 +228,8 @@ static int load_misc_binary(struct linux + goto ret; + + bprm->interpreter = interp_file; ++ if (fmt->flags & MISC_FMT_OPEN_BINARY) ++ bprm->have_execfd = 1; + if (fmt->flags & MISC_FMT_CREDENTIALS) + bprm->execfd_creds = 1; + diff --git a/queue-5.15/bluetooth-rfcomm-fix-session-uaf-in-set_termios.patch b/queue-5.15/bluetooth-rfcomm-fix-session-uaf-in-set_termios.patch new file mode 100644 index 0000000000..b457b68b6b --- /dev/null +++ b/queue-5.15/bluetooth-rfcomm-fix-session-uaf-in-set_termios.patch @@ -0,0 +1,128 @@ +From c783399efc22d035443f1dfbf2a09bf9562aaa5e Mon Sep 17 00:00:00 2001 +From: Chengfeng Ye +Date: Mon, 20 Jul 2026 00:03:11 +0800 +Subject: Bluetooth: RFCOMM: Fix session UAF in set_termios + +From: Chengfeng Ye + +commit c783399efc22d035443f1dfbf2a09bf9562aaa5e upstream. + +rfcomm_tty_set_termios() tests dlc->session without rfcomm_mutex and +later passes the pointer to rfcomm_send_rpn(). The latter dereferences +both session->initiator and session->sock. Meanwhile, krfcommd can +unlink the DLC and free the session while holding rfcomm_mutex. + +The race can proceed as follows: + + TTY ioctl task krfcommd + -------------- -------- + load dlc->session + enter rfcomm_send_rpn() + lock rfcomm_mutex + clear dlc->session + free session + unlock rfcomm_mutex + read session->initiator + +KASAN reported: + + BUG: KASAN: slab-use-after-free in rfcomm_send_rpn+0x297/0x2a0 + Read of size 4 at addr ffff88810012a850 by task poc/92 + + Call Trace: + rfcomm_send_rpn+0x297/0x2a0 + rfcomm_tty_set_termios+0x50d/0x850 + tty_set_termios+0x596/0x950 + set_termios+0x46a/0x6e0 + tty_mode_ioctl+0x152/0xbd0 + tty_ioctl+0x915/0x1240 + __x64_sys_ioctl+0x134/0x1c0 + + Allocated by task 92: + rfcomm_session_add+0x9e/0x2e0 + rfcomm_dlc_open+0x8b1/0xe00 + rfcomm_dev_activate+0x85/0x1a0 + rfcomm_tty_open+0x90/0x280 + + Freed by task 68: + kfree+0x131/0x3c0 + rfcomm_session_del+0x119/0x180 + rfcomm_run+0x737/0x4710 + +Add rfcomm_dlc_send_rpn(), which holds rfcomm_mutex while it verifies +that the DLC is still attached and sends the RPN frame. Have the TTY +path use the helper and drop its unlocked session check. This keeps the +session valid through both the frame construction and socket send. + +Fixes: 3a5e903c09ae ("[Bluetooth]: Implement RFCOMM remote port negotiation") +Cc: stable@vger.kernel.org +Signed-off-by: Chengfeng Ye +Signed-off-by: Luiz Augusto von Dentz +Signed-off-by: Greg Kroah-Hartman +--- + include/net/bluetooth/rfcomm.h | 3 +++ + net/bluetooth/rfcomm/core.c | 17 +++++++++++++++++ + net/bluetooth/rfcomm/tty.c | 7 +++---- + 3 files changed, 23 insertions(+), 4 deletions(-) + +--- a/include/net/bluetooth/rfcomm.h ++++ b/include/net/bluetooth/rfcomm.h +@@ -229,6 +229,9 @@ int rfcomm_send_rpn(struct rfcomm_sessio + u8 bit_rate, u8 data_bits, u8 stop_bits, + u8 parity, u8 flow_ctrl_settings, + u8 xon_char, u8 xoff_char, u16 param_mask); ++int rfcomm_dlc_send_rpn(struct rfcomm_dlc *d, u8 bit_rate, u8 data_bits, ++ u8 stop_bits, u8 parity, u8 flow_ctrl_settings, ++ u8 xon_char, u8 xoff_char, u16 param_mask); + + /* ---- RFCOMM DLCs (channels) ---- */ + struct rfcomm_dlc *rfcomm_dlc_alloc(gfp_t prio); +--- a/net/bluetooth/rfcomm/core.c ++++ b/net/bluetooth/rfcomm/core.c +@@ -1027,6 +1027,23 @@ int rfcomm_send_rpn(struct rfcomm_sessio + return rfcomm_send_frame(s, buf, ptr - buf); + } + ++int rfcomm_dlc_send_rpn(struct rfcomm_dlc *d, u8 bit_rate, u8 data_bits, ++ u8 stop_bits, u8 parity, u8 flow_ctrl_settings, ++ u8 xon_char, u8 xoff_char, u16 param_mask) ++{ ++ int err = -ENOTCONN; ++ ++ rfcomm_lock(); ++ if (d->session) ++ err = rfcomm_send_rpn(d->session, 1, d->dlci, bit_rate, ++ data_bits, stop_bits, parity, ++ flow_ctrl_settings, xon_char, xoff_char, ++ param_mask); ++ rfcomm_unlock(); ++ ++ return err; ++} ++ + static int rfcomm_send_rls(struct rfcomm_session *s, int cr, u8 dlci, u8 status) + { + struct rfcomm_hdr *hdr; +--- a/net/bluetooth/rfcomm/tty.c ++++ b/net/bluetooth/rfcomm/tty.c +@@ -868,7 +868,7 @@ static void rfcomm_tty_set_termios(struc + + BT_DBG("tty %p termios %p", tty, old); + +- if (!dev || !dev->dlc || !dev->dlc->session) ++ if (!dev || !dev->dlc) + return; + + /* Handle turning off CRTSCTS */ +@@ -989,9 +989,8 @@ static void rfcomm_tty_set_termios(struc + } + + if (changes) +- rfcomm_send_rpn(dev->dlc->session, 1, dev->dlc->dlci, baud, +- data_bits, stop_bits, parity, +- RFCOMM_RPN_FLOW_NONE, x_on, x_off, changes); ++ rfcomm_dlc_send_rpn(dev->dlc, baud, data_bits, stop_bits, parity, ++ RFCOMM_RPN_FLOW_NONE, x_on, x_off, changes); + } + + static void rfcomm_tty_throttle(struct tty_struct *tty) diff --git a/queue-5.15/exec-fix-unsigned-loop-counter-wrap-in-transfer_args_to_stack.patch b/queue-5.15/exec-fix-unsigned-loop-counter-wrap-in-transfer_args_to_stack.patch new file mode 100644 index 0000000000..9dd1b6bbb6 --- /dev/null +++ b/queue-5.15/exec-fix-unsigned-loop-counter-wrap-in-transfer_args_to_stack.patch @@ -0,0 +1,79 @@ +From 16cc4f5c1c4b9e45eca7f7deefa5410a292db599 Mon Sep 17 00:00:00 2001 +From: Christian Brauner +Date: Tue, 21 Jul 2026 12:08:49 +0200 +Subject: exec: fix unsigned loop counter wrap in transfer_args_to_stack() + +From: Christian Brauner + +commit 16cc4f5c1c4b9e45eca7f7deefa5410a292db599 upstream. + +The stop value is derived from bprm->p >> PAGE_SHIFT. The index variable +is an unsigned long. If bprm->p drops below PAGE_SIZE and stop becomes +zero the loop condition index >= stop is always true. + +After the index == 0 iteration the decrement wraps to ULONG_MAX and +bprm->page[ULONG_MAX] reads sizeof(void *) bytes in front of the array. +The pointer has wrapped to -1. That garbage pointer is then passed to +kmap_local_page() and PAGE_SIZE bytes are copied from wherever that +lands into the stack of the process being created. And the loop doesn't +terminate either... + +Getting there only requires bprm->p < PAGE_SIZE. On !MMU +bprm_set_stack_limit() and bprm_hit_stack_limit() are empty. So the only +constraint on how far bprm->p is pushed down is valid_arg_len(), i.e. +that each individual string still fits in what is left. + +bprm->p starts at PAGE_SIZE * MAX_ARG_PAGES - sizeof(void *) so a +single argument or environment string of a little over 31 pages leaves +it in the first page: + + Oops - load access fault [#1] + CPU: 0 UID: 0 PID: 1 Comm: victim Not tainted 7.2.0-rc4 #1 + epc : __memcpy+0xd4/0xf8 + ra : transfer_args_to_stack+0xaa/0xae + s4 : ffffffffffffffff s2 : 0000000000000000 + a1 : ffffffdc98000000 a2 : 0000000000001000 + status: 0000000a00001880 badaddr: ffffffdc98000000 cause: 0000000000000005 + [<801a5324>] __memcpy+0xd4/0xf8 + [<800d5f6a>] load_flat_binary+0x43a/0x65e + [<800a2de4>] bprm_execve+0x1d4/0x316 + [<800a351a>] do_execveat_common+0x12e/0x138 + [<800a3d44>] __riscv_sys_execve+0x38/0x4e + Kernel panic - not syncing: Fatal exception in interrupt + +This is an arcane bug but we should still fix it. + +Count down from MAX_ARG_PAGES so the loop ends when index reaches stop, +stop == 0 included. The iterations performed are unchanged for every +other value of stop. + +Only CONFIG_MMU=n builds are affected, transfer_args_to_stack() is used +by binfmt_flat and binfmt_elf_fdpic on nommu only. + +The loop predates git history. commit 7e7ec6a93434 +("elf_fdpic_transfer_args_to_stack(): make it generic") only moved it +from binfmt_elf_fdpic.c into fs/exec.c and narrowed the copy to the used +part of the first page. The condition and the decrement are unchanged +from 2.6.12-rc2. + +Link: https://patch.msgid.link/20260721-hochachtung-staumauer-pigmente-15d71f7d7d04@brauner +Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") +Cc: stable@vger.kernel.org +Reviewed-by: David Hildenbrand (Arm) +Signed-off-by: Christian Brauner (Amutable) +Signed-off-by: Greg Kroah-Hartman +--- + fs/exec.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/fs/exec.c ++++ b/fs/exec.c +@@ -876,7 +876,7 @@ int transfer_args_to_stack(struct linux_ + stop = bprm->p >> PAGE_SHIFT; + sp = *sp_location; + +- for (index = MAX_ARG_PAGES - 1; index >= stop; index--) { ++ for (index = MAX_ARG_PAGES; index-- > stop; ) { + unsigned int offset = index == stop ? bprm->p & ~PAGE_MASK : 0; + char *src = kmap(bprm->page[index]) + offset; + sp -= PAGE_SIZE - offset; diff --git a/queue-5.15/media-pci-dm1105-free-allocated-workqueue.patch b/queue-5.15/media-pci-dm1105-free-allocated-workqueue.patch new file mode 100644 index 0000000000..89fa3c7577 --- /dev/null +++ b/queue-5.15/media-pci-dm1105-free-allocated-workqueue.patch @@ -0,0 +1,31 @@ +From 1a65db225b25bb8c8febf16974c060e0cc242eb9 Mon Sep 17 00:00:00 2001 +From: Krzysztof Kozlowski +Date: Tue, 28 Apr 2026 16:50:08 +0200 +Subject: media: pci: dm1105: Free allocated workqueue + +From: Krzysztof Kozlowski + +commit 1a65db225b25bb8c8febf16974c060e0cc242eb9 upstream. + +Destroy allocated workqueue in remove() callback to free its resources, +thus fixing memory leak. + +Fixes: 519a4bdcf822 ("V4L/DVB (11984): Add support for yet another SDMC DM1105 based DVB-S card.") +Cc: +Signed-off-by: Krzysztof Kozlowski +Signed-off-by: Hans Verkuil +Signed-off-by: Greg Kroah-Hartman +--- + drivers/media/pci/dm1105/dm1105.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/media/pci/dm1105/dm1105.c ++++ b/drivers/media/pci/dm1105/dm1105.c +@@ -1193,6 +1193,7 @@ static void dm1105_remove(struct pci_dev + + dm1105_hw_exit(dev); + free_irq(pdev->irq, dev); ++ destroy_workqueue(dev->wq); + pci_iounmap(pdev, dev->io_mem); + pci_release_regions(pdev); + pci_disable_device(pdev); diff --git a/queue-5.15/media-pwc-drain-fill_buf-on-start_streaming-failure.patch b/queue-5.15/media-pwc-drain-fill_buf-on-start_streaming-failure.patch new file mode 100644 index 0000000000..423c4a08fb --- /dev/null +++ b/queue-5.15/media-pwc-drain-fill_buf-on-start_streaming-failure.patch @@ -0,0 +1,63 @@ +From 906e410dcffbbd99fb4081abab817a830033aa28 Mon Sep 17 00:00:00 2001 +From: Valery Borovsky +Date: Wed, 13 May 2026 08:42:44 +0300 +Subject: media: pwc: Drain fill_buf on start_streaming() failure + +From: Valery Borovsky + +commit 906e410dcffbbd99fb4081abab817a830033aa28 upstream. + +pwc_isoc_init() submits its isochronous URBs with +usb_submit_urb(.., GFP_KERNEL) in a loop. After the first URB is +submitted, its completion handler pwc_isoc_handler() can run on another +CPU before the loop finishes: + + start_streaming() + pwc_isoc_init() + usb_submit_urb(urbs[0], GFP_KERNEL) + pwc_isoc_handler(urbs[0]) + pdev->fill_buf = + pwc_get_next_fill_buf(pdev) + usb_submit_urb(urbs[i>0], ..) -> fails + pwc_isoc_cleanup(pdev) /* kills URBs */ + return ret; + pwc_cleanup_queued_bufs(pdev, VB2_BUF_STATE_QUEUED) + +pwc_get_next_fill_buf() detaches a buffer from pdev->queued_bufs and +stores it in pdev->fill_buf. The error path in start_streaming() only +drains pdev->queued_bufs, so the buffer parked in pdev->fill_buf is +leaked. vb2_start_streaming() then triggers +WARN_ON(owned_by_drv_count). + +stop_streaming() already handles this since commit 80b0963e1698 +("[media] pwc: fix WARN_ON"), which added the fill_buf drain in the +teardown path but not in the start_streaming() error path. Mirror that +handling on failure so start_streaming() returns with no buffer owned +by the driver. + +Issue identified by automated review of the INV-003 series at +https://sashiko.dev/ + +Fixes: 885fe18f5542 ("[media] pwc: Replace private buffer management code with videobuf2") +Cc: stable@vger.kernel.org +Signed-off-by: Valery Borovsky +Signed-off-by: Hans Verkuil +Signed-off-by: Greg Kroah-Hartman +--- + drivers/media/usb/pwc/pwc-if.c | 5 +++++ + 1 file changed, 5 insertions(+) + +--- a/drivers/media/usb/pwc/pwc-if.c ++++ b/drivers/media/usb/pwc/pwc-if.c +@@ -727,6 +727,11 @@ static int start_streaming(struct vb2_qu + pwc_camera_power(pdev, 0); + /* And cleanup any queued bufs!! */ + pwc_cleanup_queued_bufs(pdev, VB2_BUF_STATE_QUEUED); ++ if (pdev->fill_buf) { ++ vb2_buffer_done(&pdev->fill_buf->vb.vb2_buf, ++ VB2_BUF_STATE_QUEUED); ++ pdev->fill_buf = NULL; ++ } + } + mutex_unlock(&pdev->v4l2_lock); + diff --git a/queue-5.15/media-pwc-return-queued-buffers-on-start_streaming-failure.patch b/queue-5.15/media-pwc-return-queued-buffers-on-start_streaming-failure.patch new file mode 100644 index 0000000000..b4d786862f --- /dev/null +++ b/queue-5.15/media-pwc-return-queued-buffers-on-start_streaming-failure.patch @@ -0,0 +1,54 @@ +From 975b2ee20e569d47821e4f6c9761b4664d48a6a4 Mon Sep 17 00:00:00 2001 +From: Valery Borovsky +Date: Mon, 11 May 2026 20:12:08 +0300 +Subject: media: pwc: Return queued buffers on start_streaming() failure + +From: Valery Borovsky + +commit 975b2ee20e569d47821e4f6c9761b4664d48a6a4 upstream. + +The vb2 framework hands buffers to the driver via buf_queue() before +calling start_streaming(). If start_streaming() returns an error +without first returning those buffers via vb2_buffer_done(), +vb2_start_streaming() fires WARN_ON(owned_by_drv_count) and the queued +buffers leak. + +pwc's start_streaming() had two early returns that hit this trap: +-ENODEV when the USB device was already disconnected, and -ERESTARTSYS +when mutex_lock_interruptible() was interrupted by a signal. Call the +existing pwc_cleanup_queued_bufs() helper with VB2_BUF_STATE_QUEUED +before returning (matching the state already used by the +pwc_isoc_init() error path in the same function). + +This mirrors the uvcvideo fix in commit 4cf3b6fd54eb ("media: uvcvideo: +Return queued buffers on start_streaming() failure"). + +Fixes: ceede9fa8939 ("[media] pwc: Fix locking") +Cc: stable@vger.kernel.org +Signed-off-by: Valery Borovsky +Signed-off-by: Hans Verkuil +Signed-off-by: Greg Kroah-Hartman +--- + drivers/media/usb/pwc/pwc-if.c | 8 ++++++-- + 1 file changed, 6 insertions(+), 2 deletions(-) + +--- a/drivers/media/usb/pwc/pwc-if.c ++++ b/drivers/media/usb/pwc/pwc-if.c +@@ -711,11 +711,15 @@ static int start_streaming(struct vb2_qu + struct pwc_device *pdev = vb2_get_drv_priv(vq); + int r; + +- if (!pdev->udev) ++ if (!pdev->udev) { ++ pwc_cleanup_queued_bufs(pdev, VB2_BUF_STATE_QUEUED); + return -ENODEV; ++ } + +- if (mutex_lock_interruptible(&pdev->v4l2_lock)) ++ if (mutex_lock_interruptible(&pdev->v4l2_lock)) { ++ pwc_cleanup_queued_bufs(pdev, VB2_BUF_STATE_QUEUED); + return -ERESTARTSYS; ++ } + /* Turn on camera and set LEDS on */ + pwc_camera_power(pdev, 1); + pwc_set_leds(pdev, leds[0], leds[1]); diff --git a/queue-5.15/media-radio-si476x-unregister-v4l2_device-on-probe-failure.patch b/queue-5.15/media-radio-si476x-unregister-v4l2_device-on-probe-failure.patch new file mode 100644 index 0000000000..0e4642f37e --- /dev/null +++ b/queue-5.15/media-radio-si476x-unregister-v4l2_device-on-probe-failure.patch @@ -0,0 +1,42 @@ +From 436a693af04ffb889aaf87cb69ec1f2b21d3569c Mon Sep 17 00:00:00 2001 +From: Myeonghun Pak +Date: Wed, 13 May 2026 16:02:37 +0900 +Subject: media: radio-si476x: Unregister v4l2_device on probe failure + +From: Myeonghun Pak + +commit 436a693af04ffb889aaf87cb69ec1f2b21d3569c upstream. + +si476x_radio_probe() registers radio->v4l2dev before allocating the V4L2 +controls and before registering the video device. If any of those later +steps fails, probe returns through the exit label after freeing only the +control handler. + +A failed probe does not call si476x_radio_remove(), so the +v4l2_device_unregister() there is not reached. This leaves the parent +device reference taken by v4l2_device_register() behind on the error path. + +Unregister the V4L2 device in the probe error path after freeing the +controls. + +Fixes: b879a9c2a755 ("[media] v4l2: Add a V4L2 driver for SI476X MFD") +Cc: stable@vger.kernel.org +Co-developed-by: Ijae Kim +Signed-off-by: Ijae Kim +Signed-off-by: Myeonghun Pak +Signed-off-by: Hans Verkuil +Signed-off-by: Greg Kroah-Hartman +--- + drivers/media/radio/radio-si476x.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/media/radio/radio-si476x.c ++++ b/drivers/media/radio/radio-si476x.c +@@ -1504,6 +1504,7 @@ static int si476x_radio_probe(struct pla + return 0; + exit: + v4l2_ctrl_handler_free(radio->videodev.ctrl_handler); ++ v4l2_device_unregister(&radio->v4l2dev); + return rval; + } + diff --git a/queue-5.15/media-rtl2832-fix-use-after-free-in-rtl2832_remove.patch b/queue-5.15/media-rtl2832-fix-use-after-free-in-rtl2832_remove.patch new file mode 100644 index 0000000000..88ff5216da --- /dev/null +++ b/queue-5.15/media-rtl2832-fix-use-after-free-in-rtl2832_remove.patch @@ -0,0 +1,54 @@ +From 680daf40a82d483949f87f0d8f98639dc47e610c Mon Sep 17 00:00:00 2001 +From: Deepanshu Kartikey +Date: Wed, 22 Apr 2026 20:17:34 +0530 +Subject: media: rtl2832: fix use-after-free in rtl2832_remove() + +From: Deepanshu Kartikey + +commit 680daf40a82d483949f87f0d8f98639dc47e610c upstream. + +cancel_delayed_work_sync() is called before i2c_mux_del_adapters() +in rtl2832_remove(). While the cancel waits for any running instance +of i2c_gate_work to finish, it does not prevent the timer from being +rescheduled by a concurrent thread. + +During probe, the r820t_attach() call attempts I2C transfers through +the mux adapter. These transfers go through i2c_mux_master_xfer(), +which calls rtl2832_deselect() after the transfer completes, +rescheduling i2c_gate_work via schedule_delayed_work(). If this +transfer is still in flight when rtl2832_remove() runs, +rtl2832_deselect() can reschedule i2c_gate_work after it has been +cancelled, causing a use-after-free when kfree(dev) is called. + +Fix this by calling i2c_mux_del_adapters() before +cancel_delayed_work_sync(). Once the mux adapter is unregistered, no +new I2C transfers can go through it, so rtl2832_deselect() can no +longer reschedule i2c_gate_work. The subsequent +cancel_delayed_work_sync() is then guaranteed to be final. + +Fixes: cddcc40b1b15 ("[media] rtl2832: convert to use an explicit i2c mux core") +Cc: stable@vger.kernel.org +Reported-by: syzbot+019ced393ab913002b75@syzkaller.appspotmail.com +Closes: https://syzkaller.appspot.com/bug?extid=019ced393ab913002b75 +Signed-off-by: Deepanshu Kartikey +Signed-off-by: Hans Verkuil +Signed-off-by: Greg Kroah-Hartman +--- + drivers/media/dvb-frontends/rtl2832.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/drivers/media/dvb-frontends/rtl2832.c ++++ b/drivers/media/dvb-frontends/rtl2832.c +@@ -1116,10 +1116,10 @@ static int rtl2832_remove(struct i2c_cli + + dev_dbg(&client->dev, "\n"); + +- cancel_delayed_work_sync(&dev->i2c_gate_work); +- + i2c_mux_del_adapters(dev->muxc); + ++ cancel_delayed_work_sync(&dev->i2c_gate_work); ++ + regmap_exit(dev->regmap); + + kfree(dev); diff --git a/queue-5.15/media-rtl2832_sdr-return-queued-buffers-on-start_streaming-failure.patch b/queue-5.15/media-rtl2832_sdr-return-queued-buffers-on-start_streaming-failure.patch new file mode 100644 index 0000000000..8c2eaacc33 --- /dev/null +++ b/queue-5.15/media-rtl2832_sdr-return-queued-buffers-on-start_streaming-failure.patch @@ -0,0 +1,111 @@ +From 33ca0aab6f4bd90921fc1395478f38f72c4d19af Mon Sep 17 00:00:00 2001 +From: Valery Borovsky +Date: Mon, 11 May 2026 20:12:09 +0300 +Subject: media: rtl2832_sdr: Return queued buffers on start_streaming() failure + +From: Valery Borovsky + +commit 33ca0aab6f4bd90921fc1395478f38f72c4d19af upstream. + +The vb2 framework hands buffers to the driver via buf_queue() before +calling start_streaming(). If start_streaming() returns an error +without first returning those buffers via vb2_buffer_done(), +vb2_start_streaming() fires WARN_ON(owned_by_drv_count) and the queued +buffers leak. + +rtl2832_sdr_start_streaming() had multiple error paths that hit this +trap: two direct early returns (-ENODEV, -ERESTARTSYS), plus six +`goto err` paths covering subdev s_power, tuner setup, ADC setup, +stream-buffer allocation, urb allocation, and urb submission failures. +None of them returned the queued buffers. + +The original function had no distinct success exit and fell straight +through into the err label, which previously only did mutex_unlock and +"return ret". Adding queued-buffer cleanup at err must therefore be +paired with an explicit success return; otherwise every successful +start would also drain the buffer queue and kill streaming. Add that +success return, then add rtl2832_sdr_cleanup_queued_bufs() at the err +label and before each early return. + +The cleanup helper takes a vb2_buffer_state argument so that the +start_streaming error paths can pass VB2_BUF_STATE_QUEUED (as +expected by userspace on start_streaming failure) while stop_streaming +keeps its existing VB2_BUF_STATE_ERROR semantics. + +This mirrors the uvcvideo fix in commit 4cf3b6fd54eb ("media: uvcvideo: +Return queued buffers on start_streaming() failure"). + +The err label still does not roll back power_ctrl(), frontend_ctrl(), +the POWER_ON flag, or stream/URB allocations that may have happened +before the failing step. Those are pre-existing leaks of a different +class and are not addressed here. + +Fixes: 771138920eaf ("[media] rtl2832_sdr: Realtek RTL2832 SDR driver module") +Cc: stable@vger.kernel.org +Signed-off-by: Valery Borovsky +Signed-off-by: Hans Verkuil +Signed-off-by: Greg Kroah-Hartman +--- + drivers/media/dvb-frontends/rtl2832_sdr.c | 19 ++++++++++++++----- + 1 file changed, 14 insertions(+), 5 deletions(-) + +--- a/drivers/media/dvb-frontends/rtl2832_sdr.c ++++ b/drivers/media/dvb-frontends/rtl2832_sdr.c +@@ -396,7 +396,8 @@ static int rtl2832_sdr_alloc_urbs(struct + } + + /* Must be called with vb_queue_lock hold */ +-static void rtl2832_sdr_cleanup_queued_bufs(struct rtl2832_sdr_dev *dev) ++static void rtl2832_sdr_cleanup_queued_bufs(struct rtl2832_sdr_dev *dev, ++ enum vb2_buffer_state state) + { + struct platform_device *pdev = dev->pdev; + unsigned long flags; +@@ -410,7 +411,7 @@ static void rtl2832_sdr_cleanup_queued_b + buf = list_entry(dev->queued_bufs.next, + struct rtl2832_sdr_frame_buf, list); + list_del(&buf->list); +- vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_ERROR); ++ vb2_buffer_done(&buf->vb.vb2_buf, state); + } + spin_unlock_irqrestore(&dev->queued_bufs_lock, flags); + } +@@ -851,11 +852,15 @@ static int rtl2832_sdr_start_streaming(s + + dev_dbg(&pdev->dev, "\n"); + +- if (!dev->udev) ++ if (!dev->udev) { ++ rtl2832_sdr_cleanup_queued_bufs(dev, VB2_BUF_STATE_QUEUED); + return -ENODEV; ++ } + +- if (mutex_lock_interruptible(&dev->v4l2_lock)) ++ if (mutex_lock_interruptible(&dev->v4l2_lock)) { ++ rtl2832_sdr_cleanup_queued_bufs(dev, VB2_BUF_STATE_QUEUED); + return -ERESTARTSYS; ++ } + + if (d->props->power_ctrl) + d->props->power_ctrl(d, 1); +@@ -896,7 +901,11 @@ static int rtl2832_sdr_start_streaming(s + if (ret) + goto err; + ++ mutex_unlock(&dev->v4l2_lock); ++ return 0; ++ + err: ++ rtl2832_sdr_cleanup_queued_bufs(dev, VB2_BUF_STATE_QUEUED); + mutex_unlock(&dev->v4l2_lock); + + return ret; +@@ -916,7 +925,7 @@ static void rtl2832_sdr_stop_streaming(s + rtl2832_sdr_kill_urbs(dev); + rtl2832_sdr_free_urbs(dev); + rtl2832_sdr_free_stream_bufs(dev); +- rtl2832_sdr_cleanup_queued_bufs(dev); ++ rtl2832_sdr_cleanup_queued_bufs(dev, VB2_BUF_STATE_ERROR); + rtl2832_sdr_unset_adc(dev); + + /* sleep tuner */ diff --git a/queue-5.15/media-saa7134-fix-a-possible-memory-leak-in-saa7134_video_init1.patch b/queue-5.15/media-saa7134-fix-a-possible-memory-leak-in-saa7134_video_init1.patch new file mode 100644 index 0000000000..1043605a68 --- /dev/null +++ b/queue-5.15/media-saa7134-fix-a-possible-memory-leak-in-saa7134_video_init1.patch @@ -0,0 +1,79 @@ +From f86ed548386e3050e5f8f25b450d09dc009d9a88 Mon Sep 17 00:00:00 2001 +From: Ma Ke +Date: Thu, 2 Apr 2026 15:35:29 +0800 +Subject: media: saa7134: Fix a possible memory leak in saa7134_video_init1 + +From: Ma Ke + +commit f86ed548386e3050e5f8f25b450d09dc009d9a88 upstream. + +In saa7134_video_init1(), the return value of the first +saa7134_pgtable_alloc() is not checked. If it fails, the function +continues as if successful, leaving the driver with an invalid page +table. Additionally, if vb2_queue_init() for the VBI queue fails after +the video queue page table has been allocated, the allocated memory is +not freed before returning. The second saa7134_pgtable_alloc() also +lacks a return value check. Errors occur during device probing before +the device is fully registered, the normal cleanup path in +saa7134_finidev() is not executed, leading to memory leaks and +potential use of uninitialized DMA resources. + +Check the return value of both saa7134_pgtable_alloc() calls and +propagate errors. On failure of any later step, free allocated page +tables to avoid memory leaks. Ensure control handlers are also +released on error to prevent further resource leakage. + +Found by code review. + +Signed-off-by: Ma Ke +Cc: stable@vger.kernel.org +Fixes: a00e68888d5d ("[media] saa7134: move saa7134_pgtable to saa7134_dmaqueue") +Signed-off-by: Hans Verkuil +Signed-off-by: Greg Kroah-Hartman +--- + drivers/media/pci/saa7134/saa7134-video.c | 25 ++++++++++++++++++++----- + 1 file changed, 20 insertions(+), 5 deletions(-) + +--- a/drivers/media/pci/saa7134/saa7134-video.c ++++ b/drivers/media/pci/saa7134/saa7134-video.c +@@ -2126,8 +2126,10 @@ int saa7134_video_init1(struct saa7134_d + q->dev = &dev->pci->dev; + ret = vb2_queue_init(q); + if (ret) +- return ret; +- saa7134_pgtable_alloc(dev->pci, &dev->video_q.pt); ++ goto err_free_ctrl; ++ ret = saa7134_pgtable_alloc(dev->pci, &dev->video_q.pt); ++ if (ret) ++ goto err_free_ctrl; + + q = &dev->vbi_vbq; + q->type = V4L2_BUF_TYPE_VBI_CAPTURE; +@@ -2144,11 +2146,24 @@ int saa7134_video_init1(struct saa7134_d + q->lock = &dev->lock; + q->dev = &dev->pci->dev; + ret = vb2_queue_init(q); +- if (ret) +- return ret; +- saa7134_pgtable_alloc(dev->pci, &dev->vbi_q.pt); ++ if (ret) { ++ saa7134_pgtable_free(dev->pci, &dev->video_q.pt); ++ goto err_free_ctrl; ++ } ++ ++ ret = saa7134_pgtable_alloc(dev->pci, &dev->vbi_q.pt); ++ if (ret) { ++ saa7134_pgtable_free(dev->pci, &dev->video_q.pt); ++ goto err_free_ctrl; ++ } + + return 0; ++ ++err_free_ctrl: ++ v4l2_ctrl_handler_free(&dev->ctrl_handler); ++ if (card_has_radio(dev)) ++ v4l2_ctrl_handler_free(&dev->radio_ctrl_handler); ++ return ret; + } + + void saa7134_video_fini(struct saa7134_dev *dev) diff --git a/queue-5.15/media-sun4i-csi-return-queued-buffers-on-start_streaming-failure.patch b/queue-5.15/media-sun4i-csi-return-queued-buffers-on-start_streaming-failure.patch new file mode 100644 index 0000000000..efd73ddae9 --- /dev/null +++ b/queue-5.15/media-sun4i-csi-return-queued-buffers-on-start_streaming-failure.patch @@ -0,0 +1,51 @@ +From bbba3e260a62810a717b4442a3bb96d0ec0f6309 Mon Sep 17 00:00:00 2001 +From: Valery Borovsky +Date: Mon, 11 May 2026 20:12:11 +0300 +Subject: media: sun4i-csi: Return queued buffers on start_streaming() failure + +From: Valery Borovsky + +commit bbba3e260a62810a717b4442a3bb96d0ec0f6309 upstream. + +The vb2 framework hands buffers to the driver via buf_queue() before +calling start_streaming(). If start_streaming() returns an error +without first returning those buffers via vb2_buffer_done(), +vb2_start_streaming() fires WARN_ON(owned_by_drv_count) and the queued +buffers leak. + +sun4i_csi_start_streaming() returned -EINVAL when no matching CSI +format could be found, before any setup (scratch buffer allocation, +pipeline start) had been performed. The remaining error paths already +converge on the err_clear_dma_queue label, which calls +return_all_buffers(..., VB2_BUF_STATE_QUEUED) under csi->qlock. Jump +to that label directly: the intermediate err_disable_device / +err_disable_pipeline / err_free_scratch_buffer labels are skipped, +which is correct because nothing they would undo has happened yet. + +This mirrors the uvcvideo fix in commit 4cf3b6fd54eb ("media: uvcvideo: +Return queued buffers on start_streaming() failure"). + +Fixes: 577bbf23b758 ("media: sunxi: Add A10 CSI driver") +Cc: stable@vger.kernel.org +Signed-off-by: Valery Borovsky +Signed-off-by: Hans Verkuil +Signed-off-by: Greg Kroah-Hartman +--- + drivers/media/platform/sunxi/sun4i-csi/sun4i_dma.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +--- a/drivers/media/platform/sunxi/sun4i-csi/sun4i_dma.c ++++ b/drivers/media/platform/sunxi/sun4i-csi/sun4i_dma.c +@@ -234,8 +234,10 @@ static int sun4i_csi_start_streaming(str + int ret; + + csi_fmt = sun4i_csi_find_format(&csi->fmt.pixelformat, NULL); +- if (!csi_fmt) +- return -EINVAL; ++ if (!csi_fmt) { ++ ret = -EINVAL; ++ goto err_clear_dma_queue; ++ } + + dev_dbg(csi->dev, "Starting capture\n"); + diff --git a/queue-5.15/media-tegra-video-vi-fix-invalid-u32-return-value-in-format-lookup.patch b/queue-5.15/media-tegra-video-vi-fix-invalid-u32-return-value-in-format-lookup.patch new file mode 100644 index 0000000000..7591859ac7 --- /dev/null +++ b/queue-5.15/media-tegra-video-vi-fix-invalid-u32-return-value-in-format-lookup.patch @@ -0,0 +1,41 @@ +From d5b50055338e131a1a99f923ebb0361974a00f36 Mon Sep 17 00:00:00 2001 +From: Hungyu Lin +Date: Thu, 7 May 2026 02:22:13 +0000 +Subject: media: tegra-video: vi: fix invalid u32 return value in format lookup + +From: Hungyu Lin + +commit d5b50055338e131a1a99f923ebb0361974a00f36 upstream. + +tegra_get_format_fourcc_by_idx() returns a u32 but uses -EINVAL to +signal an out-of-bounds index. This results in a large unsigned +value being returned, which may be interpreted as a valid fourcc. + +Returning 0 is not a valid fourcc either. This condition should +never happen, so use WARN_ON_ONCE() to catch unexpected out-of-bounds +access and return a valid fallback format instead. + +Suggested-by: Hans Verkuil +Fixes: 3d8a97eabef0 ("media: tegra-video: Add Tegra210 Video input driver") +Cc: stable@vger.kernel.org +Reviewed-by: Luca Ceresoli +Signed-off-by: Hungyu Lin +Signed-off-by: Hans Verkuil +Signed-off-by: Greg Kroah-Hartman +--- + drivers/staging/media/tegra-video/vi.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/drivers/staging/media/tegra-video/vi.c ++++ b/drivers/staging/media/tegra-video/vi.c +@@ -76,8 +76,8 @@ static int tegra_get_format_idx_by_code( + static u32 tegra_get_format_fourcc_by_idx(struct tegra_vi *vi, + unsigned int index) + { +- if (index >= vi->soc->nformats) +- return -EINVAL; ++ if (WARN_ON_ONCE(index >= vi->soc->nformats)) ++ return vi->soc->video_formats[0].fourcc; + + return vi->soc->video_formats[index].fourcc; + } diff --git a/queue-5.15/media-v4l2-ctrls-request-add-null-check-in-v4l2_ctrl_request_complete.patch b/queue-5.15/media-v4l2-ctrls-request-add-null-check-in-v4l2_ctrl_request_complete.patch new file mode 100644 index 0000000000..9d1c70c791 --- /dev/null +++ b/queue-5.15/media-v4l2-ctrls-request-add-null-check-in-v4l2_ctrl_request_complete.patch @@ -0,0 +1,60 @@ +From caced3578bf9f104a4aaad8f46c4c719e705d9a6 Mon Sep 17 00:00:00 2001 +From: Sergey Shtylyov +Date: Fri, 1 May 2026 23:28:31 +0300 +Subject: media: v4l2-ctrls-request: add NULL check in v4l2_ctrl_request_complete() + +From: Sergey Shtylyov + +commit caced3578bf9f104a4aaad8f46c4c719e705d9a6 upstream. + +If CONFIG_MEDIA_CONTROLLER is undefined, media_request_object_find() will +always return NULL, so its 2nd call in v4l2_ctrl_request_complete() would +fail as well as the 1st one and thus cause hdl to have a wrong value (at +the top of memory) and list_for_each_entry() to iterate over the garbage +data located there. Add NULL check for the 2nd call and place the error +cleanup at the end of v4l2_ctrl_request_complete()... + +Found by Linux Verification Center (linuxtesting.org) with the Svace static +analysis tool. + +Fixes: c3bf5129f339 ("media: v4l2-ctrls: always copy the controls on completion") +Cc: stable@vger.kernel.org +Signed-off-by: Sergey Shtylyov +Signed-off-by: Hans Verkuil +Signed-off-by: Greg Kroah-Hartman +--- + drivers/media/v4l2-core/v4l2-ctrls-request.c | 14 +++++++++----- + 1 file changed, 9 insertions(+), 5 deletions(-) + +--- a/drivers/media/v4l2-core/v4l2-ctrls-request.c ++++ b/drivers/media/v4l2-core/v4l2-ctrls-request.c +@@ -348,13 +348,12 @@ void v4l2_ctrl_request_complete(struct m + ret = v4l2_ctrl_handler_init(hdl, (main_hdl->nr_of_buckets - 1) * 8); + if (!ret) + ret = v4l2_ctrl_request_bind(req, hdl, main_hdl); +- if (ret) { +- v4l2_ctrl_handler_free(hdl); +- kfree(hdl); +- return; +- } ++ if (ret) ++ goto error; + hdl->request_is_queued = true; + obj = media_request_object_find(req, &req_ops, main_hdl); ++ if (!obj) ++ goto error; + } + hdl = container_of(obj, struct v4l2_ctrl_handler, req_obj); + +@@ -389,6 +388,11 @@ void v4l2_ctrl_request_complete(struct m + mutex_unlock(main_hdl->lock); + media_request_object_complete(obj); + media_request_object_put(obj); ++ return; ++ ++error: ++ v4l2_ctrl_handler_free(hdl); ++ kfree(hdl); + } + EXPORT_SYMBOL(v4l2_ctrl_request_complete); + diff --git a/queue-5.15/media-vb2-use-ssize_t-for-vb2_read-vb2_write.patch b/queue-5.15/media-vb2-use-ssize_t-for-vb2_read-vb2_write.patch new file mode 100644 index 0000000000..08b31ee0bc --- /dev/null +++ b/queue-5.15/media-vb2-use-ssize_t-for-vb2_read-vb2_write.patch @@ -0,0 +1,99 @@ +From a562d6dc86bdfdd299e1b4734977a8d63e803583 Mon Sep 17 00:00:00 2001 +From: Zile Xiong +Date: Fri, 20 Mar 2026 14:54:45 +0800 +Subject: media: vb2: use ssize_t for vb2_read/vb2_write + +From: Zile Xiong + +commit a562d6dc86bdfdd299e1b4734977a8d63e803583 upstream. + +vb2_read() and vb2_write() return size_t, but propagate +negative errno values from __vb2_perform_fileio(). + +This relies on implicit signed/unsigned conversions in callers +(e.g. vb2_fop_read()) to recover error codes: + + __vb2_perform_fileio() -> -EINVAL + vb2_read() -> (size_t)-EINVAL + vb2_fop_read() -> -EINVAL + +This relies on implicit conversions that are not obvious. + +These helpers are exported (EXPORT_SYMBOL_GPL) and part of the +vb2 API, so changing their return type may affect existing users. + +However, they conceptually follow read/write semantics, where +ssize_t is typically used to return either a byte count or a +negative error code. + +Switch vb2_read() and vb2_write() to ssize_t, and update +__vb2_perform_fileio() accordingly. + +Signed-off-by: Zile Xiong +Acked-by: Marek Szyprowski +Fixes: b25748fe6126 ("[media] v4l: videobuf2: add read() and write() emulator") +Cc: stable@vger.kernel.org +Signed-off-by: Hans Verkuil +Signed-off-by: Greg Kroah-Hartman +--- + drivers/media/common/videobuf2/videobuf2-core.c | 12 ++++++------ + include/media/videobuf2-core.h | 8 ++++---- + 2 files changed, 10 insertions(+), 10 deletions(-) + +--- a/drivers/media/common/videobuf2/videobuf2-core.c ++++ b/drivers/media/common/videobuf2/videobuf2-core.c +@@ -2719,8 +2719,8 @@ static int __vb2_cleanup_fileio(struct v + * @nonblock: mode selector (1 means blocking calls, 0 means nonblocking) + * @read: access mode selector (1 means read, 0 means write) + */ +-static size_t __vb2_perform_fileio(struct vb2_queue *q, char __user *data, size_t count, +- loff_t *ppos, int nonblock, int read) ++static ssize_t __vb2_perform_fileio(struct vb2_queue *q, char __user *data, size_t count, ++ loff_t *ppos, int nonblock, int read) + { + struct vb2_fileio_data *fileio; + struct vb2_fileio_buf *buf; +@@ -2880,15 +2880,15 @@ static size_t __vb2_perform_fileio(struc + return ret; + } + +-size_t vb2_read(struct vb2_queue *q, char __user *data, size_t count, +- loff_t *ppos, int nonblocking) ++ssize_t vb2_read(struct vb2_queue *q, char __user *data, size_t count, ++ loff_t *ppos, int nonblocking) + { + return __vb2_perform_fileio(q, data, count, ppos, nonblocking, 1); + } + EXPORT_SYMBOL_GPL(vb2_read); + +-size_t vb2_write(struct vb2_queue *q, const char __user *data, size_t count, +- loff_t *ppos, int nonblocking) ++ssize_t vb2_write(struct vb2_queue *q, const char __user *data, size_t count, ++ loff_t *ppos, int nonblocking) + { + return __vb2_perform_fileio(q, (char __user *) data, count, + ppos, nonblocking, 0); +--- a/include/media/videobuf2-core.h ++++ b/include/media/videobuf2-core.h +@@ -1044,8 +1044,8 @@ __poll_t vb2_core_poll(struct vb2_queue + * @ppos: file handle position tracking pointer + * @nonblock: mode selector (1 means blocking calls, 0 means nonblocking) + */ +-size_t vb2_read(struct vb2_queue *q, char __user *data, size_t count, +- loff_t *ppos, int nonblock); ++ssize_t vb2_read(struct vb2_queue *q, char __user *data, size_t count, ++ loff_t *ppos, int nonblock); + /** + * vb2_write() - implements write() syscall logic. + * @q: pointer to &struct vb2_queue with videobuf2 queue. +@@ -1054,8 +1054,8 @@ size_t vb2_read(struct vb2_queue *q, cha + * @ppos: file handle position tracking pointer + * @nonblock: mode selector (1 means blocking calls, 0 means nonblocking) + */ +-size_t vb2_write(struct vb2_queue *q, const char __user *data, size_t count, +- loff_t *ppos, int nonblock); ++ssize_t vb2_write(struct vb2_queue *q, const char __user *data, size_t count, ++ loff_t *ppos, int nonblock); + + /** + * typedef vb2_thread_fnc - callback function for use with vb2_thread. diff --git a/queue-5.15/media-vidtv-fix-reference-leak-on-failed-device-registration.patch b/queue-5.15/media-vidtv-fix-reference-leak-on-failed-device-registration.patch new file mode 100644 index 0000000000..653b942aeb --- /dev/null +++ b/queue-5.15/media-vidtv-fix-reference-leak-on-failed-device-registration.patch @@ -0,0 +1,49 @@ +From 9aa21e1549db8882ff77b691e7714153df21dff0 Mon Sep 17 00:00:00 2001 +From: Guangshuo Li +Date: Wed, 15 Apr 2026 23:28:26 +0800 +Subject: media: vidtv: fix reference leak on failed device registration + +From: Guangshuo Li + +commit 9aa21e1549db8882ff77b691e7714153df21dff0 upstream. + +When platform_device_register() fails in vidtv_bridge_init(), the +embedded struct device in vidtv_bridge_dev has already been initialized +by device_initialize(), but the failure path returns the error without +dropping the device reference for the current platform device: + + vidtv_bridge_init() + -> platform_device_register(&vidtv_bridge_dev) + -> device_initialize(&vidtv_bridge_dev.dev) + -> setup_pdev_dma_masks(&vidtv_bridge_dev) + -> platform_device_add(&vidtv_bridge_dev) + +This leads to a reference leak when platform_device_register() fails. +Fix this by calling platform_device_put() before returning the error. + +The issue was identified by a static analysis tool I developed and +confirmed by manual review. + +Fixes: f90cf6079bf67 ("media: vidtv: add a bridge driver") +Cc: stable@vger.kernel.org +Signed-off-by: Guangshuo Li +Signed-off-by: Hans Verkuil +Signed-off-by: Greg Kroah-Hartman +--- + drivers/media/test-drivers/vidtv/vidtv_bridge.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +--- a/drivers/media/test-drivers/vidtv/vidtv_bridge.c ++++ b/drivers/media/test-drivers/vidtv/vidtv_bridge.c +@@ -596,8 +596,10 @@ static int __init vidtv_bridge_init(void + int ret; + + ret = platform_device_register(&vidtv_bridge_dev); +- if (ret) ++ if (ret) { ++ platform_device_put(&vidtv_bridge_dev); + return ret; ++ } + + ret = platform_driver_register(&vidtv_bridge_driver); + if (ret) diff --git a/queue-5.15/media-vimc-fix-reference-leak-on-failed-device-registration.patch b/queue-5.15/media-vimc-fix-reference-leak-on-failed-device-registration.patch new file mode 100644 index 0000000000..352d86cfba --- /dev/null +++ b/queue-5.15/media-vimc-fix-reference-leak-on-failed-device-registration.patch @@ -0,0 +1,45 @@ +From 33e2b833c66b890a0d71c4fa82d4c97143f7f75f Mon Sep 17 00:00:00 2001 +From: Guangshuo Li +Date: Wed, 15 Apr 2026 23:45:37 +0800 +Subject: media: vimc: fix reference leak on failed device registration + +From: Guangshuo Li + +commit 33e2b833c66b890a0d71c4fa82d4c97143f7f75f upstream. + +When platform_device_register() fails in vimc_init(), the embedded +struct device in vimc_pdev has already been initialized by +device_initialize(), but the failure path returns the error without +dropping the device reference for the current platform device: + + vimc_init() + -> platform_device_register(&vimc_pdev) + -> device_initialize(&vimc_pdev.dev) + -> setup_pdev_dma_masks(&vimc_pdev) + -> platform_device_add(&vimc_pdev) + +This leads to a reference leak when platform_device_register() fails. +Fix this by calling platform_device_put() before returning the error. + +The issue was identified by a static analysis tool I developed and +confirmed by manual review. + +Fixes: 4babf057c143f ("media: vimc: allocate vimc_device dynamically") +Cc: stable@vger.kernel.org +Signed-off-by: Guangshuo Li +Signed-off-by: Hans Verkuil +Signed-off-by: Greg Kroah-Hartman +--- + drivers/media/test-drivers/vimc/vimc-core.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/media/test-drivers/vimc/vimc-core.c ++++ b/drivers/media/test-drivers/vimc/vimc-core.c +@@ -350,6 +350,7 @@ static int __init vimc_init(void) + if (ret) { + dev_err(&vimc_pdev.dev, + "platform device registration failed (err=%d)\n", ret); ++ platform_device_put(&vimc_pdev); + return ret; + } + diff --git a/queue-5.15/media-vivid-check-for-vb2_is_busy-when-toggling-caps.patch b/queue-5.15/media-vivid-check-for-vb2_is_busy-when-toggling-caps.patch new file mode 100644 index 0000000000..661e6178b3 --- /dev/null +++ b/queue-5.15/media-vivid-check-for-vb2_is_busy-when-toggling-caps.patch @@ -0,0 +1,115 @@ +From c2d1a2130c93f6d758af58590b86b2254c7a1dec Mon Sep 17 00:00:00 2001 +From: Hans Verkuil +Date: Wed, 20 May 2026 09:22:41 +0200 +Subject: media: vivid: check for vb2_is_busy() when toggling caps + +From: Hans Verkuil + +commit c2d1a2130c93f6d758af58590b86b2254c7a1dec upstream. + +The vivid_update_format_cap/out() functions must only be called if the +capture/output queue are not busy. But for the controls that select +the CROP/COMPOSE/SCALE capability that is not checked. + +Only when streaming starts will they be set to 'grabbed' and it is +impossible to change the control, but between REQBUFS and STREAMON you +are still allowed to set these controls. Since vivid_update_format_cap/out +will change the format, this can cause unexpected results. + +Besides adding these checks, also add a WARN_ON in +vivid_update_format_cap/out() if the queue is busy. + +I'm 90% certain that this is the cause of this syzbot bug: + +https://syzkaller.appspot.com/bug?extid=dac8f5eaa46837e97b89 + +But since we never have reproducers, it is hard to be certain. In any case, +these checks are needed regardless. + +Reviewed-by: Nicolas Dufresne +Fixes: 73c3f48230cd ("[media] vivid: add the control handling code") +Cc: stable@vger.kernel.org +Reported-by: syzbot+dac8f5eaa46837e97b89@syzkaller.appspotmail.com +Closes: https://syzkaller.appspot.com/bug?extid=dac8f5eaa46837e97b89 +Signed-off-by: Hans Verkuil +Signed-off-by: Greg Kroah-Hartman +--- + drivers/media/test-drivers/vivid/vivid-ctrls.c | 12 ++++++++++++ + drivers/media/test-drivers/vivid/vivid-vid-cap.c | 6 ++++++ + drivers/media/test-drivers/vivid/vivid-vid-out.c | 6 ++++++ + 3 files changed, 24 insertions(+) + +--- a/drivers/media/test-drivers/vivid/vivid-ctrls.c ++++ b/drivers/media/test-drivers/vivid/vivid-ctrls.c +@@ -487,14 +487,20 @@ static int vivid_vid_cap_s_ctrl(struct v + vivid_update_format_cap(dev, true); + break; + case VIVID_CID_HAS_CROP_CAP: ++ if (vb2_is_busy(&dev->vb_vid_cap_q)) ++ return -EBUSY; + dev->has_crop_cap = ctrl->val; + vivid_update_format_cap(dev, true); + break; + case VIVID_CID_HAS_COMPOSE_CAP: ++ if (vb2_is_busy(&dev->vb_vid_cap_q)) ++ return -EBUSY; + dev->has_compose_cap = ctrl->val; + vivid_update_format_cap(dev, true); + break; + case VIVID_CID_HAS_SCALER_CAP: ++ if (vb2_is_busy(&dev->vb_vid_cap_q)) ++ return -EBUSY; + dev->has_scaler_cap = ctrl->val; + vivid_update_format_cap(dev, true); + break; +@@ -970,14 +976,20 @@ static int vivid_vid_out_s_ctrl(struct v + + switch (ctrl->id) { + case VIVID_CID_HAS_CROP_OUT: ++ if (vb2_is_busy(&dev->vb_vid_out_q)) ++ return -EBUSY; + dev->has_crop_out = ctrl->val; + vivid_update_format_out(dev); + break; + case VIVID_CID_HAS_COMPOSE_OUT: ++ if (vb2_is_busy(&dev->vb_vid_out_q)) ++ return -EBUSY; + dev->has_compose_out = ctrl->val; + vivid_update_format_out(dev); + break; + case VIVID_CID_HAS_SCALER_OUT: ++ if (vb2_is_busy(&dev->vb_vid_out_q)) ++ return -EBUSY; + dev->has_scaler_out = ctrl->val; + vivid_update_format_out(dev); + break; +--- a/drivers/media/test-drivers/vivid/vivid-vid-cap.c ++++ b/drivers/media/test-drivers/vivid/vivid-vid-cap.c +@@ -385,6 +385,12 @@ void vivid_update_format_cap(struct vivi + unsigned size; + u64 pixelclock; + ++ /* ++ * This resets the format, so must never be called while vb2_is_busy(). ++ */ ++ if (WARN_ON(vb2_is_busy(&dev->vb_vid_cap_q))) ++ return; ++ + switch (dev->input_type[dev->input]) { + case WEBCAM: + default: +--- a/drivers/media/test-drivers/vivid/vivid-vid-out.c ++++ b/drivers/media/test-drivers/vivid/vivid-vid-out.c +@@ -222,6 +222,12 @@ void vivid_update_format_out(struct vivi + unsigned size, p; + u64 pixelclock; + ++ /* ++ * This resets the format, so must never be called while vb2_is_busy(). ++ */ ++ if (WARN_ON(vb2_is_busy(&dev->vb_vid_out_q))) ++ return; ++ + switch (dev->output_type[dev->output]) { + case SVID: + default: diff --git a/queue-5.15/series b/queue-5.15/series index e9f823db16..53925a35c9 100644 --- a/queue-5.15/series +++ b/queue-5.15/series @@ -162,3 +162,26 @@ media-cx231xx-fix-devres-lifetime.patch media-cx23885-add-ioremap-return-check-and-cleanup.patch media-meson-vdec-fix-memory-leak-in-error-path-of-vdec_open.patch media-msi2500-return-queued-buffers-on-start_streaming-failure.patch +media-pci-dm1105-free-allocated-workqueue.patch +media-pwc-drain-fill_buf-on-start_streaming-failure.patch +media-pwc-return-queued-buffers-on-start_streaming-failure.patch +media-radio-si476x-unregister-v4l2_device-on-probe-failure.patch +media-rtl2832-fix-use-after-free-in-rtl2832_remove.patch +media-rtl2832_sdr-return-queued-buffers-on-start_streaming-failure.patch +media-saa7134-fix-a-possible-memory-leak-in-saa7134_video_init1.patch +media-sun4i-csi-return-queued-buffers-on-start_streaming-failure.patch +media-tegra-video-vi-fix-invalid-u32-return-value-in-format-lookup.patch +media-v4l2-ctrls-request-add-null-check-in-v4l2_ctrl_request_complete.patch +media-vb2-use-ssize_t-for-vb2_read-vb2_write.patch +media-vidtv-fix-reference-leak-on-failed-device-registration.patch +media-vimc-fix-reference-leak-on-failed-device-registration.patch +media-vivid-check-for-vb2_is_busy-when-toggling-caps.patch +wifi-ath6kl-fix-oob-access-from-firmware-addba-window-size.patch +wifi-mwifiex-fix-null-dereference-when-the-ap-has-ht-cap-but-no-ht-oper.patch +wifi-wilc1000-validate-assoc-response-length-before-subtracting-header.patch +wifi-brcmfmac-make-release_scratchbuffers-idempotent.patch +staging-rtl8723bs-fix-oob-reads-in-rtw_get_wps_ie.patch +staging-rtl8723bs-fix-inverted-ht40-secondary-channel-offset.patch +bluetooth-rfcomm-fix-session-uaf-in-set_termios.patch +exec-fix-unsigned-loop-counter-wrap-in-transfer_args_to_stack.patch +binfmt_misc-set-have_execfd-only-once-the-interpreter-is-opened.patch diff --git a/queue-5.15/staging-rtl8723bs-fix-inverted-ht40-secondary-channel-offset.patch b/queue-5.15/staging-rtl8723bs-fix-inverted-ht40-secondary-channel-offset.patch new file mode 100644 index 0000000000..a560843525 --- /dev/null +++ b/queue-5.15/staging-rtl8723bs-fix-inverted-ht40-secondary-channel-offset.patch @@ -0,0 +1,59 @@ +From 30d49cba27f8905bc288cef5846963f0004f644c Mon Sep 17 00:00:00 2001 +From: MinJea Kim +Date: Tue, 14 Jul 2026 22:14:21 +0900 +Subject: staging: rtl8723bs: fix inverted HT40 secondary channel offset + +From: MinJea Kim + +commit 30d49cba27f8905bc288cef5846963f0004f644c upstream. + +rtw_get_chan_type() maps the driver's channel offset to nl80211 channel +types the wrong way around. + +In this driver HAL_PRIME_CHNL_OFFSET_LOWER means the primary channel is +the lower 20 MHz half of the 40 MHz pair, i.e. the secondary channel is +above the primary one: rtw_get_center_ch() computes the center channel +as "channel + 2" for OFFSET_LOWER, and bwmode_update_check() sets +OFFSET_LOWER when the AP's HT operation IE announces SCA (secondary +channel above). In nl80211 terms that is NL80211_CHAN_HT40PLUS, not +HT40MINUS. + +Because of the inversion, cfg80211_rtw_get_channel() reports an HT40+ +association as HT40-. For an HT40+ AP on a low channel (e.g. channel 3) +the resulting chandef spans below the 2.4 GHz band edge and is invalid, +so the regulatory core tears the connection down 60 seconds +(REG_ENFORCE_GRACE_MS) after the AP's country IE triggers a regdomain +change: reg_check_chans_work() considers the reported chandef unusable +and calls cfg80211_leave(). The supplicant then reconnects, the country +IE changes the regdomain again, and the cycle repeats, causing a +disconnect/reconnect loop every ~65 seconds for as long as the link is +up. + +Observed on a TECLAST X80 Power tablet (RTL8723BS) associated to an +HT40+ AP on channel 3 with a KR country IE; a kprobe trace showed +cfg80211_disconnect() being invoked from reg_check_chans_work(). With +the mapping fixed, "iw dev wlan0 info" reports the correct +"width: 40 MHz, center1: 2432 MHz" and the periodic disconnects stop. + +Fixes: 5402cc178c5d ("staging: rtl8723bs: add get_channel cfg80211 implementation") +Cc: stable@vger.kernel.org +Assisted-by: Claude-Code:claude-fable-5 bpftrace +Signed-off-by: MinJea Kim +Link: https://patch.msgid.link/20260714131421.3980-1-qndkdrnl@gmail.com +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Greg Kroah-Hartman +--- + drivers/staging/rtl8723bs/os_dep/ioctl_cfg80211.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/staging/rtl8723bs/os_dep/ioctl_cfg80211.c ++++ b/drivers/staging/rtl8723bs/os_dep/ioctl_cfg80211.c +@@ -1996,7 +1996,7 @@ static u8 rtw_get_chan_type(struct adapt + else + return NL80211_CHAN_NO_HT; + case CHANNEL_WIDTH_40: +- if (mlme_ext->cur_ch_offset == HAL_PRIME_CHNL_OFFSET_UPPER) ++ if (mlme_ext->cur_ch_offset == HAL_PRIME_CHNL_OFFSET_LOWER) + return NL80211_CHAN_HT40PLUS; + else + return NL80211_CHAN_HT40MINUS; diff --git a/queue-5.15/staging-rtl8723bs-fix-oob-reads-in-rtw_get_wps_ie.patch b/queue-5.15/staging-rtl8723bs-fix-oob-reads-in-rtw_get_wps_ie.patch new file mode 100644 index 0000000000..42126f0ef8 --- /dev/null +++ b/queue-5.15/staging-rtl8723bs-fix-oob-reads-in-rtw_get_wps_ie.patch @@ -0,0 +1,49 @@ +From 0e95ff792ae0aa6fbad9455943e9e1e4062670e9 Mon Sep 17 00:00:00 2001 +From: Moksh Panicker +Date: Thu, 25 Jun 2026 20:29:11 +0000 +Subject: staging: rtl8723bs: fix OOB reads in rtw_get_wps_ie() + +From: Moksh Panicker + +commit 0e95ff792ae0aa6fbad9455943e9e1e4062670e9 upstream. + +rtw_get_wps_ie() iterates over IE data from network frames without +validating that the IE header and payload fit within the remaining +buffer before reading them. Specifically: + +- in_ie[cnt + 1] is read without checking cnt + 1 < in_len +- memcmp(&in_ie[cnt + 2], ...) accesses cnt + 2 without bounds check +- in_ie[cnt + 1] is used as length without verifying payload fits + +Add bounds checks at the top of the loop body to break early if fewer +than 2 bytes remain for the IE header, or if the declared payload +extends past the end of the buffer. Also require at least 4 bytes of +payload before comparing the WPS OUI. + +Fixes: 554c0a3abf21 ("staging: Add rtl8723bs sdio wifi driver") +Cc: stable +Signed-off-by: Moksh Panicker +Link: https://patch.msgid.link/20260625202911.26782-1-mokshpanicker.7@gmail.com +Signed-off-by: Greg Kroah-Hartman +--- + drivers/staging/rtl8723bs/core/rtw_ieee80211.c | 9 ++++++++- + 1 file changed, 8 insertions(+), 1 deletion(-) + +--- a/drivers/staging/rtl8723bs/core/rtw_ieee80211.c ++++ b/drivers/staging/rtl8723bs/core/rtw_ieee80211.c +@@ -694,7 +694,14 @@ u8 *rtw_get_wps_ie(u8 *in_ie, uint in_le + while (cnt < in_len) { + eid = in_ie[cnt]; + +- if ((eid == WLAN_EID_VENDOR_SPECIFIC) && (!memcmp(&in_ie[cnt + 2], wps_oui, 4))) { ++ if (cnt + 2 > in_len) ++ break; ++ ++ if (in_ie[cnt + 1] + 2 > in_len - cnt) ++ break; ++ ++ if ((eid == WLAN_EID_VENDOR_SPECIFIC) && (in_ie[cnt + 1] >= 4) && ++ (!memcmp(&in_ie[cnt + 2], wps_oui, 4))) { + wpsie_ptr = &in_ie[cnt]; + + if (wps_ie) diff --git a/queue-5.15/wifi-ath6kl-fix-oob-access-from-firmware-addba-window-size.patch b/queue-5.15/wifi-ath6kl-fix-oob-access-from-firmware-addba-window-size.patch new file mode 100644 index 0000000000..685c3972fb --- /dev/null +++ b/queue-5.15/wifi-ath6kl-fix-oob-access-from-firmware-addba-window-size.patch @@ -0,0 +1,52 @@ +From 44126b6994eeb28f2103b638e698f40a1244f327 Mon Sep 17 00:00:00 2001 +From: Tristan Madani +Date: Thu, 2 Jul 2026 00:50:20 +0000 +Subject: wifi: ath6kl: fix OOB access from firmware ADDBA window size + +From: Tristan Madani + +commit 44126b6994eeb28f2103b638e698f40a1244f327 upstream. + +aggr_recv_addba_req_evt() logs a debug message when the firmware-supplied +win_sz is outside [AGGR_WIN_SZ_MIN, AGGR_WIN_SZ_MAX] but does not +return. The out-of-range win_sz is then used in TID_WINDOW_SZ() to +compute a kzalloc size and stored in rxtid->hold_q_sz, leading to +zero-size or overflowed allocations and subsequent out-of-bounds access. + +Clean up any previously active aggregation session for the TID first, +then return early when win_sz is out of the valid range, instead of +proceeding with a broken allocation size. + +Fixes: bdcd81707973 ("Add ath6kl cleaned up driver") +Cc: stable@vger.kernel.org +Reviewed-by: Vasanthakumar Thiagarajan +Signed-off-by: Tristan Madani +Link: https://patch.msgid.link/20260702005020.708717-1-tristmd@gmail.com +Signed-off-by: Jeff Johnson +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/wireless/ath/ath6kl/txrx.c | 10 ++++++---- + 1 file changed, 6 insertions(+), 4 deletions(-) + +--- a/drivers/net/wireless/ath/ath6kl/txrx.c ++++ b/drivers/net/wireless/ath/ath6kl/txrx.c +@@ -1722,13 +1722,15 @@ void aggr_recv_addba_req_evt(struct ath6 + + rxtid = &aggr_conn->rx_tid[tid]; + +- if (win_sz < AGGR_WIN_SZ_MIN || win_sz > AGGR_WIN_SZ_MAX) +- ath6kl_dbg(ATH6KL_DBG_WLAN_RX, "%s: win_sz %d, tid %d\n", +- __func__, win_sz, tid); +- + if (rxtid->aggr) + aggr_delete_tid_state(aggr_conn, tid); + ++ if (win_sz < AGGR_WIN_SZ_MIN || win_sz > AGGR_WIN_SZ_MAX) { ++ ath6kl_dbg(ATH6KL_DBG_WLAN_RX, "%s: win_sz %d, tid %d\n", ++ __func__, win_sz, tid); ++ return; ++ } ++ + rxtid->seq_next = seq_no; + hold_q_size = TID_WINDOW_SZ(win_sz) * sizeof(struct skb_hold_q); + rxtid->hold_q = kzalloc(hold_q_size, GFP_KERNEL); diff --git a/queue-5.15/wifi-brcmfmac-make-release_scratchbuffers-idempotent.patch b/queue-5.15/wifi-brcmfmac-make-release_scratchbuffers-idempotent.patch new file mode 100644 index 0000000000..81db5f6dff --- /dev/null +++ b/queue-5.15/wifi-brcmfmac-make-release_scratchbuffers-idempotent.patch @@ -0,0 +1,63 @@ +From 538c51e9d124cf656f2dd0c0394a8545efc7102d Mon Sep 17 00:00:00 2001 +From: Fan Wu +Date: Sat, 18 Jul 2026 02:43:52 +0000 +Subject: wifi: brcmfmac: make release_scratchbuffers idempotent + +From: Fan Wu + +commit 538c51e9d124cf656f2dd0c0394a8545efc7102d upstream. + +brcmf_pcie_release_scratchbuffers() frees the shared.scratch and +shared.ringupd DMA buffers with dma_free_coherent() but does not clear +the pointers afterwards, unlike the sibling release_ringbuffers() which +NULLs commonrings/flowrings/idxbuf on release. + +Both the bus_reset .reset callback (brcmf_pcie_reset) and +brcmf_pcie_remove() call release_scratchbuffers. When reset teardown +has run before removal, remove's own teardown would call +dma_free_coherent() a second time on the already-freed DMA allocation. + +NULL the pointers after free, matching release_ringbuffers(), so a later +release observes that the allocation has already been released. This +patch makes repeated sequential release safe; the reset-work lifetime is +handled separately by the following patch. + +This issue was found by an in-house static analysis tool. + +Fixes: 4684997d9eea ("brcmfmac: reset PCIe bus on a firmware crash") +Cc: stable@vger.kernel.org +Signed-off-by: Fan Wu +Assisted-by: Codex:gpt-5.6 +Acked-by: Arend van Spriel +Link: https://patch.msgid.link/20260718024353.3147201-2-fanwu01@zju.edu.cn +Signed-off-by: Johannes Berg +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c | 8 ++++++-- + 1 file changed, 6 insertions(+), 2 deletions(-) + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c +@@ -1255,16 +1255,20 @@ fail: + static void + brcmf_pcie_release_scratchbuffers(struct brcmf_pciedev_info *devinfo) + { +- if (devinfo->shared.scratch) ++ if (devinfo->shared.scratch) { + dma_free_coherent(&devinfo->pdev->dev, + BRCMF_DMA_D2H_SCRATCH_BUF_LEN, + devinfo->shared.scratch, + devinfo->shared.scratch_dmahandle); +- if (devinfo->shared.ringupd) ++ devinfo->shared.scratch = NULL; ++ } ++ if (devinfo->shared.ringupd) { + dma_free_coherent(&devinfo->pdev->dev, + BRCMF_DMA_D2H_RINGUPD_BUF_LEN, + devinfo->shared.ringupd, + devinfo->shared.ringupd_dmahandle); ++ devinfo->shared.ringupd = NULL; ++ } + } + + static int brcmf_pcie_init_scratchbuffers(struct brcmf_pciedev_info *devinfo) diff --git a/queue-5.15/wifi-mwifiex-fix-null-dereference-when-the-ap-has-ht-cap-but-no-ht-oper.patch b/queue-5.15/wifi-mwifiex-fix-null-dereference-when-the-ap-has-ht-cap-but-no-ht-oper.patch new file mode 100644 index 0000000000..4c847ab74f --- /dev/null +++ b/queue-5.15/wifi-mwifiex-fix-null-dereference-when-the-ap-has-ht-cap-but-no-ht-oper.patch @@ -0,0 +1,52 @@ +From c3d68e294cbb6a4090bb219d3dcaca85a011809b Mon Sep 17 00:00:00 2001 +From: Doruk Tan Ozturk +Date: Thu, 16 Jul 2026 12:30:42 +0200 +Subject: wifi: mwifiex: fix NULL dereference when the AP has HT-cap but no HT-oper + +From: Doruk Tan Ozturk + +commit c3d68e294cbb6a4090bb219d3dcaca85a011809b upstream. + +mwifiex_tdls_add_ht_oper() gates its follow-the-AP-bandwidth path on +bss_desc->bcn_ht_cap being present, but then dereferences a different +pointer, bss_desc->bcn_ht_oper: + + if (ISSUPP_CHANWIDTH40(priv->adapter->hw_dot_11n_dev_cap) && + bss_desc->bcn_ht_cap && + ISALLOWED_CHANWIDTH40(bss_desc->bcn_ht_oper->ht_param)) + +bcn_ht_cap and bcn_ht_oper are populated independently while parsing the +associated AP's beacon in mwifiex_update_bss_desc_with_ie(): an AP that +advertises an HT Capabilities element but no HT Operation element leaves +bcn_ht_cap non-NULL and bcn_ht_oper NULL. Setting up a TDLS link to a +peer while associated to such an AP then dereferences the NULL +bcn_ht_oper and crashes the kernel. Every other bcn_ht_oper user in the +driver NULL-checks it first. + +Guard on the pointer that is actually dereferenced. + +Found by 0sec automated security-research tooling (https://0sec.ai). + +Fixes: 396939f94084 ("mwifiex: add HT operation IE in TDLS setup confirm") +Cc: stable@vger.kernel.org +Assisted-by: 0sec:multi-model +Signed-off-by: Doruk Tan Ozturk +Reviewed-by: Francesco Dolcini +Link: https://patch.msgid.link/20260716103042.88469-1-doruk@0sec.ai +Signed-off-by: Johannes Berg +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/wireless/marvell/mwifiex/tdls.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/net/wireless/marvell/mwifiex/tdls.c ++++ b/drivers/net/wireless/marvell/mwifiex/tdls.c +@@ -215,7 +215,7 @@ mwifiex_tdls_add_ht_oper(struct mwifiex_ + + /* follow AP's channel bandwidth */ + if (ISSUPP_CHANWIDTH40(priv->adapter->hw_dot_11n_dev_cap) && +- bss_desc->bcn_ht_cap && ++ bss_desc->bcn_ht_oper && + ISALLOWED_CHANWIDTH40(bss_desc->bcn_ht_oper->ht_param)) + ht_oper->ht_param = bss_desc->bcn_ht_oper->ht_param; + diff --git a/queue-5.15/wifi-wilc1000-validate-assoc-response-length-before-subtracting-header.patch b/queue-5.15/wifi-wilc1000-validate-assoc-response-length-before-subtracting-header.patch new file mode 100644 index 0000000000..a450d256fa --- /dev/null +++ b/queue-5.15/wifi-wilc1000-validate-assoc-response-length-before-subtracting-header.patch @@ -0,0 +1,58 @@ +From 4c4c97b60a5e978121d9ee8cb0ab3916e5d6a8de Mon Sep 17 00:00:00 2001 +From: Huihui Huang +Date: Tue, 14 Jul 2026 17:17:58 +0800 +Subject: wifi: wilc1000: validate assoc response length before subtracting header + +From: Huihui Huang + +commit 4c4c97b60a5e978121d9ee8cb0ab3916e5d6a8de upstream. + +wilc_parse_assoc_resp_info() computes the trailing IE length as + + ies_len = buffer_len - sizeof(*res); + +without first checking that buffer_len is at least sizeof(struct +wilc_assoc_resp) (6 bytes). buffer_len is the length reported for a +received association response (host_int_parse_assoc_resp_info() passes +hif_drv->assoc_resp / assoc_resp_info_len straight in) and must be +validated before the driver accesses the fixed header. + +For a frame shorter than the 6-byte fixed header, the subtraction wraps. +For a four-byte response the result is truncated to a u16 ies_len of +65534, so kmemdup() then attempts to copy 65534 bytes starting at +buffer + sizeof(*res), beyond the valid association-response data +(CWE-125). A response shorter than four bytes can also cause an +out-of-bounds read of res->status_code at offsets 2 and 3. + +Reject frames too short to hold the fixed header before touching the +header or computing ies_len. Also set the connection status to a failure +on this path: the caller falls through to a +"conn_info->status == WLAN_STATUS_SUCCESS" check after the parser +returns, so leaving the status untouched could let a malformed short +response be treated as a successful association. + +Fixes: c5c77ba18ea6 ("staging: wilc1000: Add SDIO/SPI 802.11 driver") +Cc: stable@vger.kernel.org +Assisted-by: Claude:claude-opus-4-8 +Signed-off-by: Huihui Huang +Link: https://patch.msgid.link/20260714091811.3596126-1-hhhuang@smu.edu.sg +Signed-off-by: Johannes Berg +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/wireless/microchip/wilc1000/hif.c | 5 +++++ + 1 file changed, 5 insertions(+) + +--- a/drivers/net/wireless/microchip/wilc1000/hif.c ++++ b/drivers/net/wireless/microchip/wilc1000/hif.c +@@ -582,6 +582,11 @@ static s32 wilc_parse_assoc_resp_info(u8 + u16 ies_len; + struct wilc_assoc_resp *res = (struct wilc_assoc_resp *)buffer; + ++ if (buffer_len < sizeof(*res)) { ++ ret_conn_info->status = WLAN_STATUS_UNSPECIFIED_FAILURE; ++ return -EINVAL; ++ } ++ + ret_conn_info->status = le16_to_cpu(res->status_code); + if (ret_conn_info->status == WLAN_STATUS_SUCCESS) { + ies = &buffer[sizeof(*res)];