From: Greg Kroah-Hartman Date: Mon, 20 Apr 2026 14:56:06 +0000 (+0200) Subject: 6.6-stable patches X-Git-Url: http://git.ipfire.org/index.cgi?a=commitdiff_plain;h=22b9c4167a97acac3038dd282d6eeffa57ddf4a3;p=thirdparty%2Fkernel%2Fstable-queue.git 6.6-stable patches added patches: alsa-6fire-fix-use-after-free-on-disconnect.patch asoc-qcom-q6apm-move-component-registration-to-unmanaged-version.patch bcache-fix-cached_dev.sb_bio-use-after-free-and-crash.patch kvm-x86-use-scratch-field-in-mmio-fragment-to-hold-small-write-values.patch media-em28xx-fix-use-after-free-in-em28xx_v4l2_open.patch media-mediatek-vcodec-fix-use-after-free-in-encoder-release-path.patch media-vidtv-fix-nfeeds-state-corruption-on-start_streaming-failure.patch mm-blk-cgroup-fix-use-after-free-in-cgwb_release_workfn.patch mm-kasan-fix-double-free-for-kasan-pxds.patch --- diff --git a/queue-6.6/alsa-6fire-fix-use-after-free-on-disconnect.patch b/queue-6.6/alsa-6fire-fix-use-after-free-on-disconnect.patch new file mode 100644 index 0000000000..0af78f38e7 --- /dev/null +++ b/queue-6.6/alsa-6fire-fix-use-after-free-on-disconnect.patch @@ -0,0 +1,82 @@ +From b9c826916fdce6419b94eb0cd8810fdac18c2386 Mon Sep 17 00:00:00 2001 +From: Berk Cem Goksel +Date: Fri, 10 Apr 2026 08:13:41 +0300 +Subject: ALSA: 6fire: fix use-after-free on disconnect + +From: Berk Cem Goksel + +commit b9c826916fdce6419b94eb0cd8810fdac18c2386 upstream. + +In usb6fire_chip_abort(), the chip struct is allocated as the card's +private data (via snd_card_new with sizeof(struct sfire_chip)). When +snd_card_free_when_closed() is called and no file handles are open, the +card and embedded chip are freed synchronously. The subsequent +chip->card = NULL write then hits freed slab memory. + +Call trace: + usb6fire_chip_abort sound/usb/6fire/chip.c:59 [inline] + usb6fire_chip_disconnect+0x348/0x358 sound/usb/6fire/chip.c:182 + usb_unbind_interface+0x1a8/0x88c drivers/usb/core/driver.c:458 + ... + hub_event+0x1a04/0x4518 drivers/usb/core/hub.c:5953 + +Fix by moving the card lifecycle out of usb6fire_chip_abort() and into +usb6fire_chip_disconnect(). The card pointer is saved in a local +before any teardown, snd_card_disconnect() is called first to prevent +new opens, URBs are aborted while chip is still valid, and +snd_card_free_when_closed() is called last so chip is never accessed +after the card may be freed. + +Fixes: a0810c3d6dd2 ("ALSA: 6fire: Release resources at card release") +Cc: stable@vger.kernel.org +Cc: Andrey Konovalov +Signed-off-by: Berk Cem Goksel +Link: https://patch.msgid.link/20260410051341.1069716-1-berkcgoksel@gmail.com +Signed-off-by: Takashi Iwai +Signed-off-by: Greg Kroah-Hartman +--- + sound/usb/6fire/chip.c | 17 ++++++++++++----- + 1 file changed, 12 insertions(+), 5 deletions(-) + +--- a/sound/usb/6fire/chip.c ++++ b/sound/usb/6fire/chip.c +@@ -53,11 +53,6 @@ static void usb6fire_chip_abort(struct s + usb6fire_comm_abort(chip); + if (chip->control) + usb6fire_control_abort(chip); +- if (chip->card) { +- snd_card_disconnect(chip->card); +- snd_card_free_when_closed(chip->card); +- chip->card = NULL; +- } + } + } + +@@ -170,6 +165,7 @@ destroy_chip: + static void usb6fire_chip_disconnect(struct usb_interface *intf) + { + struct sfire_chip *chip; ++ struct snd_card *card; + + chip = usb_get_intfdata(intf); + if (chip) { /* if !chip, fw upload has been performed */ +@@ -180,8 +176,19 @@ static void usb6fire_chip_disconnect(str + chips[chip->regidx] = NULL; + mutex_unlock(®ister_mutex); + ++ /* ++ * Save card pointer before teardown. ++ * snd_card_free_when_closed() may free card (and ++ * the embedded chip) immediately, so it must be ++ * called last and chip must not be accessed after. ++ */ ++ card = chip->card; + chip->shutdown = true; ++ if (card) ++ snd_card_disconnect(card); + usb6fire_chip_abort(chip); ++ if (card) ++ snd_card_free_when_closed(card); + } + } + } diff --git a/queue-6.6/asoc-qcom-q6apm-move-component-registration-to-unmanaged-version.patch b/queue-6.6/asoc-qcom-q6apm-move-component-registration-to-unmanaged-version.patch new file mode 100644 index 0000000000..9b1a05cad7 --- /dev/null +++ b/queue-6.6/asoc-qcom-q6apm-move-component-registration-to-unmanaged-version.patch @@ -0,0 +1,149 @@ +From 6ec1235fc941dac6c011b30ee01d9220ff87e0cd Mon Sep 17 00:00:00 2001 +From: Srinivas Kandagatla +Date: Thu, 2 Apr 2026 08:11:06 +0000 +Subject: ASoC: qcom: q6apm: move component registration to unmanaged version + +From: Srinivas Kandagatla + +commit 6ec1235fc941dac6c011b30ee01d9220ff87e0cd upstream. + +q6apm component registers dais dynamically from ASoC toplology, which +are allocated using device managed version apis. Allocating both +component and dynamic dais using managed version could lead to incorrect +free ordering, dai will be freed while component still holding references +to it. + +Fix this issue by moving component to unmanged version so +that the dai pointers are only freeded after the component is removed. + +================================================================== +BUG: KASAN: slab-use-after-free in snd_soc_del_component_unlocked+0x3d4/0x400 [snd_soc_core] +Read of size 8 at addr ffff00084493a6e8 by task kworker/u48:0/3426 +Tainted: [W]=WARN +Hardware name: LENOVO 21N2ZC5PUS/21N2ZC5PUS, BIOS N42ET57W (1.31 ) 08/08/2024 +Workqueue: pdr_notifier_wq pdr_notifier_work [pdr_interface] +Call trace: + show_stack+0x28/0x7c (C) + dump_stack_lvl+0x60/0x80 + print_report+0x160/0x4b4 + kasan_report+0xac/0xfc + __asan_report_load8_noabort+0x20/0x34 + snd_soc_del_component_unlocked+0x3d4/0x400 [snd_soc_core] + snd_soc_unregister_component_by_driver+0x50/0x88 [snd_soc_core] + devm_component_release+0x30/0x5c [snd_soc_core] + devres_release_all+0x13c/0x210 + device_unbind_cleanup+0x20/0x190 + device_release_driver_internal+0x350/0x468 + device_release_driver+0x18/0x30 + bus_remove_device+0x1a0/0x35c + device_del+0x314/0x7f0 + device_unregister+0x20/0xbc + apr_remove_device+0x5c/0x7c [apr] + device_for_each_child+0xd8/0x160 + apr_pd_status+0x7c/0xa8 [apr] + pdr_notifier_work+0x114/0x240 [pdr_interface] + process_one_work+0x500/0xb70 + worker_thread+0x630/0xfb0 + kthread+0x370/0x6c0 + ret_from_fork+0x10/0x20 + +Allocated by task 77: + kasan_save_stack+0x40/0x68 + kasan_save_track+0x20/0x40 + kasan_save_alloc_info+0x44/0x58 + __kasan_kmalloc+0xbc/0xdc + __kmalloc_node_track_caller_noprof+0x1f4/0x620 + devm_kmalloc+0x7c/0x1c8 + snd_soc_register_dai+0x50/0x4f0 [snd_soc_core] + soc_tplg_pcm_elems_load+0x55c/0x1eb8 [snd_soc_core] + snd_soc_tplg_component_load+0x4f8/0xb60 [snd_soc_core] + audioreach_tplg_init+0x124/0x1fc [snd_q6apm] + q6apm_audio_probe+0x10/0x1c [snd_q6apm] + snd_soc_component_probe+0x5c/0x118 [snd_soc_core] + soc_probe_component+0x44c/0xaf0 [snd_soc_core] + snd_soc_bind_card+0xad0/0x2370 [snd_soc_core] + snd_soc_register_card+0x3b0/0x4c0 [snd_soc_core] + devm_snd_soc_register_card+0x50/0xc8 [snd_soc_core] + x1e80100_platform_probe+0x208/0x368 [snd_soc_x1e80100] + platform_probe+0xc0/0x188 + really_probe+0x188/0x804 + __driver_probe_device+0x158/0x358 + driver_probe_device+0x60/0x190 + __device_attach_driver+0x16c/0x2a8 + bus_for_each_drv+0x100/0x194 + __device_attach+0x174/0x380 + device_initial_probe+0x14/0x20 + bus_probe_device+0x124/0x154 + deferred_probe_work_func+0x140/0x220 + process_one_work+0x500/0xb70 + worker_thread+0x630/0xfb0 + kthread+0x370/0x6c0 + ret_from_fork+0x10/0x20 + +Freed by task 3426: + kasan_save_stack+0x40/0x68 + kasan_save_track+0x20/0x40 + __kasan_save_free_info+0x4c/0x80 + __kasan_slab_free+0x78/0xa0 + kfree+0x100/0x4a4 + devres_release_all+0x144/0x210 + device_unbind_cleanup+0x20/0x190 + device_release_driver_internal+0x350/0x468 + device_release_driver+0x18/0x30 + bus_remove_device+0x1a0/0x35c + device_del+0x314/0x7f0 + device_unregister+0x20/0xbc + apr_remove_device+0x5c/0x7c [apr] + device_for_each_child+0xd8/0x160 + apr_pd_status+0x7c/0xa8 [apr] + pdr_notifier_work+0x114/0x240 [pdr_interface] + process_one_work+0x500/0xb70 + worker_thread+0x630/0xfb0 + kthread+0x370/0x6c0 + ret_from_fork+0x10/0x20 + +Fixes: 5477518b8a0e ("ASoC: qdsp6: audioreach: add q6apm support") +Cc: Stable@vger.kernel.org +Signed-off-by: Srinivas Kandagatla +Link: https://patch.msgid.link/20260402081118.348071-2-srinivas.kandagatla@oss.qualcomm.com +Signed-off-by: Mark Brown +Signed-off-by: Greg Kroah-Hartman +--- + sound/soc/qcom/qdsp6/q6apm.c | 14 ++++++++++++-- + 1 file changed, 12 insertions(+), 2 deletions(-) + +--- a/sound/soc/qcom/qdsp6/q6apm.c ++++ b/sound/soc/qcom/qdsp6/q6apm.c +@@ -764,13 +764,22 @@ static int apm_probe(gpr_device_t *gdev) + + q6apm_get_apm_state(apm); + +- ret = devm_snd_soc_register_component(dev, &q6apm_audio_component, NULL, 0); ++ ret = snd_soc_register_component(dev, &q6apm_audio_component, NULL, 0); + if (ret < 0) { + dev_err(dev, "failed to register q6apm: %d\n", ret); + return ret; + } + +- return of_platform_populate(dev->of_node, NULL, NULL, dev); ++ ret = of_platform_populate(dev->of_node, NULL, NULL, dev); ++ if (ret) ++ snd_soc_unregister_component(dev); ++ ++ return ret; ++} ++ ++static void apm_remove(gpr_device_t *gdev) ++{ ++ snd_soc_unregister_component(&gdev->dev); + } + + struct audioreach_module *q6apm_find_module_by_mid(struct q6apm_graph *graph, uint32_t mid) +@@ -837,6 +846,7 @@ MODULE_DEVICE_TABLE(of, apm_device_id); + + static gpr_driver_t apm_driver = { + .probe = apm_probe, ++ .remove = apm_remove, + .gpr_callback = apm_callback, + .driver = { + .name = "qcom-apm", diff --git a/queue-6.6/bcache-fix-cached_dev.sb_bio-use-after-free-and-crash.patch b/queue-6.6/bcache-fix-cached_dev.sb_bio-use-after-free-and-crash.patch new file mode 100644 index 0000000000..792bb2310e --- /dev/null +++ b/queue-6.6/bcache-fix-cached_dev.sb_bio-use-after-free-and-crash.patch @@ -0,0 +1,67 @@ +From fec114a98b8735ee89c75216c45a78e28be0f128 Mon Sep 17 00:00:00 2001 +From: Mingzhe Zou +Date: Sun, 22 Mar 2026 21:41:02 +0800 +Subject: bcache: fix cached_dev.sb_bio use-after-free and crash + +From: Mingzhe Zou + +commit fec114a98b8735ee89c75216c45a78e28be0f128 upstream. + +In our production environment, we have received multiple crash reports +regarding libceph, which have caught our attention: + +``` +[6888366.280350] Call Trace: +[6888366.280452] blk_update_request+0x14e/0x370 +[6888366.280561] blk_mq_end_request+0x1a/0x130 +[6888366.280671] rbd_img_handle_request+0x1a0/0x1b0 [rbd] +[6888366.280792] rbd_obj_handle_request+0x32/0x40 [rbd] +[6888366.280903] __complete_request+0x22/0x70 [libceph] +[6888366.281032] osd_dispatch+0x15e/0xb40 [libceph] +[6888366.281164] ? inet_recvmsg+0x5b/0xd0 +[6888366.281272] ? ceph_tcp_recvmsg+0x6f/0xa0 [libceph] +[6888366.281405] ceph_con_process_message+0x79/0x140 [libceph] +[6888366.281534] ceph_con_v1_try_read+0x5d7/0xf30 [libceph] +[6888366.281661] ceph_con_workfn+0x329/0x680 [libceph] +``` + +After analyzing the coredump file, we found that the address of +dc->sb_bio has been freed. We know that cached_dev is only freed when it +is stopped. + +Since sb_bio is a part of struct cached_dev, rather than an alloc every +time. If the device is stopped while writing to the superblock, the +released address will be accessed at endio. + +This patch hopes to wait for sb_write to complete in cached_dev_free. + +It should be noted that we analyzed the cause of the problem, then tell +all details to the QWEN and adopted the modifications it made. + +Signed-off-by: Mingzhe Zou +Fixes: cafe563591446 ("bcache: A block layer cache") +Cc: stable@vger.kernel.org # 3.10+ +Signed-off-by: Coly Li +Link: https://patch.msgid.link/20260322134102.480107-1-colyli@fnnas.com +Signed-off-by: Jens Axboe +Signed-off-by: Greg Kroah-Hartman +--- + drivers/md/bcache/super.c | 7 +++++++ + 1 file changed, 7 insertions(+) + +--- a/drivers/md/bcache/super.c ++++ b/drivers/md/bcache/super.c +@@ -1367,6 +1367,13 @@ static void cached_dev_free(struct closu + + mutex_unlock(&bch_register_lock); + ++ /* ++ * Wait for any pending sb_write to complete before free. ++ * The sb_bio is embedded in struct cached_dev, so we must ++ * ensure no I/O is in progress. ++ */ ++ closure_sync(&dc->sb_write); ++ + if (dc->sb_disk) + put_page(virt_to_page(dc->sb_disk)); + diff --git a/queue-6.6/kvm-x86-use-scratch-field-in-mmio-fragment-to-hold-small-write-values.patch b/queue-6.6/kvm-x86-use-scratch-field-in-mmio-fragment-to-hold-small-write-values.patch new file mode 100644 index 0000000000..787b1c530f --- /dev/null +++ b/queue-6.6/kvm-x86-use-scratch-field-in-mmio-fragment-to-hold-small-write-values.patch @@ -0,0 +1,157 @@ +From 0b16e69d17d8c35c5c9d5918bf596c75a44655d3 Mon Sep 17 00:00:00 2001 +From: Sean Christopherson +Date: Tue, 24 Feb 2026 17:20:36 -0800 +Subject: KVM: x86: Use scratch field in MMIO fragment to hold small write values + +From: Sean Christopherson + +commit 0b16e69d17d8c35c5c9d5918bf596c75a44655d3 upstream. + +When exiting to userspace to service an emulated MMIO write, copy the +to-be-written value to a scratch field in the MMIO fragment if the size +of the data payload is 8 bytes or less, i.e. can fit in a single chunk, +instead of pointing the fragment directly at the source value. + +This fixes a class of use-after-free bugs that occur when the emulator +initiates a write using an on-stack, local variable as the source, the +write splits a page boundary, *and* both pages are MMIO pages. Because +KVM's ABI only allows for physically contiguous MMIO requests, accesses +that split MMIO pages are separated into two fragments, and are sent to +userspace one at a time. When KVM attempts to complete userspace MMIO in +response to KVM_RUN after the first fragment, KVM will detect the second +fragment and generate a second userspace exit, and reference the on-stack +variable. + +The issue is most visible if the second KVM_RUN is performed by a separate +task, in which case the stack of the initiating task can show up as truly +freed data. + + ================================================================== + BUG: KASAN: use-after-free in complete_emulated_mmio+0x305/0x420 + Read of size 1 at addr ffff888009c378d1 by task syz-executor417/984 + + CPU: 1 PID: 984 Comm: syz-executor417 Not tainted 5.10.0-182.0.0.95.h2627.eulerosv2r13.x86_64 #3 + Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.15.0-0-g2dd4b9b3f840-prebuilt.qemu.org 04/01/2014 Call Trace: + dump_stack+0xbe/0xfd + print_address_description.constprop.0+0x19/0x170 + __kasan_report.cold+0x6c/0x84 + kasan_report+0x3a/0x50 + check_memory_region+0xfd/0x1f0 + memcpy+0x20/0x60 + complete_emulated_mmio+0x305/0x420 + kvm_arch_vcpu_ioctl_run+0x63f/0x6d0 + kvm_vcpu_ioctl+0x413/0xb20 + __se_sys_ioctl+0x111/0x160 + do_syscall_64+0x30/0x40 + entry_SYSCALL_64_after_hwframe+0x67/0xd1 + RIP: 0033:0x42477d + Code: <48> 3d 01 f0 ff ff 73 01 c3 48 c7 c1 b0 ff ff ff f7 d8 64 89 01 48 + RSP: 002b:00007faa8e6890e8 EFLAGS: 00000246 ORIG_RAX: 0000000000000010 + RAX: ffffffffffffffda RBX: 00000000004d7338 RCX: 000000000042477d + RDX: 0000000000000000 RSI: 000000000000ae80 RDI: 0000000000000005 + RBP: 00000000004d7330 R08: 00007fff28d546df R09: 0000000000000000 + R10: 0000000000000000 R11: 0000000000000246 R12: 00000000004d733c + R13: 0000000000000000 R14: 000000000040a200 R15: 00007fff28d54720 + + The buggy address belongs to the page: + page:0000000029f6a428 refcount:0 mapcount:0 mapping:0000000000000000 index:0x0 pfn:0x9c37 + flags: 0xfffffc0000000(node=0|zone=1|lastcpupid=0x1fffff) + raw: 000fffffc0000000 0000000000000000 ffffea0000270dc8 0000000000000000 + raw: 0000000000000000 0000000000000000 00000000ffffffff 0000000000000000 page dumped because: kasan: bad access detected + + Memory state around the buggy address: + ffff888009c37780: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff + ffff888009c37800: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff + >ffff888009c37880: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff + ^ + ffff888009c37900: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff + ffff888009c37980: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff + ================================================================== + +The bug can also be reproduced with a targeted KVM-Unit-Test by hacking +KVM to fill a large on-stack variable in complete_emulated_mmio(), i.e. by +overwrite the data value with garbage. + +Limit the use of the scratch fields to 8-byte or smaller accesses, and to +just writes, as larger accesses and reads are not affected thanks to +implementation details in the emulator, but add a sanity check to ensure +those details don't change in the future. Specifically, KVM never uses +on-stack variables for accesses larger that 8 bytes, e.g. uses an operand +in the emulator context, and *all* reads are buffered through the mem_read +cache. + +Note! Using the scratch field for reads is not only unnecessary, it's +also extremely difficult to handle correctly. As above, KVM buffers all +reads through the mem_read cache, and heavily relies on that behavior when +re-emulating the instruction after a userspace MMIO read exit. If a read +splits a page, the first page is NOT an MMIO page, and the second page IS +an MMIO page, then the MMIO fragment needs to point at _just_ the second +chunk of the destination, i.e. its position in the mem_read cache. Taking +the "obvious" approach of copying the fragment value into the destination +when re-emulating the instruction would clobber the first chunk of the +destination, i.e. would clobber the data that was read from guest memory. + +Fixes: f78146b0f923 ("KVM: Fix page-crossing MMIO") +Suggested-by: Yashu Zhang +Reported-by: Yashu Zhang +Closes: https://lore.kernel.org/all/369eaaa2b3c1425c85e8477066391bc7@huawei.com +Cc: stable@vger.kernel.org +Tested-by: Tom Lendacky +Tested-by: Rick Edgecombe +Link: https://patch.msgid.link/20260225012049.920665-2-seanjc@google.com +Signed-off-by: Sean Christopherson +Signed-off-by: Greg Kroah-Hartman +--- + arch/x86/kvm/x86.c | 14 +++++++++++++- + include/linux/kvm_host.h | 3 ++- + 2 files changed, 15 insertions(+), 2 deletions(-) + +--- a/arch/x86/kvm/x86.c ++++ b/arch/x86/kvm/x86.c +@@ -7713,7 +7713,13 @@ static int emulator_read_write_onepage(u + WARN_ON(vcpu->mmio_nr_fragments >= KVM_MAX_MMIO_FRAGMENTS); + frag = &vcpu->mmio_fragments[vcpu->mmio_nr_fragments++]; + frag->gpa = gpa; +- frag->data = val; ++ if (write && bytes <= 8u) { ++ frag->val = 0; ++ frag->data = &frag->val; ++ memcpy(&frag->val, val, bytes); ++ } else { ++ frag->data = val; ++ } + frag->len = bytes; + return X86EMUL_CONTINUE; + } +@@ -7728,6 +7734,9 @@ static int emulator_read_write(struct x8 + gpa_t gpa; + int rc; + ++ if (WARN_ON_ONCE((bytes > 8u || !ops->write) && object_is_on_stack(val))) ++ return X86EMUL_UNHANDLEABLE; ++ + if (ops->read_write_prepare && + ops->read_write_prepare(vcpu, val, bytes)) + return X86EMUL_CONTINUE; +@@ -11136,6 +11145,9 @@ static int complete_emulated_mmio(struct + frag++; + vcpu->mmio_cur_fragment++; + } else { ++ if (WARN_ON_ONCE(frag->data == &frag->val)) ++ return -EIO; ++ + /* Go forward to the next mmio piece. */ + frag->data += len; + frag->gpa += len; +--- a/include/linux/kvm_host.h ++++ b/include/linux/kvm_host.h +@@ -316,7 +316,8 @@ static inline bool kvm_vcpu_can_poll(kti + struct kvm_mmio_fragment { + gpa_t gpa; + void *data; +- unsigned len; ++ u64 val; ++ unsigned int len; + }; + + struct kvm_vcpu { diff --git a/queue-6.6/media-em28xx-fix-use-after-free-in-em28xx_v4l2_open.patch b/queue-6.6/media-em28xx-fix-use-after-free-in-em28xx_v4l2_open.patch new file mode 100644 index 0000000000..f7b18a1d88 --- /dev/null +++ b/queue-6.6/media-em28xx-fix-use-after-free-in-em28xx_v4l2_open.patch @@ -0,0 +1,68 @@ +From a66485a934c7187ae8e36517d40615fa2e961cff Mon Sep 17 00:00:00 2001 +From: Abhishek Kumar +Date: Tue, 10 Mar 2026 22:14:37 +0530 +Subject: media: em28xx: fix use-after-free in em28xx_v4l2_open() + +From: Abhishek Kumar + +commit a66485a934c7187ae8e36517d40615fa2e961cff upstream. + +em28xx_v4l2_open() reads dev->v4l2 without holding dev->lock, +creating a race with em28xx_v4l2_init()'s error path and +em28xx_v4l2_fini(), both of which free the em28xx_v4l2 struct +and set dev->v4l2 to NULL under dev->lock. + +This race leads to two issues: + - use-after-free in v4l2_fh_init() when accessing vdev->ctrl_handler, + since the video_device is embedded in the freed em28xx_v4l2 struct. + - NULL pointer dereference in em28xx_resolution_set() when accessing + v4l2->norm, since dev->v4l2 has been set to NULL. + +Fix this by moving the mutex_lock() before the dev->v4l2 read and +adding a NULL check for dev->v4l2 under the lock. + +Reported-by: syzbot+c025d34b8eaa54c571b8@syzkaller.appspotmail.com +Closes: https://syzkaller.appspot.com/bug?extid=c025d34b8eaa54c571b8 +Fixes: 8139a4d583ab ("[media] em28xx: move v4l2 user counting fields from struct em28xx to struct v4l2") +Cc: stable@vger.kernel.org +Signed-off-by: Abhishek Kumar +Signed-off-by: Hans Verkuil +Signed-off-by: Greg Kroah-Hartman +--- + drivers/media/usb/em28xx/em28xx-video.c | 14 ++++++++++---- + 1 file changed, 10 insertions(+), 4 deletions(-) + +--- a/drivers/media/usb/em28xx/em28xx-video.c ++++ b/drivers/media/usb/em28xx/em28xx-video.c +@@ -2126,7 +2126,7 @@ static int em28xx_v4l2_open(struct file + { + struct video_device *vdev = video_devdata(filp); + struct em28xx *dev = video_drvdata(filp); +- struct em28xx_v4l2 *v4l2 = dev->v4l2; ++ struct em28xx_v4l2 *v4l2; + enum v4l2_buf_type fh_type = 0; + int ret; + +@@ -2143,13 +2143,19 @@ static int em28xx_v4l2_open(struct file + return -EINVAL; + } + ++ if (mutex_lock_interruptible(&dev->lock)) ++ return -ERESTARTSYS; ++ ++ v4l2 = dev->v4l2; ++ if (!v4l2) { ++ mutex_unlock(&dev->lock); ++ return -ENODEV; ++ } ++ + em28xx_videodbg("open dev=%s type=%s users=%d\n", + video_device_node_name(vdev), v4l2_type_names[fh_type], + v4l2->users); + +- if (mutex_lock_interruptible(&dev->lock)) +- return -ERESTARTSYS; +- + ret = v4l2_fh_open(filp); + if (ret) { + dev_err(&dev->intf->dev, diff --git a/queue-6.6/media-mediatek-vcodec-fix-use-after-free-in-encoder-release-path.patch b/queue-6.6/media-mediatek-vcodec-fix-use-after-free-in-encoder-release-path.patch new file mode 100644 index 0000000000..3a351f4368 --- /dev/null +++ b/queue-6.6/media-mediatek-vcodec-fix-use-after-free-in-encoder-release-path.patch @@ -0,0 +1,104 @@ +From 76e35091ffc722ba39b303e48bc5d08abb59dd56 Mon Sep 17 00:00:00 2001 +From: Fan Wu +Date: Wed, 4 Mar 2026 09:35:06 +0000 +Subject: media: mediatek: vcodec: fix use-after-free in encoder release path + +From: Fan Wu + +commit 76e35091ffc722ba39b303e48bc5d08abb59dd56 upstream. + +The fops_vcodec_release() function frees the context structure (ctx) +without first cancelling any pending or running work in ctx->encode_work. +This creates a race window where the workqueue handler (mtk_venc_worker) +may still be accessing the context memory after it has been freed. + +Race condition: + + CPU 0 (release path) CPU 1 (workqueue) + --------------------- ------------------ + fops_vcodec_release() + v4l2_m2m_ctx_release() + v4l2_m2m_cancel_job() + // waits for m2m job "done" + mtk_venc_worker() + v4l2_m2m_job_finish() + // m2m job "done" + // BUT worker still running! + // post-job_finish access: + other ctx dereferences + // UAF if ctx already freed + // returns (job "done") + kfree(ctx) // ctx freed + +Root cause: The v4l2_m2m_ctx_release() only waits for the m2m job +lifecycle (via TRANS_RUNNING flag), not the workqueue lifecycle. +After v4l2_m2m_job_finish() is called, the m2m framework considers +the job complete and v4l2_m2m_ctx_release() returns, but the worker +function continues executing and may still access ctx. + +The work is queued during encode operations via: + queue_work(ctx->dev->encode_workqueue, &ctx->encode_work) +The worker function accesses ctx->m2m_ctx, ctx->dev, and other ctx +fields even after calling v4l2_m2m_job_finish(). + +This vulnerability was confirmed with KASAN by running an instrumented +test module that widens the post-job_finish race window. KASAN detected: + + BUG: KASAN: slab-use-after-free in mtk_venc_worker+0x159/0x180 + Read of size 4 at addr ffff88800326e000 by task kworker/u8:0/12 + + Workqueue: mtk_vcodec_enc_wq mtk_venc_worker + + Allocated by task 47: + __kasan_kmalloc+0x7f/0x90 + fops_vcodec_open+0x85/0x1a0 + + Freed by task 47: + __kasan_slab_free+0x43/0x70 + kfree+0xee/0x3a0 + fops_vcodec_release+0xb7/0x190 + +Fix this by calling cancel_work_sync(&ctx->encode_work) before kfree(ctx). +This ensures the workqueue handler is both cancelled (if pending) and +synchronized (waits for any running handler to complete) before the +context is freed. + +Placement rationale: The fix is placed after v4l2_ctrl_handler_free() +and before list_del_init(&ctx->list). At this point, all m2m operations +are done (v4l2_m2m_ctx_release() has returned), and we need to ensure +the workqueue is synchronized before removing ctx from the list and +freeing it. + +Note: The open error path does NOT need cancel_work_sync() because +INIT_WORK() only initializes the work structure - it does not schedule +it. Work is only scheduled later during device_run() operations. + +Fixes: 0934d3759615 ("media: mediatek: vcodec: separate decoder and encoder") +Cc: stable@vger.kernel.org +Signed-off-by: Fan Wu +Reviewed-by: Nicolas Dufresne +Signed-off-by: Nicolas Dufresne +Signed-off-by: Hans Verkuil +Signed-off-by: Greg Kroah-Hartman +--- + drivers/media/platform/mediatek/vcodec/encoder/mtk_vcodec_enc_drv.c | 9 +++++++++ + 1 file changed, 9 insertions(+) + +--- a/drivers/media/platform/mediatek/vcodec/encoder/mtk_vcodec_enc_drv.c ++++ b/drivers/media/platform/mediatek/vcodec/encoder/mtk_vcodec_enc_drv.c +@@ -216,6 +216,15 @@ static int fops_vcodec_release(struct fi + v4l2_fh_exit(&ctx->fh); + v4l2_ctrl_handler_free(&ctx->ctrl_hdl); + ++ /* ++ * Cancel any pending encode work before freeing the context. ++ * Although v4l2_m2m_ctx_release() waits for m2m job completion, ++ * the workqueue handler (mtk_venc_worker) may still be accessing ++ * the context after v4l2_m2m_job_finish() returns. Without this, ++ * a use-after-free occurs when the worker accesses ctx after kfree. ++ */ ++ cancel_work_sync(&ctx->encode_work); ++ + spin_lock_irqsave(&dev->dev_ctx_lock, flags); + list_del_init(&ctx->list); + spin_unlock_irqrestore(&dev->dev_ctx_lock, flags); diff --git a/queue-6.6/media-vidtv-fix-nfeeds-state-corruption-on-start_streaming-failure.patch b/queue-6.6/media-vidtv-fix-nfeeds-state-corruption-on-start_streaming-failure.patch new file mode 100644 index 0000000000..c18c8b7f76 --- /dev/null +++ b/queue-6.6/media-vidtv-fix-nfeeds-state-corruption-on-start_streaming-failure.patch @@ -0,0 +1,62 @@ +From a0e5a598fe9a4612b852406b51153b881592aede Mon Sep 17 00:00:00 2001 +From: Ruslan Valiyev +Date: Sun, 1 Mar 2026 21:07:35 +0000 +Subject: media: vidtv: fix nfeeds state corruption on start_streaming failure + +From: Ruslan Valiyev + +commit a0e5a598fe9a4612b852406b51153b881592aede upstream. + +syzbot reported a memory leak in vidtv_psi_service_desc_init [1]. + +When vidtv_start_streaming() fails inside vidtv_start_feed(), the +nfeeds counter is left incremented even though no feed was actually +started. This corrupts the driver state: subsequent start_feed calls +see nfeeds > 1 and skip starting the mux, while stop_feed calls +eventually try to stop a non-existent stream. + +This state corruption can also lead to memory leaks, since the mux +and channel resources may be partially allocated during a failed +start_streaming but never cleaned up, as the stop path finds +dvb->streaming == false and returns early. + +Fix by decrementing nfeeds back when start_streaming fails, keeping +the counter in sync with the actual number of active feeds. + +[1] +BUG: memory leak +unreferenced object 0xffff888145b50820 (size 32): + comm "syz.0.17", pid 6068, jiffies 4294944486 + backtrace (crc 90a0c7d4): + vidtv_psi_service_desc_init+0x74/0x1b0 drivers/media/test-drivers/vidtv/vidtv_psi.c:288 + vidtv_channel_s302m_init+0xb1/0x2a0 drivers/media/test-drivers/vidtv/vidtv_channel.c:83 + vidtv_channels_init+0x1b/0x40 drivers/media/test-drivers/vidtv/vidtv_channel.c:524 + vidtv_mux_init+0x516/0xbe0 drivers/media/test-drivers/vidtv/vidtv_mux.c:518 + vidtv_start_streaming drivers/media/test-drivers/vidtv/vidtv_bridge.c:194 [inline] + vidtv_start_feed+0x33e/0x4d0 drivers/media/test-drivers/vidtv/vidtv_bridge.c:239 + +Fixes: f90cf6079bf67 ("media: vidtv: add a bridge driver") +Cc: stable@vger.kernel.org +Reported-by: syzbot+639ebc6ec75e96674741@syzkaller.appspotmail.com +Closes: https://syzkaller.appspot.com/bug?extid=639ebc6ec75e96674741 +Signed-off-by: Ruslan Valiyev +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 +@@ -237,8 +237,10 @@ static int vidtv_start_feed(struct dvb_d + + if (dvb->nfeeds == 1) { + ret = vidtv_start_streaming(dvb); +- if (ret < 0) ++ if (ret < 0) { ++ dvb->nfeeds--; + rc = ret; ++ } + } + + mutex_unlock(&dvb->feed_lock); diff --git a/queue-6.6/mm-blk-cgroup-fix-use-after-free-in-cgwb_release_workfn.patch b/queue-6.6/mm-blk-cgroup-fix-use-after-free-in-cgwb_release_workfn.patch new file mode 100644 index 0000000000..7b0c9c6a4e --- /dev/null +++ b/queue-6.6/mm-blk-cgroup-fix-use-after-free-in-cgwb_release_workfn.patch @@ -0,0 +1,87 @@ +From 8f5857be99f1ed1fa80991c72449541f634626ee Mon Sep 17 00:00:00 2001 +From: Breno Leitao +Date: Mon, 13 Apr 2026 03:09:19 -0700 +Subject: mm: blk-cgroup: fix use-after-free in cgwb_release_workfn() + +From: Breno Leitao + +commit 8f5857be99f1ed1fa80991c72449541f634626ee upstream. + +cgwb_release_workfn() calls css_put(wb->blkcg_css) and then later accesses +wb->blkcg_css again via blkcg_unpin_online(). If css_put() drops the last +reference, the blkcg can be freed asynchronously (css_free_rwork_fn -> +blkcg_css_free -> kfree) before blkcg_unpin_online() dereferences the +pointer to access blkcg->online_pin, resulting in a use-after-free: + + BUG: KASAN: slab-use-after-free in blkcg_unpin_online (./include/linux/instrumented.h:112 ./include/linux/atomic/atomic-instrumented.h:400 ./include/linux/refcount.h:389 ./include/linux/refcount.h:432 ./include/linux/refcount.h:450 block/blk-cgroup.c:1367) + Write of size 4 at addr ff11000117aa6160 by task kworker/71:1/531 + Workqueue: cgwb_release cgwb_release_workfn + Call Trace: + + blkcg_unpin_online (./include/linux/instrumented.h:112 ./include/linux/atomic/atomic-instrumented.h:400 ./include/linux/refcount.h:389 ./include/linux/refcount.h:432 ./include/linux/refcount.h:450 block/blk-cgroup.c:1367) + cgwb_release_workfn (mm/backing-dev.c:629) + process_scheduled_works (kernel/workqueue.c:3278 kernel/workqueue.c:3385) + + Freed by task 1016: + kfree (./include/linux/kasan.h:235 mm/slub.c:2689 mm/slub.c:6246 mm/slub.c:6561) + css_free_rwork_fn (kernel/cgroup/cgroup.c:5542) + process_scheduled_works (kernel/workqueue.c:3302 kernel/workqueue.c:3385) + +** Stack based on commit 66672af7a095 ("Add linux-next specific files +for 20260410") + +I am seeing this crash sporadically in Meta fleet across multiple kernel +versions. A full reproducer is available at: +https://github.com/leitao/debug/blob/main/reproducers/repro_blkcg_uaf.sh + +(The race window is narrow. To make it easily reproducible, inject a +msleep(100) between css_put() and blkcg_unpin_online() in +cgwb_release_workfn(). With that delay and a KASAN-enabled kernel, the +reproducer triggers the splat reliably in less than a second.) + +Fix this by moving blkcg_unpin_online() before css_put(), so the +cgwb's CSS reference keeps the blkcg alive while blkcg_unpin_online() +accesses it. + +Link: https://lore.kernel.org/20260413-blkcg-v1-1-35b72622d16c@debian.org +Fixes: 59b57717fff8 ("blkcg: delay blkg destruction until after writeback has finished") +Signed-off-by: Breno Leitao +Reviewed-by: Dennis Zhou +Reviewed-by: Shakeel Butt +Cc: David Hildenbrand +Cc: Jens Axboe +Cc: Johannes Weiner +Cc: Josef Bacik +Cc: JP Kobryn +Cc: Liam Howlett +Cc: Lorenzo Stoakes (Oracle) +Cc: Martin KaFai Lau +Cc: Michal Hocko +Cc: Mike Rapoport +Cc: Suren Baghdasaryan +Cc: Tejun Heo +Cc: +Signed-off-by: Andrew Morton +Signed-off-by: Greg Kroah-Hartman +--- + mm/backing-dev.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +--- a/mm/backing-dev.c ++++ b/mm/backing-dev.c +@@ -529,12 +529,13 @@ static void cgwb_release_workfn(struct w + wb_shutdown(wb); + + css_put(wb->memcg_css); +- css_put(wb->blkcg_css); +- mutex_unlock(&wb->bdi->cgwb_release_mutex); + + /* triggers blkg destruction if no online users left */ + blkcg_unpin_online(wb->blkcg_css); + ++ css_put(wb->blkcg_css); ++ mutex_unlock(&wb->bdi->cgwb_release_mutex); ++ + fprop_local_destroy_percpu(&wb->memcg_completions); + + spin_lock_irq(&cgwb_lock); diff --git a/queue-6.6/mm-kasan-fix-double-free-for-kasan-pxds.patch b/queue-6.6/mm-kasan-fix-double-free-for-kasan-pxds.patch new file mode 100644 index 0000000000..932c4608ae --- /dev/null +++ b/queue-6.6/mm-kasan-fix-double-free-for-kasan-pxds.patch @@ -0,0 +1,139 @@ +From 51d8c78be0c27ddb91bc2c0263941d8b30a47d3b Mon Sep 17 00:00:00 2001 +From: "Ritesh Harjani (IBM)" +Date: Tue, 24 Feb 2026 18:53:16 +0530 +Subject: mm/kasan: fix double free for kasan pXds + +From: Ritesh Harjani (IBM) + +commit 51d8c78be0c27ddb91bc2c0263941d8b30a47d3b upstream. + +kasan_free_pxd() assumes the page table is always struct page aligned. +But that's not always the case for all architectures. E.g. In case of +powerpc with 64K pagesize, PUD table (of size 4096) comes from slab cache +named pgtable-2^9. Hence instead of page_to_virt(pxd_page()) let's just +directly pass the start of the pxd table which is passed as the 1st +argument. + +This fixes the below double free kasan issue seen with PMEM: + +radix-mmu: Mapped 0x0000047d10000000-0x0000047f90000000 with 2.00 MiB pages +================================================================== +BUG: KASAN: double-free in kasan_remove_zero_shadow+0x9c4/0xa20 +Free of addr c0000003c38e0000 by task ndctl/2164 + +CPU: 34 UID: 0 PID: 2164 Comm: ndctl Not tainted 6.19.0-rc1-00048-gea1013c15392 #157 VOLUNTARY +Hardware name: IBM,9080-HEX POWER10 (architected) 0x800200 0xf000006 of:IBM,FW1060.00 (NH1060_012) hv:phyp pSeries +Call Trace: + dump_stack_lvl+0x88/0xc4 (unreliable) + print_report+0x214/0x63c + kasan_report_invalid_free+0xe4/0x110 + check_slab_allocation+0x100/0x150 + kmem_cache_free+0x128/0x6e0 + kasan_remove_zero_shadow+0x9c4/0xa20 + memunmap_pages+0x2b8/0x5c0 + devm_action_release+0x54/0x70 + release_nodes+0xc8/0x1a0 + devres_release_all+0xe0/0x140 + device_unbind_cleanup+0x30/0x120 + device_release_driver_internal+0x3e4/0x450 + unbind_store+0xfc/0x110 + drv_attr_store+0x78/0xb0 + sysfs_kf_write+0x114/0x140 + kernfs_fop_write_iter+0x264/0x3f0 + vfs_write+0x3bc/0x7d0 + ksys_write+0xa4/0x190 + system_call_exception+0x190/0x480 + system_call_vectored_common+0x15c/0x2ec +---- interrupt: 3000 at 0x7fff93b3d3f4 +NIP: 00007fff93b3d3f4 LR: 00007fff93b3d3f4 CTR: 0000000000000000 +REGS: c0000003f1b07e80 TRAP: 3000 Not tainted (6.19.0-rc1-00048-gea1013c15392) +MSR: 800000000280f033 CR: 48888208 XER: 00000000 +<...> +NIP [00007fff93b3d3f4] 0x7fff93b3d3f4 +LR [00007fff93b3d3f4] 0x7fff93b3d3f4 +---- interrupt: 3000 + + The buggy address belongs to the object at c0000003c38e0000 + which belongs to the cache pgtable-2^9 of size 4096 + The buggy address is located 0 bytes inside of + 4096-byte region [c0000003c38e0000, c0000003c38e1000) + + The buggy address belongs to the physical page: + page: refcount:0 mapcount:0 mapping:0000000000000000 index:0x0 pfn:0x3c38c + head: order:2 mapcount:0 entire_mapcount:0 nr_pages_mapped:0 pincount:0 + memcg:c0000003bfd63e01 + flags: 0x63ffff800000040(head|node=6|zone=0|lastcpupid=0x7ffff) + page_type: f5(slab) + raw: 063ffff800000040 c000000140058980 5deadbeef0000122 0000000000000000 + raw: 0000000000000000 0000000080200020 00000000f5000000 c0000003bfd63e01 + head: 063ffff800000040 c000000140058980 5deadbeef0000122 0000000000000000 + head: 0000000000000000 0000000080200020 00000000f5000000 c0000003bfd63e01 + head: 063ffff800000002 c00c000000f0e301 00000000ffffffff 00000000ffffffff + head: ffffffffffffffff 0000000000000000 00000000ffffffff 0000000000000004 + page dumped because: kasan: bad access detected + +[ 138.953636] [ T2164] Memory state around the buggy address: +[ 138.953643] [ T2164] c0000003c38dff00: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc +[ 138.953652] [ T2164] c0000003c38dff80: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc +[ 138.953661] [ T2164] >c0000003c38e0000: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc +[ 138.953669] [ T2164] ^ +[ 138.953675] [ T2164] c0000003c38e0080: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc +[ 138.953684] [ T2164] c0000003c38e0100: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc +[ 138.953692] [ T2164] ================================================================== +[ 138.953701] [ T2164] Disabling lock debugging due to kernel taint + +Link: https://lkml.kernel.org/r/2f9135c7866c6e0d06e960993b8a5674a9ebc7ec.1771938394.git.ritesh.list@gmail.com +Fixes: 0207df4fa1a8 ("kernel/memremap, kasan: make ZONE_DEVICE with work with KASAN") +Signed-off-by: Ritesh Harjani (IBM) +Reported-by: Venkat Rao Bagalkote +Reviewed-by: Alexander Potapenko +Cc: Andrey Konovalov +Cc: Andrey Ryabinin +Cc: Dmitry Vyukov +Cc: "Ritesh Harjani (IBM)" +Cc: Vincenzo Frascino +Cc: +Signed-off-by: Andrew Morton +Signed-off-by: Greg Kroah-Hartman +--- + mm/kasan/init.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +--- a/mm/kasan/init.c ++++ b/mm/kasan/init.c +@@ -300,7 +300,7 @@ static void kasan_free_pte(pte_t *pte_st + return; + } + +- pte_free_kernel(&init_mm, (pte_t *)page_to_virt(pmd_page(*pmd))); ++ pte_free_kernel(&init_mm, pte_start); + pmd_clear(pmd); + } + +@@ -315,7 +315,7 @@ static void kasan_free_pmd(pmd_t *pmd_st + return; + } + +- pmd_free(&init_mm, (pmd_t *)page_to_virt(pud_page(*pud))); ++ pmd_free(&init_mm, pmd_start); + pud_clear(pud); + } + +@@ -330,7 +330,7 @@ static void kasan_free_pud(pud_t *pud_st + return; + } + +- pud_free(&init_mm, (pud_t *)page_to_virt(p4d_page(*p4d))); ++ pud_free(&init_mm, pud_start); + p4d_clear(p4d); + } + +@@ -345,7 +345,7 @@ static void kasan_free_p4d(p4d_t *p4d_st + return; + } + +- p4d_free(&init_mm, (p4d_t *)page_to_virt(pgd_page(*pgd))); ++ p4d_free(&init_mm, p4d_start); + pgd_clear(pgd); + } + diff --git a/queue-6.6/series b/queue-6.6/series index 20815d197a..9861852920 100644 --- a/queue-6.6/series +++ b/queue-6.6/series @@ -112,3 +112,12 @@ blktrace-fix-__this_cpu_read-write-in-preemptible-co.patch nf_tables-nft_dynset-fix-possible-stateful-expressio.patch ice-fix-memory-leak-in-ice_set_ringparam.patch checkpatch-add-support-for-assisted-by-tag.patch +kvm-x86-use-scratch-field-in-mmio-fragment-to-hold-small-write-values.patch +asoc-qcom-q6apm-move-component-registration-to-unmanaged-version.patch +mm-kasan-fix-double-free-for-kasan-pxds.patch +mm-blk-cgroup-fix-use-after-free-in-cgwb_release_workfn.patch +media-vidtv-fix-nfeeds-state-corruption-on-start_streaming-failure.patch +media-mediatek-vcodec-fix-use-after-free-in-encoder-release-path.patch +media-em28xx-fix-use-after-free-in-em28xx_v4l2_open.patch +alsa-6fire-fix-use-after-free-on-disconnect.patch +bcache-fix-cached_dev.sb_bio-use-after-free-and-crash.patch