From: Greg Kroah-Hartman Date: Thu, 2 Jul 2026 13:36:51 +0000 (+0200) Subject: 6.18-stable patches X-Git-Tag: v5.10.260~34 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=7ccc67a67dbf643621f0bfd277e45d5b431f2152;p=thirdparty%2Fkernel%2Fstable-queue.git 6.18-stable patches added patches: block-avoid-mounting-the-bdev-pseudo-filesystem-in-userspace.patch block-invalidate-cached-plug-timestamp-after-task-switch.patch bpf-use-kvfree-for-replaced-sysctl-write-buffer.patch crypto-nx-fix-nx_crypto_ctx_exit-argument.patch err.h-use-__always_inline-on-all-error-pointer-helpers.patch exfat-fix-potential-use-after-free-in-exfat_find_dir_entry.patch f2fs-fix-incorrect-fi_no_extent-handling-in-__destroy_extent_node.patch f2fs-fix-to-round-down-start-offset-of-fallocate-for-pin-file.patch f2fs-keep-atomic-write-retry-from-zeroing-original-data.patch f2fs-pass-correct-iostat-type-for-single-node-writes.patch f2fs-validate-acl-entry-sizes-in-f2fs_acl_from_disk.patch f2fs-validate-compress-cache-inode-only-when-enabled.patch f2fs-validate-orphan-inode-entry-count.patch fbdev-fix-use-after-free-in-store_modes.patch gcov-use-atomic-counter-updates-to-fix-concurrent-access-crashes.patch keys-fix-overflow-in-keyctl_pkey_params_get_2.patch keys-pin-request_key_auth-payload-in-instantiate-paths.patch kvm-arm64-omit-tag-sync-on-stage-2-mappings-of-the-zero-page.patch kvm-replace-guest-triggerable-bug_on-in-ioeventfd-datamatch-with-get_unaligned.patch kvm-x86-mmu-ensure-hugepage-is-in-by-slot-before-checking-max-mapping-level.patch mips-dec-prevent-initial-console-buffer-from-landing-in-xkphys.patch ntb-epf-avoid-pci_iounmap-with-offset-when-peer_spad-and-config-share-bar.patch userfaultfd-ensure-mremap_userfaultfd_fail-releases-mmap_changing.patch wifi-ath11k-fix-warning-when-unbinding.patch wifi-iwlwifi-mld-fix-race-condition-in-ptp-removal.patch wifi-iwlwifi-mld-validate-sta_mask-before-ffs-in-ba-session-handlers.patch wifi-iwlwifi-mvm-fix-race-condition-in-ptp-removal.patch wifi-mt76-mt76x2u-add-support-for-elecom-wdc-867su3s.patch wifi-mt76-mt7925-don-t-disable-ap-bss-when-removing-tdls-peer.patch wifi-rtlwifi-rtl8821ae-fix-c2h-bit-location-in-rx-descriptor.patch wifi-rtw88-increase-tx-report-timeout-to-fix-race-condition.patch wifi-rtw88-usb-fix-memory-leaks-on-usb-write-failures.patch --- diff --git a/queue-6.18/block-avoid-mounting-the-bdev-pseudo-filesystem-in-userspace.patch b/queue-6.18/block-avoid-mounting-the-bdev-pseudo-filesystem-in-userspace.patch new file mode 100644 index 0000000000..490e321254 --- /dev/null +++ b/queue-6.18/block-avoid-mounting-the-bdev-pseudo-filesystem-in-userspace.patch @@ -0,0 +1,76 @@ +From f73aa66dffcb8e61e78f01b56163ec16a15d06d2 Mon Sep 17 00:00:00 2001 +From: Denis Arefev +Date: Thu, 21 May 2026 10:28:56 +0300 +Subject: block: Avoid mounting the bdev pseudo-filesystem in userspace + +From: Denis Arefev + +commit f73aa66dffcb8e61e78f01b56163ec16a15d06d2 upstream. + +The bdev pseudo-filesystem is an internal kernel filesystem with which +userspace should not interfere. Unregister it so that userspace cannot +even attempt to mount it. + +This fixes a bug [1] that occurs when attempting to access files, +because the system call move_mount() uses pointers declared in the +inode_operations structure, which for the bdev pseudo-filesystem +are always equal to 0. `inode->i_op = &empty_iops;` + +[1] + + BUG: kernel NULL pointer dereference, address: 0000000000000000 + #PF: supervisor instruction fetch in kernel mode + #PF: error_code(0x0010) - not-present page + PGD 23380067 P4D 23380067 PUD 23381067 PMD 0 + Oops: 0010 [#1] PREEMPT SMP KASAN NOPTI + CPU: 2 PID: 17125 Comm: syz-executor.0 Not tainted 6.1.155-syzkaller-00350-g84221fde2681 #0 + Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.12.0-1 04/01/2014 + RIP: 0010:0x0 + + Call Trace: + + lookup_open.isra.0+0x700/0x1180 fs/namei.c:3460 + open_last_lookups fs/namei.c:3550 [inline] + path_openat+0x953/0x2700 fs/namei.c:3780 + do_filp_open+0x1c5/0x410 fs/namei.c:3810 + do_sys_openat2+0x171/0x4d0 fs/open.c:1318 + do_sys_open fs/open.c:1334 [inline] + __do_sys_openat fs/open.c:1350 [inline] + __se_sys_openat fs/open.c:1345 [inline] + __x64_sys_openat+0x13c/0x1f0 fs/open.c:1345 + do_syscall_x64 arch/x86/entry/common.c:51 [inline] + do_syscall_64+0x35/0x80 arch/x86/entry/common.c:81 + entry_SYSCALL_64_after_hwframe+0x6e/0xd8 + +Found by Linux Verification Center (linuxtesting.org) with Syzkaller. + +Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") +Link: https://lore.kernel.org/all/20131010004732.GJ13318@ZenIV.linux.org.uk/T/# +Cc: stable@vger.kernel.org +Signed-off-by: Denis Arefev +Reviewed-by: Christoph Hellwig +Link: https://patch.msgid.link/20260521072857.5078-1-arefev@swemel.ru +Signed-off-by: Jens Axboe +Signed-off-by: Greg Kroah-Hartman +--- + block/bdev.c | 5 ----- + 1 file changed, 5 deletions(-) + +--- a/block/bdev.c ++++ b/block/bdev.c +@@ -438,15 +438,10 @@ EXPORT_SYMBOL_GPL(blockdev_superblock); + + void __init bdev_cache_init(void) + { +- int err; +- + bdev_cachep = kmem_cache_create("bdev_cache", sizeof(struct bdev_inode), + 0, (SLAB_HWCACHE_ALIGN|SLAB_RECLAIM_ACCOUNT| + SLAB_ACCOUNT|SLAB_PANIC), + init_once); +- err = register_filesystem(&bd_type); +- if (err) +- panic("Cannot register bdev pseudo-fs"); + blockdev_mnt = kern_mount(&bd_type); + if (IS_ERR(blockdev_mnt)) + panic("Cannot create bdev pseudo-fs"); diff --git a/queue-6.18/block-invalidate-cached-plug-timestamp-after-task-switch.patch b/queue-6.18/block-invalidate-cached-plug-timestamp-after-task-switch.patch new file mode 100644 index 0000000000..89a86a31e5 --- /dev/null +++ b/queue-6.18/block-invalidate-cached-plug-timestamp-after-task-switch.patch @@ -0,0 +1,109 @@ +From fad156c2af227f42ca796cbb20ddc354a6dd9932 Mon Sep 17 00:00:00 2001 +From: Usama Arif +Date: Tue, 16 Jun 2026 07:15:18 -0700 +Subject: block: invalidate cached plug timestamp after task switch + +From: Usama Arif + +commit fad156c2af227f42ca796cbb20ddc354a6dd9932 upstream. + +blk_time_get_ns() caches ktime_get_ns() in current->plug->cur_ktime +and marks the task with PF_BLOCK_TS. That cache is only valid while the +task keeps running; if the task is switched out, wall-clock time +advances and the cached value must not be reused when the task runs again. + +The existing invalidation covers explicit plug flushes through +__blk_flush_plug(), and the schedule() / rtmutex paths through +sched_update_worker(). It does not cover in-kernel preemption paths such +as preempt_schedule(), preempt_schedule_notrace(), and +preempt_schedule_irq(), which enter __schedule(SM_PREEMPT) directly and +return without calling sched_update_worker(). + +As a result, a task preempted while holding a plug with PF_BLOCK_TS set +can reuse a stale plug->cur_ktime after it is scheduled back in. blk-iocost +then consumes that stale timestamp through ioc_now(), producing stale vnow +values for throttle decisions, and through ioc_rqos_done(), inflating +on-queue time and feeding false missed-QoS samples into vrate +adjustment. + +Move the schedule-side invalidation to finish_task_switch(), which runs +for the scheduled-in task after every actual context switch regardless +of which schedule entry point was used. Keep __blk_flush_plug() as the +explicit flush/finish-plug invalidation path, and remove only the +PF_BLOCK_TS handling from sched_update_worker(). + +Fixes: 06b23f92af87 ("block: update cached timestamp post schedule/preemption") +Cc: stable@vger.kernel.org +Signed-off-by: Usama Arif +Link: https://patch.msgid.link/20260616141604.328820-3-usama.arif@linux.dev +Signed-off-by: Jens Axboe +Signed-off-by: Greg Kroah-Hartman +--- + include/linux/blkdev.h | 18 +++++++----------- + kernel/sched/core.c | 12 ++++++++---- + 2 files changed, 15 insertions(+), 15 deletions(-) + +--- a/include/linux/blkdev.h ++++ b/include/linux/blkdev.h +@@ -1187,16 +1187,12 @@ static inline void blk_flush_plug(struct + __blk_flush_plug(plug, async); + } + +-/* +- * tsk == current here +- */ +-static inline void blk_plug_invalidate_ts(struct task_struct *tsk) +-{ +- struct blk_plug *plug = tsk->plug; +- +- if (plug) +- plug->cur_ktime = 0; +- current->flags &= ~PF_BLOCK_TS; ++static __always_inline void blk_plug_invalidate_ts(void) ++{ ++ if (unlikely(current->flags & PF_BLOCK_TS)) { ++ current->plug->cur_ktime = 0; ++ current->flags &= ~PF_BLOCK_TS; ++ } + } + + int blkdev_issue_flush(struct block_device *bdev); +@@ -1222,7 +1218,7 @@ static inline void blk_flush_plug(struct + { + } + +-static inline void blk_plug_invalidate_ts(struct task_struct *tsk) ++static inline void blk_plug_invalidate_ts(void) + { + } + +--- a/kernel/sched/core.c ++++ b/kernel/sched/core.c +@@ -5206,6 +5206,12 @@ static struct rq *finish_task_switch(str + */ + kmap_local_sched_in(); + ++ /* ++ * Any cached block-layer timestamp (plug->cur_ktime) is stale now, ++ * invalidate it. ++ */ ++ blk_plug_invalidate_ts(); ++ + fire_sched_in_preempt_notifiers(current); + /* + * When switching through a kernel thread, the loop in +@@ -7000,12 +7006,10 @@ static inline void sched_submit_work(str + + static void sched_update_worker(struct task_struct *tsk) + { +- if (tsk->flags & (PF_WQ_WORKER | PF_IO_WORKER | PF_BLOCK_TS)) { +- if (tsk->flags & PF_BLOCK_TS) +- blk_plug_invalidate_ts(tsk); ++ if (tsk->flags & (PF_WQ_WORKER | PF_IO_WORKER)) { + if (tsk->flags & PF_WQ_WORKER) + wq_worker_running(tsk); +- else if (tsk->flags & PF_IO_WORKER) ++ else + io_wq_worker_running(tsk); + } + } diff --git a/queue-6.18/bpf-use-kvfree-for-replaced-sysctl-write-buffer.patch b/queue-6.18/bpf-use-kvfree-for-replaced-sysctl-write-buffer.patch new file mode 100644 index 0000000000..3281d2c16e --- /dev/null +++ b/queue-6.18/bpf-use-kvfree-for-replaced-sysctl-write-buffer.patch @@ -0,0 +1,89 @@ +From 4c21b5927d4364bfe7365f2700da5fea0ed0d004 Mon Sep 17 00:00:00 2001 +From: Dawei Feng +Date: Wed, 3 Jun 2026 18:53:16 +0800 +Subject: bpf: use kvfree() for replaced sysctl write buffer + +From: Dawei Feng + +commit 4c21b5927d4364bfe7365f2700da5fea0ed0d004 upstream. + +proc_sys_call_handler() allocates its temporary sysctl buffer with +kvzalloc() and passes it to __cgroup_bpf_run_filter_sysctl(). Since +kvzalloc() may fall back to vmalloc() for large allocations, freeing +that buffer with kfree() is wrong and can corrupt memory. + +Use kvfree() to safely handle both kmalloc and kvzalloc()/vmalloc +allocations. + +The bug was first flagged by an experimental analysis tool we are +developing for kernel memory-management bugs while analyzing +v6.13-rc1. The tool is still under development and is not yet publicly +available. Manual inspection confirms that the bug is still +present in v7.1-rc5. + +Reproduced the bug based on v7.1-rc4 in a QEMU x86_64 guest booted with +KASAN and CONFIG_FAILSLAB enabled. To exercise the replacement path, the +test tree also included the accompanying fix for the stale ret == 1 +check in __cgroup_bpf_run_filter_sysctl(). The reproducer confines +failslab injections to the proc_sys_call_handler() range, uses +stacktrace-depth=32, and injects fail-nth=1 while writing 8191 bytes to +/proc/sys/kernel/domainname from a task in the target cgroup. Under +that setup, fail-nth=1 triggered the fault: + + BUG: unable to handle page fault for address: ffffeb0200024d48 + #PF: supervisor read access in kernel mode + #PF: error_code(0x0000) - not-present page + PGD 0 P4D 0 + Oops: Oops: 0000 SMP KASAN NOPTI + CPU: 2 UID: 0 PID: 209 Comm: repro_proc_sys_ Not tainted 7.1.0-rc4-00686-g97625979a5d4 PREEMPT(lazy) + Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.15.0-1 04/01/2014 + RIP: 0010:kfree+0x6e/0x510 + ... + Call Trace: + + ? __cgroup_bpf_run_filter_sysctl+0x626/0xc30 + __cgroup_bpf_run_filter_sysctl+0x74d/0xc30 + ? __pfx___cgroup_bpf_run_filter_sysctl+0x10/0x10 + ? srso_return_thunk+0x5/0x5f + ? __kvmalloc_node_noprof+0x345/0x870 + ? proc_sys_call_handler+0x250/0x480 + ? srso_return_thunk+0x5/0x5f + proc_sys_call_handler+0x3a2/0x480 + ? __pfx_proc_sys_call_handler+0x10/0x10 + ? srso_return_thunk+0x5/0x5f + ? selinux_file_permission+0x39f/0x500 + ? srso_return_thunk+0x5/0x5f + ? lock_is_held_type+0x9e/0x120 + vfs_write+0x98e/0x1000 + ... + + +With this fix applied on top of the same test setup, rerunning the +reproducer with fail-nth=1 yields no corresponding Oops reports. + +Fixes: 4508943794ef ("proc: use kvzalloc for our kernel buffer") +Cc: stable@vger.kernel.org + +Reviewed-by: Emil Tsalapatis +Reviewed-by: Jiayuan Chen +Acked-by: Yonghong Song +Signed-off-by: Zilin Guan +Signed-off-by: Dawei Feng +Link: https://lore.kernel.org/r/20260603105317.944304-3-dawei.feng@seu.edu.cn +Signed-off-by: Alexei Starovoitov +Signed-off-by: Greg Kroah-Hartman +--- + kernel/bpf/cgroup.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/kernel/bpf/cgroup.c ++++ b/kernel/bpf/cgroup.c +@@ -1940,7 +1940,7 @@ int __cgroup_bpf_run_filter_sysctl(struc + kfree(ctx.cur_val); + + if (ret == 1 && ctx.new_updated) { +- kfree(*buf); ++ kvfree(*buf); + *buf = ctx.new_val; + *pcount = ctx.new_len; + } else { diff --git a/queue-6.18/crypto-nx-fix-nx_crypto_ctx_exit-argument.patch b/queue-6.18/crypto-nx-fix-nx_crypto_ctx_exit-argument.patch new file mode 100644 index 0000000000..fe77e0c322 --- /dev/null +++ b/queue-6.18/crypto-nx-fix-nx_crypto_ctx_exit-argument.patch @@ -0,0 +1,90 @@ +From 4e67f504ee9ded15e256b64f4fde150e917381d7 Mon Sep 17 00:00:00 2001 +From: Sam James +Date: Mon, 25 May 2026 08:56:19 +0100 +Subject: crypto: nx - fix nx_crypto_ctx_exit argument + +From: Sam James + +commit 4e67f504ee9ded15e256b64f4fde150e917381d7 upstream. + +nx_crypto_ctx_shash_exit calls nx_crypto_ctx_exit with crypto_shash_ctx(...) +but crypto_shash_ctx gives a nx_crypto_ctx *, not a crypto_tfm *. + +Fix the type in nx_crypto_ctx_exit and drop the bogus crypto_tfm_ctx +call. + +This fixes the following oops: + + BUG: Unable to handle kernel data access at 0xc0403effffffffc8 + Faulting instruction address: 0xc000000000396cb4 + Oops: Kernel access of bad area, sig: 11 [#15] + Call Trace: + nx_crypto_ctx_shash_exit+0x24/0x60 + crypto_shash_exit_tfm+0x28/0x40 + crypto_destroy_tfm+0x98/0x140 + crypto_exit_ahash_using_shash+0x20/0x40 + crypto_destroy_tfm+0x98/0x140 + hash_release+0x1c/0x30 + alg_sock_destruct+0x38/0x60 + __sk_destruct+0x48/0x2b0 + af_alg_release+0x58/0xb0 + __sock_release+0x68/0x150 + sock_close+0x20/0x40 + __fput+0x110/0x3a0 + sys_close+0x48/0xa0 + system_call_exception+0x140/0x2d0 + system_call_common+0xf4/0x258 + +.. which came from hardlink(1) opportunistically using AF_ALG. + +The same problem exists with nx_crypto_ctx_skcipher_exit getting a context +it wasn't expecting, but apparently nobody hit that for years. + +Cc: Eric Biggers +Cc: stable@vger.kernel.org +Fixes: bfd9efddf990 ("crypto: nx - convert AES-ECB to skcipher API") +Fixes: 9420e628e7d8 ("crypto: nx - Use API partial block handling") +Acked-by: Breno Leitao +Reviewed-by: Eric Biggers +Reported-by: Calvin Buckley +Tested-by: Calvin Buckley +Suggested-by: Brad Spengler +Signed-off-by: Sam James +Signed-off-by: Herbert Xu +Signed-off-by: Greg Kroah-Hartman +--- + drivers/crypto/nx/nx.c | 6 ++---- + drivers/crypto/nx/nx.h | 2 +- + 2 files changed, 3 insertions(+), 5 deletions(-) + +--- a/drivers/crypto/nx/nx.c ++++ b/drivers/crypto/nx/nx.c +@@ -714,15 +714,13 @@ int nx_crypto_ctx_aes_xcbc_init(struct c + /** + * nx_crypto_ctx_exit - destroy a crypto api context + * +- * @tfm: the crypto transform pointer for the context ++ * @nx_ctx: the crypto api context + * + * As crypto API contexts are destroyed, this exit hook is called to free the + * memory associated with it. + */ +-void nx_crypto_ctx_exit(struct crypto_tfm *tfm) ++void nx_crypto_ctx_exit(struct nx_crypto_ctx *nx_ctx) + { +- struct nx_crypto_ctx *nx_ctx = crypto_tfm_ctx(tfm); +- + kfree_sensitive(nx_ctx->kmem); + nx_ctx->csbcpb = NULL; + nx_ctx->csbcpb_aead = NULL; +--- a/drivers/crypto/nx/nx.h ++++ b/drivers/crypto/nx/nx.h +@@ -153,7 +153,7 @@ int nx_crypto_ctx_aes_ctr_init(struct cr + int nx_crypto_ctx_aes_cbc_init(struct crypto_skcipher *tfm); + int nx_crypto_ctx_aes_ecb_init(struct crypto_skcipher *tfm); + int nx_crypto_ctx_sha_init(struct crypto_shash *tfm); +-void nx_crypto_ctx_exit(struct crypto_tfm *tfm); ++void nx_crypto_ctx_exit(struct nx_crypto_ctx *nx_ctx); + void nx_crypto_ctx_skcipher_exit(struct crypto_skcipher *tfm); + void nx_crypto_ctx_aead_exit(struct crypto_aead *tfm); + void nx_crypto_ctx_shash_exit(struct crypto_shash *tfm); diff --git a/queue-6.18/err.h-use-__always_inline-on-all-error-pointer-helpers.patch b/queue-6.18/err.h-use-__always_inline-on-all-error-pointer-helpers.patch new file mode 100644 index 0000000000..2cd04f5726 --- /dev/null +++ b/queue-6.18/err.h-use-__always_inline-on-all-error-pointer-helpers.patch @@ -0,0 +1,96 @@ +From 94bfc7f3b0c7c33331ba4ff6cc64ff309dfcbce8 Mon Sep 17 00:00:00 2001 +From: Arnd Bergmann +Date: Tue, 26 May 2026 12:18:41 +0200 +Subject: err.h: use __always_inline on all error pointer helpers + +From: Arnd Bergmann + +commit 94bfc7f3b0c7c33331ba4ff6cc64ff309dfcbce8 upstream. + +While testing randconfig builds on s390, I came across a link failure with +CONFIG_DMA_SHARED_BUFFER disabled: + +ERROR: modpost: "dma_buf_put" [drivers/iommu/iommufd/iommufd.ko] undefined! + +The problem here is that IS_ERR() is not inlined and dead code elimination +fails as a consequence. + +The err.h helpers all turn into a trivial assignment of a bit mask and +should never result in a function call, so force them to always be inline. +This should generally result in better object code aside from avoiding +the link failure above. + +Link: https://lore.kernel.org/20260526101851.2495110-1-arnd@kernel.org +Signed-off-by: Arnd Bergmann +Reviewed-by: Alexander Lobakin +Reviewed-by: Nathan Chancellor +Tested-by: Tamir Duberstein +Cc: Alexander Gordeev +Cc: Andriy Shevchenko +Cc: Ansuel Smith +Cc: Bjorn Andersson +Cc: Heiko Carstens +Cc: Vasily Gorbik +Cc: +Signed-off-by: Andrew Morton +Signed-off-by: Greg Kroah-Hartman +--- + include/linux/err.h | 12 ++++++------ + 1 file changed, 6 insertions(+), 6 deletions(-) + +--- a/include/linux/err.h ++++ b/include/linux/err.h +@@ -36,7 +36,7 @@ + * + * Return: A pointer with @error encoded within its value. + */ +-static inline void * __must_check ERR_PTR(long error) ++static __always_inline void * __must_check ERR_PTR(long error) + { + return (void *) error; + } +@@ -52,7 +52,7 @@ static inline void * __must_check ERR_PT + * @ptr: An error pointer. + * Return: The error code within @ptr. + */ +-static inline long __must_check PTR_ERR(__force const void *ptr) ++static __always_inline long __must_check PTR_ERR(__force const void *ptr) + { + return (long) ptr; + } +@@ -65,7 +65,7 @@ static inline long __must_check PTR_ERR( + * @ptr: The pointer to check. + * Return: true if @ptr is an error pointer, false otherwise. + */ +-static inline bool __must_check IS_ERR(__force const void *ptr) ++static __always_inline bool __must_check IS_ERR(__force const void *ptr) + { + return IS_ERR_VALUE((unsigned long)ptr); + } +@@ -79,7 +79,7 @@ static inline bool __must_check IS_ERR(_ + * + * Like IS_ERR(), but also returns true for a null pointer. + */ +-static inline bool __must_check IS_ERR_OR_NULL(__force const void *ptr) ++static __always_inline bool __must_check IS_ERR_OR_NULL(__force const void *ptr) + { + return unlikely(!ptr) || IS_ERR_VALUE((unsigned long)ptr); + } +@@ -91,7 +91,7 @@ static inline bool __must_check IS_ERR_O + * Explicitly cast an error-valued pointer to another pointer type in such a + * way as to make it clear that's what's going on. + */ +-static inline void * __must_check ERR_CAST(__force const void *ptr) ++static __always_inline void * __must_check ERR_CAST(__force const void *ptr) + { + /* cast away the const */ + return (void *) ptr; +@@ -114,7 +114,7 @@ static inline void * __must_check ERR_CA + * + * Return: The error code within @ptr if it is an error pointer; 0 otherwise. + */ +-static inline int __must_check PTR_ERR_OR_ZERO(__force const void *ptr) ++static __always_inline int __must_check PTR_ERR_OR_ZERO(__force const void *ptr) + { + if (IS_ERR(ptr)) + return PTR_ERR(ptr); diff --git a/queue-6.18/exfat-fix-potential-use-after-free-in-exfat_find_dir_entry.patch b/queue-6.18/exfat-fix-potential-use-after-free-in-exfat_find_dir_entry.patch new file mode 100644 index 0000000000..fe0a48fcef --- /dev/null +++ b/queue-6.18/exfat-fix-potential-use-after-free-in-exfat_find_dir_entry.patch @@ -0,0 +1,90 @@ +From 3f5f8ee9917cc2b9076ac533492d8a200edcabb8 Mon Sep 17 00:00:00 2001 +From: Michael Bommarito +Date: Wed, 22 Apr 2026 11:58:44 -0400 +Subject: exfat: fix potential use-after-free in exfat_find_dir_entry() + +From: Michael Bommarito + +commit 3f5f8ee9917cc2b9076ac533492d8a200edcabb8 upstream. + +In exfat_find_dir_entry(), the buffer_head obtained from +exfat_get_dentry() is released with brelse(bh) before the fall-through +TYPE_EXTEND branch reads the directory entry through ep (which points +into bh->b_data): + + brelse(bh); + if (entry_type == TYPE_EXTEND) { + ... + len = exfat_extract_uni_name(ep, entry_uniname); + ... + } + +After brelse() drops our reference, nothing guarantees that the +underlying page backing bh->b_data remains valid for the subsequent +exfat_extract_uni_name() read. This is the same pattern fixed in +commit fc961522ddbd ("exfat: Fix potential use after free in +exfat_load_upcase_table()"). + +Move brelse(bh) so it runs after ep is no longer dereferenced on +each branch. + +Confirmed on QEMU x86_64 with CONFIG_KASAN=y + CONFIG_DEBUG_PAGEALLOC=y ++ CONFIG_PAGE_POISONING=y on linux-next, using a crafted exFAT image +(long filename with same-hash collisions forcing the TYPE_EXTEND path). +With a debug-only invalidate_bdev() inserted between brelse(bh) and +the ep read to make the stale-deref window deterministic, the +unpatched kernel faults: + + BUG: KASAN: use-after-free in exfat_find_dir_entry+0x133b/0x15a0 + BUG: unable to handle page fault for address: ffff88801a5fa0c2 + Oops: 0000 [#1] SMP DEBUG_PAGEALLOC KASAN NOPTI + RIP: 0010:exfat_find_dir_entry+0x1188/0x15a0 + +With this patch applied, the same instrumented harness completes +cleanly under the same sanitizer stack. I have not reproduced a +crash on an uninstrumented kernel under ordinary reclaim; the +instrumented A/B establishes the lifetime violation and that the +patch closes it, not an unaided triggerability claim. + +Fixes: ca06197382bd ("exfat: add directory operations") +Cc: stable@vger.kernel.org +Assisted-by: Claude:claude-opus-4-7 +Signed-off-by: Michael Bommarito +Signed-off-by: Namjae Jeon +Signed-off-by: Greg Kroah-Hartman +--- + fs/exfat/dir.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +--- a/fs/exfat/dir.c ++++ b/fs/exfat/dir.c +@@ -1081,12 +1081,12 @@ rewind: + continue; + } + +- brelse(bh); + if (entry_type == TYPE_EXTEND) { + unsigned short entry_uniname[16], unichar; + + if (step != DIRENT_STEP_NAME || + name_len >= MAX_NAME_LENGTH) { ++ brelse(bh); + step = DIRENT_STEP_FILE; + continue; + } +@@ -1097,6 +1097,7 @@ rewind: + uniname += EXFAT_FILE_NAME_LEN; + + len = exfat_extract_uni_name(ep, entry_uniname); ++ brelse(bh); + name_len += len; + + unichar = *(uniname+len); +@@ -1115,6 +1116,7 @@ rewind: + continue; + } + ++ brelse(bh); + if (entry_type & + (TYPE_CRITICAL_SEC | TYPE_BENIGN_SEC)) { + if (step == DIRENT_STEP_SECD) { diff --git a/queue-6.18/f2fs-fix-incorrect-fi_no_extent-handling-in-__destroy_extent_node.patch b/queue-6.18/f2fs-fix-incorrect-fi_no_extent-handling-in-__destroy_extent_node.patch new file mode 100644 index 0000000000..2d5aaa2371 --- /dev/null +++ b/queue-6.18/f2fs-fix-incorrect-fi_no_extent-handling-in-__destroy_extent_node.patch @@ -0,0 +1,85 @@ +From 1f70ddb28a3c71df124da5fa4040c808116d6bb9 Mon Sep 17 00:00:00 2001 +From: Yongpeng Yang +Date: Mon, 27 Apr 2026 21:10:51 +0800 +Subject: f2fs: fix incorrect FI_NO_EXTENT handling in __destroy_extent_node() + +From: Yongpeng Yang + +commit 1f70ddb28a3c71df124da5fa4040c808116d6bb9 upstream. + +When __destroy_extent_node() sets the inode flag FI_NO_EXTENT, it does +not reset the length of the largest extent to 0 and update the inode +folio. Since modifications to the extent tree are disallowed afterward, +the cached largest extent may become stale. This can trigger the +following error in xfstests generic/388: + +F2FS-fs (dm-0): sanity_check_extent_cache: inode (ino=1761) extent info [220057, 57, 6] is incorrect, run fsck to fix + +In the f2fs_drop_inode path, __destroy_extent_node() does not need to +guarantee that et->node_cnt is 0, because concurrency with writeback +is expected in this path, and writeback may update the extent cache. + +This patch reverts commit ed78aeebef05 ("f2fs: fix node_cnt race between +extent node destroy and writeback"), and remove the unnecessary zero +check of et->node_cnt. + +Fixes: ed78aeebef05 ("f2fs: fix node_cnt race between extent node destroy and writeback") +Cc: stable@vger.kernel.org +Reported-by: Chao Yu +Suggested-by: Chao Yu +Signed-off-by: Yongpeng Yang +Reviewed-by: Chao Yu +Signed-off-by: Jaegeuk Kim +Signed-off-by: Greg Kroah-Hartman +--- + fs/f2fs/extent_cache.c | 19 +++++++------------ + 1 file changed, 7 insertions(+), 12 deletions(-) + +--- a/fs/f2fs/extent_cache.c ++++ b/fs/f2fs/extent_cache.c +@@ -119,10 +119,9 @@ static bool __may_extent_tree(struct ino + if (!__init_may_extent_tree(inode, type)) + return false; + +- if (is_inode_flag_set(inode, FI_NO_EXTENT)) +- return false; +- + if (type == EX_READ) { ++ if (is_inode_flag_set(inode, FI_NO_EXTENT)) ++ return false; + if (is_inode_flag_set(inode, FI_COMPRESSED_FILE) && + !f2fs_sb_has_readonly(F2FS_I_SB(inode))) + return false; +@@ -645,14 +644,10 @@ static unsigned int __destroy_extent_nod + + while (atomic_read(&et->node_cnt)) { + write_lock(&et->lock); +- if (!is_inode_flag_set(inode, FI_NO_EXTENT)) +- set_inode_flag(inode, FI_NO_EXTENT); + node_cnt += __free_extent_tree(sbi, et, nr_shrink); + write_unlock(&et->lock); + } + +- f2fs_bug_on(sbi, atomic_read(&et->node_cnt)); +- + return node_cnt; + } + +@@ -691,12 +686,12 @@ static void __update_extent_tree_range(s + + write_lock(&et->lock); + +- if (is_inode_flag_set(inode, FI_NO_EXTENT)) { +- write_unlock(&et->lock); +- return; +- } +- + if (type == EX_READ) { ++ if (is_inode_flag_set(inode, FI_NO_EXTENT)) { ++ write_unlock(&et->lock); ++ return; ++ } ++ + prev = et->largest; + dei.len = 0; + diff --git a/queue-6.18/f2fs-fix-to-round-down-start-offset-of-fallocate-for-pin-file.patch b/queue-6.18/f2fs-fix-to-round-down-start-offset-of-fallocate-for-pin-file.patch new file mode 100644 index 0000000000..f3f62d1a6d --- /dev/null +++ b/queue-6.18/f2fs-fix-to-round-down-start-offset-of-fallocate-for-pin-file.patch @@ -0,0 +1,71 @@ +From 4275b59673eb60b02eec3997816c83f1f4b909c4 Mon Sep 17 00:00:00 2001 +From: Sunmin Jeong +Date: Mon, 22 Jun 2026 14:28:17 +0900 +Subject: f2fs: fix to round down start offset of fallocate for pin file + +From: Sunmin Jeong + +commit 4275b59673eb60b02eec3997816c83f1f4b909c4 upstream. + +Currently, the length of fallocate for pin file is section-aligned to +keep allocated sections from being selected as victims of GC. However, +for the case that the start offset of fallocate is not aligned in +section, the allocated sections can't be fully utilized. It's because a +new section is allocated by f2fs_allocate_pinning_section() after using +blks_per_sec blocks regardless of the start offset. As a result, several +unexpected dirty segments may be created, including blocks assigned to +the pinned file. + +To address this issue, let's round down the start offset of fallocate +to the length of section. + +The reproducing scenario is as below + +chunk=$(((2<<20)+4096)) # 2MB + 4KB +touch test +f2fs_io pinfile set test +f2fs_io fallocate 0 0 $chunk test +f2fs_io fallocate 0 $chunk $chunk test +f2fs_io fallocate 0 $((chunk*2)) $chunk test +f2fs_io fiemap 0 $((chunk*3)) test + +Fiemap: offset = 0 len = 12288 + logical addr. physical addr. length flags +0 0000000000000000 000000068c600000 0000000000400000 00001088 +1 0000000000400000 000000003d400000 0000000000001000 00001088 +2 0000000000401000 00000003eb200000 0000000000200000 00001088 +3 0000000000601000 00000005e4200000 0000000000001000 00001088 +4 0000000000602000 0000000605400000 0000000000200000 00001089 + +Cc: stable@vger.kernel.org +Fixes: f5a53edcf01e ("f2fs: support aligned pinned file") +Reviewed-by: Yunji Kang +Reviewed-by: Yeongjin Gil +Reviewed-by: Sungjong Seo +Signed-off-by: Sunmin Jeong +Reviewed-by: Chao Yu +Signed-off-by: Jaegeuk Kim +Signed-off-by: Greg Kroah-Hartman +--- + fs/f2fs/file.c | 9 ++++++++- + 1 file changed, 8 insertions(+), 1 deletion(-) + +--- a/fs/f2fs/file.c ++++ b/fs/f2fs/file.c +@@ -1895,8 +1895,15 @@ static int f2fs_expand_inode_data(struct + + if (f2fs_is_pinned_file(inode)) { + block_t sec_blks = CAP_BLKS_PER_SEC(sbi); +- block_t sec_len = roundup(map.m_len, sec_blks); ++ block_t sec_len; + ++ if (map.m_lblk % sec_blks) { ++ map.m_lblk = rounddown(map.m_lblk, sec_blks); ++ map.m_len = pg_end - map.m_lblk; ++ if (off_end) ++ map.m_len++; ++ } ++ sec_len = roundup(map.m_len, sec_blks); + map.m_len = sec_blks; + next_alloc: + f2fs_down_write(&sbi->pin_sem); diff --git a/queue-6.18/f2fs-keep-atomic-write-retry-from-zeroing-original-data.patch b/queue-6.18/f2fs-keep-atomic-write-retry-from-zeroing-original-data.patch new file mode 100644 index 0000000000..577989c57f --- /dev/null +++ b/queue-6.18/f2fs-keep-atomic-write-retry-from-zeroing-original-data.patch @@ -0,0 +1,76 @@ +From 6d874b65aadce56ac78f76129dbcfc2599b638f8 Mon Sep 17 00:00:00 2001 +From: Wenjie Qi +Date: Wed, 27 May 2026 20:06:28 +0800 +Subject: f2fs: keep atomic write retry from zeroing original data + +From: Wenjie Qi + +commit 6d874b65aadce56ac78f76129dbcfc2599b638f8 upstream. + +A partial atomic write reserves a block in the COW inode before reading the +original data page for the untouched bytes in that page. + +If that read fails, write_begin returns an error but leaves the COW inode +entry as NEW_ADDR. A retry of the same partial write then finds the COW +entry, treats it as existing COW data, and f2fs_write_begin() zeroes the +whole folio because blkaddr is NEW_ADDR. + +If the retry is committed, the bytes outside the retried write range are +committed as zeroes instead of preserving the original file contents. + +Only use the COW inode as the read source when it already has a real data +block. If the COW entry is still NEW_ADDR, treat it as a reservation to +reuse: keep reading the old data from the original inode and avoid +reserving or accounting the same atomic block again. + +Cc: stable@kernel.org +Fixes: 3db1de0e582c ("f2fs: change the current atomic write way") +Signed-off-by: Wenjie Qi +Reviewed-by: Chao Yu +Signed-off-by: Jaegeuk Kim +Signed-off-by: Greg Kroah-Hartman +--- + fs/f2fs/data.c | 16 +++++++++++----- + 1 file changed, 11 insertions(+), 5 deletions(-) + +--- a/fs/f2fs/data.c ++++ b/fs/f2fs/data.c +@@ -3537,6 +3537,7 @@ static int prepare_atomic_write_begin(st + pgoff_t index = folio->index; + int err = 0; + block_t ori_blk_addr = NULL_ADDR; ++ bool cow_has_reserved_block = false; + + /* If pos is beyond the end of file, reserve a new block in COW inode */ + if ((pos & PAGE_MASK) >= i_size_read(inode)) +@@ -3546,9 +3547,11 @@ static int prepare_atomic_write_begin(st + err = __find_data_block(cow_inode, index, blk_addr); + if (err) { + return err; +- } else if (*blk_addr != NULL_ADDR) { ++ } else if (__is_valid_data_blkaddr(*blk_addr)) { + *use_cow = true; + return 0; ++ } else if (*blk_addr == NEW_ADDR) { ++ cow_has_reserved_block = true; + } + + if (is_inode_flag_set(inode, FI_ATOMIC_REPLACE)) +@@ -3561,10 +3564,13 @@ static int prepare_atomic_write_begin(st + + reserve_block: + /* Finally, we should reserve a new block in COW inode for the update */ +- err = __reserve_data_block(cow_inode, index, blk_addr, node_changed); +- if (err) +- return err; +- inc_atomic_write_cnt(inode); ++ if (!cow_has_reserved_block) { ++ err = __reserve_data_block(cow_inode, index, blk_addr, ++ node_changed); ++ if (err) ++ return err; ++ inc_atomic_write_cnt(inode); ++ } + + if (ori_blk_addr != NULL_ADDR) + *blk_addr = ori_blk_addr; diff --git a/queue-6.18/f2fs-pass-correct-iostat-type-for-single-node-writes.patch b/queue-6.18/f2fs-pass-correct-iostat-type-for-single-node-writes.patch new file mode 100644 index 0000000000..4ac75c8c74 --- /dev/null +++ b/queue-6.18/f2fs-pass-correct-iostat-type-for-single-node-writes.patch @@ -0,0 +1,43 @@ +From fcb05c26c2a67953b420739b85f49386efc9b6c0 Mon Sep 17 00:00:00 2001 +From: Wenjie Qi +Date: Wed, 20 May 2026 20:07:05 +0800 +Subject: f2fs: pass correct iostat type for single node writes + +From: Wenjie Qi + +commit fcb05c26c2a67953b420739b85f49386efc9b6c0 upstream. + +f2fs_write_single_node_folio() takes an io_type argument, but still +passes FS_GC_NODE_IO to __write_node_folio() unconditionally. + +This was harmless while the helper was only used by +f2fs_move_node_folio(), whose caller passes FS_GC_NODE_IO. However, +commit fe9b8b30b971 ("f2fs: fix inline data not being written to disk +in writeback path") made f2fs_inline_data_fiemap() call the helper with +FS_NODE_IO for FIEMAP_FLAG_SYNC. + +Honor the caller supplied io_type so inline-data FIEMAP sync writeback is +accounted as normal node IO instead of GC node IO, while the GC path +continues to pass FS_GC_NODE_IO explicitly. + +Cc: stable@kernel.org +Fixes: fe9b8b30b971 ("f2fs: fix inline data not being written to disk in writeback path") +Signed-off-by: Wenjie Qi +Reviewed-by: Chao Yu +Signed-off-by: Jaegeuk Kim +Signed-off-by: Greg Kroah-Hartman +--- + fs/f2fs/node.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/fs/f2fs/node.c ++++ b/fs/f2fs/node.c +@@ -1853,7 +1853,7 @@ int f2fs_write_single_node_folio(struct + } + + if (!__write_node_folio(node_folio, false, false, NULL, +- &wbc, false, FS_GC_NODE_IO, NULL)) ++ &wbc, false, io_type, NULL)) + err = -EAGAIN; + goto release_folio; + out_folio: diff --git a/queue-6.18/f2fs-validate-acl-entry-sizes-in-f2fs_acl_from_disk.patch b/queue-6.18/f2fs-validate-acl-entry-sizes-in-f2fs_acl_from_disk.patch new file mode 100644 index 0000000000..5fea004e31 --- /dev/null +++ b/queue-6.18/f2fs-validate-acl-entry-sizes-in-f2fs_acl_from_disk.patch @@ -0,0 +1,118 @@ +From c4810ada31e80cbe4011467c4f3b1e93f94134f3 Mon Sep 17 00:00:00 2001 +From: Zhang Cen +Date: Mon, 15 Jun 2026 15:19:54 +0800 +Subject: f2fs: validate ACL entry sizes in f2fs_acl_from_disk() + +From: Zhang Cen + +commit c4810ada31e80cbe4011467c4f3b1e93f94134f3 upstream. + +f2fs_acl_count() only validates the aggregate ACL xattr length. A +malformed ACL can still place ACL_USER or ACL_GROUP in a slot that only +contains struct f2fs_acl_entry_short bytes, and f2fs_acl_from_disk() +then reads entry->e_id before verifying that a full entry fits. + +Require a short entry before reading e_tag and e_perm, and require a +full entry before reading e_id for ACL_USER and ACL_GROUP. Return +-EFSCORRUPTED from these new truncated-entry checks, while keeping the +pre-existing -EINVAL paths unchanged. + +Validation reproduced this kernel report: +KASAN slab-out-of-bounds in __f2fs_get_acl+0x6fb/0x7e0 +RIP: 0033:0x7f4b835ea7aa +The buggy address belongs to the object at ffff888114589960 which belongs +to the cache kmalloc-8 of size 8 +The buggy address is located 0 bytes to the right of allocated 8-byte +region [ffff888114589960, ffff888114589968) +Read of size 4 +Call trace: + dump_stack_lvl+0x66/0xa0 (?:?) + print_report+0xce/0x630 (?:?) + __f2fs_get_acl+0x6fb/0x7e0 (fs/f2fs/acl.c:169) + srso_alias_return_thunk+0x5/0xfbef5 (?:?) + __virt_addr_valid+0x224/0x430 (?:?) + kasan_report+0xe0/0x110 (?:?) + __f2fs_get_acl+0x5/0x7e0 (fs/f2fs/acl.c:169) + __get_acl+0x281/0x380 (?:?) + vfs_get_acl+0x10b/0x190 (?:?) + do_get_acl+0x2a/0x410 (?:?) + do_get_acl+0x9/0x410 (?:?) + do_getxattr+0xe8/0x260 (?:?) + filename_getxattr+0xd1/0x140 (?:?) + do_getname+0x2d/0x2d0 (?:?) + path_getxattrat+0x16c/0x200 (?:?) + lock_release+0xc8/0x290 (?:?) + cgroup_update_frozen+0x9d/0x320 (?:?) + lockdep_hardirqs_on_prepare+0xea/0x1a0 (?:?) + trace_hardirqs_on+0x1a/0x170 (?:?) + _raw_spin_unlock_irq+0x28/0x50 (?:?) + do_syscall_64+0x115/0x6a0 (arch/x86/entry/syscall_64.c:87) + entry_SYSCALL_64_after_hwframe+0x77/0x7f (?:?) + +Cc: stable@kernel.org +Fixes: af48b85b8cd3 ("f2fs: add xattr and acl functionalities") +Assisted-by: Codex:gpt-5.5 +Signed-off-by: Zhang Cen +Reviewed-by: Chao Yu +Signed-off-by: Jaegeuk Kim +Signed-off-by: Greg Kroah-Hartman +--- + fs/f2fs/acl.c | 18 ++++++++++++++++-- + 1 file changed, 16 insertions(+), 2 deletions(-) + +--- a/fs/f2fs/acl.c ++++ b/fs/f2fs/acl.c +@@ -46,6 +46,7 @@ static inline int f2fs_acl_count(size_t + static struct posix_acl *f2fs_acl_from_disk(const char *value, size_t size) + { + int i, count; ++ int err = -EINVAL; + struct posix_acl *acl; + struct f2fs_acl_header *hdr = (struct f2fs_acl_header *)value; + struct f2fs_acl_entry *entry = (struct f2fs_acl_entry *)(hdr + 1); +@@ -69,8 +70,11 @@ static struct posix_acl *f2fs_acl_from_d + + for (i = 0; i < count; i++) { + +- if ((char *)entry > end) ++ if (unlikely((char *)entry + ++ sizeof(struct f2fs_acl_entry_short) > end)) { ++ err = -EFSCORRUPTED; + goto fail; ++ } + + acl->a_entries[i].e_tag = le16_to_cpu(entry->e_tag); + acl->a_entries[i].e_perm = le16_to_cpu(entry->e_perm); +@@ -85,6 +89,11 @@ static struct posix_acl *f2fs_acl_from_d + break; + + case ACL_USER: ++ if (unlikely((char *)entry + ++ sizeof(struct f2fs_acl_entry) > end)) { ++ err = -EFSCORRUPTED; ++ goto fail; ++ } + acl->a_entries[i].e_uid = + make_kuid(&init_user_ns, + le32_to_cpu(entry->e_id)); +@@ -92,6 +101,11 @@ static struct posix_acl *f2fs_acl_from_d + sizeof(struct f2fs_acl_entry)); + break; + case ACL_GROUP: ++ if (unlikely((char *)entry + ++ sizeof(struct f2fs_acl_entry) > end)) { ++ err = -EFSCORRUPTED; ++ goto fail; ++ } + acl->a_entries[i].e_gid = + make_kgid(&init_user_ns, + le32_to_cpu(entry->e_id)); +@@ -107,7 +121,7 @@ static struct posix_acl *f2fs_acl_from_d + return acl; + fail: + posix_acl_release(acl); +- return ERR_PTR(-EINVAL); ++ return ERR_PTR(err); + } + + static void *f2fs_acl_to_disk(struct f2fs_sb_info *sbi, diff --git a/queue-6.18/f2fs-validate-compress-cache-inode-only-when-enabled.patch b/queue-6.18/f2fs-validate-compress-cache-inode-only-when-enabled.patch new file mode 100644 index 0000000000..ebcc0e96f8 --- /dev/null +++ b/queue-6.18/f2fs-validate-compress-cache-inode-only-when-enabled.patch @@ -0,0 +1,53 @@ +From 5073c66a96a9c23c0c2533ed4ed06e42f9021208 Mon Sep 17 00:00:00 2001 +From: Wenjie Qi +Date: Thu, 21 May 2026 11:16:18 +0800 +Subject: f2fs: validate compress cache inode only when enabled + +From: Wenjie Qi + +commit 5073c66a96a9c23c0c2533ed4ed06e42f9021208 upstream. + +F2FS_COMPRESS_INO() uses NM_I(sbi)->max_nid as the synthetic inode +number for the compressed page cache inode. That inode only exists when +the compress_cache mount option is enabled. + +When compress_cache is disabled, max_nid is outside the valid inode +range. A corrupted directory entry that points to ino == max_nid should +therefore be rejected by f2fs_check_nid_range(). However, is_meta_ino() +currently treats F2FS_COMPRESS_INO() as a meta inode unconditionally, +so f2fs_iget() bypasses do_read_inode() and its nid range check, and +instantiates a fake internal inode instead. + +Gate the compressed cache inode case on COMPRESS_CACHE, matching +f2fs_init_compress_inode(). With compress_cache disabled, ino == +max_nid now follows the normal inode path and is rejected as an +out-of-range nid. + +Cc: stable@kernel.org +Fixes: 6ce19aff0b8c ("f2fs: compress: add compress_inode to cache compressed blocks") +Signed-off-by: Wenjie Qi +Reviewed-by: Chao Yu +Signed-off-by: Jaegeuk Kim +Signed-off-by: Greg Kroah-Hartman +--- + fs/f2fs/inode.c | 9 +++++++-- + 1 file changed, 7 insertions(+), 2 deletions(-) + +--- a/fs/f2fs/inode.c ++++ b/fs/f2fs/inode.c +@@ -555,8 +555,13 @@ static int do_read_inode(struct inode *i + + static bool is_meta_ino(struct f2fs_sb_info *sbi, unsigned int ino) + { +- return ino == F2FS_NODE_INO(sbi) || ino == F2FS_META_INO(sbi) || +- ino == F2FS_COMPRESS_INO(sbi); ++ if (ino == F2FS_NODE_INO(sbi) || ino == F2FS_META_INO(sbi)) ++ return true; ++#ifdef CONFIG_F2FS_FS_COMPRESSION ++ if (test_opt(sbi, COMPRESS_CACHE) && ino == F2FS_COMPRESS_INO(sbi)) ++ return true; ++#endif ++ return false; + } + + struct inode *f2fs_iget(struct super_block *sb, unsigned long ino) diff --git a/queue-6.18/f2fs-validate-orphan-inode-entry-count.patch b/queue-6.18/f2fs-validate-orphan-inode-entry-count.patch new file mode 100644 index 0000000000..a2ec662240 --- /dev/null +++ b/queue-6.18/f2fs-validate-orphan-inode-entry-count.patch @@ -0,0 +1,75 @@ +From 846c499a65816d13f1186e3090e825e8bb8bcb8b Mon Sep 17 00:00:00 2001 +From: Wenjie Qi +Date: Tue, 26 May 2026 13:35:57 +0800 +Subject: f2fs: validate orphan inode entry count + +From: Wenjie Qi + +commit 846c499a65816d13f1186e3090e825e8bb8bcb8b upstream. + +f2fs_recover_orphan_inodes() trusts the orphan block entry_count when +replaying orphan inodes from the checkpoint pack. A corrupted entry_count +larger than F2FS_ORPHANS_PER_BLOCK makes the recovery loop read past the +ino[] array and interpret footer or following data as inode numbers. + +On a crafted image, mounting an unpatched kernel can drive orphan recovery +into f2fs_bug_on() and panic the kernel. Validate entry_count before +consuming entries so corrupted checkpoint data fails the mount with +-EFSCORRUPTED and requests fsck instead. + +Set ERROR_INCONSISTENT_ORPHAN as well, so the corruption reason can be +recorded in the superblock s_errors[] field. This gives fsck a persistent +hint even though mount-time orphan recovery failure may leave no chance to +persist SBI_NEED_FSCK through a checkpoint. + +Cc: stable@kernel.org +Fixes: 127e670abfa7 ("f2fs: add checkpoint operations") +Signed-off-by: Wenjie Qi +Reviewed-by: Chao Yu +Signed-off-by: Jaegeuk Kim +Signed-off-by: Greg Kroah-Hartman +--- + fs/f2fs/checkpoint.c | 14 +++++++++++++- + include/linux/f2fs_fs.h | 1 + + 2 files changed, 14 insertions(+), 1 deletion(-) + +--- a/fs/f2fs/checkpoint.c ++++ b/fs/f2fs/checkpoint.c +@@ -745,6 +745,7 @@ int f2fs_recover_orphan_inodes(struct f2 + for (i = 0; i < orphan_blocks; i++) { + struct folio *folio; + struct f2fs_orphan_block *orphan_blk; ++ unsigned int entry_count; + + folio = f2fs_get_meta_folio(sbi, start_blk + i); + if (IS_ERR(folio)) { +@@ -753,7 +754,18 @@ int f2fs_recover_orphan_inodes(struct f2 + } + + orphan_blk = folio_address(folio); +- for (j = 0; j < le32_to_cpu(orphan_blk->entry_count); j++) { ++ entry_count = le32_to_cpu(orphan_blk->entry_count); ++ if (entry_count > F2FS_ORPHANS_PER_BLOCK) { ++ f2fs_err(sbi, "invalid orphan inode entry count %u", ++ entry_count); ++ set_sbi_flag(sbi, SBI_NEED_FSCK); ++ f2fs_handle_error(sbi, ERROR_INCONSISTENT_ORPHAN); ++ err = -EFSCORRUPTED; ++ f2fs_folio_put(folio, true); ++ goto out; ++ } ++ ++ for (j = 0; j < entry_count; j++) { + nid_t ino = le32_to_cpu(orphan_blk->ino[j]); + + err = recover_orphan_inode(sbi, ino); +--- a/include/linux/f2fs_fs.h ++++ b/include/linux/f2fs_fs.h +@@ -104,6 +104,7 @@ enum f2fs_error { + ERROR_CORRUPTED_XATTR, + ERROR_INVALID_NODE_REFERENCE, + ERROR_INCONSISTENT_NAT, ++ ERROR_INCONSISTENT_ORPHAN, + ERROR_MAX, + }; + diff --git a/queue-6.18/fbdev-fix-use-after-free-in-store_modes.patch b/queue-6.18/fbdev-fix-use-after-free-in-store_modes.patch new file mode 100644 index 0000000000..83eacd1983 --- /dev/null +++ b/queue-6.18/fbdev-fix-use-after-free-in-store_modes.patch @@ -0,0 +1,73 @@ +From 2c1c805c65fb7dc7524e20376d6987721e73a0b1 Mon Sep 17 00:00:00 2001 +From: Ian Bridges +Date: Thu, 25 Jun 2026 23:50:48 -0500 +Subject: fbdev: fix use-after-free in store_modes() + +From: Ian Bridges + +commit 2c1c805c65fb7dc7524e20376d6987721e73a0b1 upstream. + +store_modes() replaces a framebuffer's modelist with modes from userspace. +On success it frees the old modelist with fb_destroy_modelist(). Two +fields still point into that freed list. + +One pointer is fb_display[i].mode, the mode a console is using. +fbcon_new_modelist() moves these pointers to the new list. It only does so +for consoles still mapped to the framebuffer. An unmapped console is +skipped and keeps its stale pointer. Unbinding fbcon, for example, sets +con2fb_map[i] to -1 but leaves fb_display[i].mode set. An +FBIOPUT_VSCREENINFO ioctl with FB_ACTIVATE_INV_MODE later reaches +fbcon_mode_deleted(). That function reads the stale fb_display[i].mode +through fb_mode_is_equal(). The read is a use-after-free. + +The other pointer is fb_info->mode, the current mode. It is set through +the mode sysfs attribute. store_modes() does not update fb_info->mode, so +it is left pointing into the freed list. show_mode(), the attribute's read +handler, dereferences the stale fb_info->mode through mode_string(). The +read is a use-after-free. + +Clear both pointers before freeing the list. Commit a1f305893074 ("fbcon: +Set fb_display[i]->mode to NULL when the mode is released") added the +helper fbcon_delete_modelist(). It clears every fb_display[i].mode that +points into a given list. So far it is called only from the unregister +path. Call it from store_modes() too, and set fb_info->mode to NULL. + +Reported-by: syzbot+81c7c6b52649fd07299d@syzkaller.appspotmail.com +Closes: https://syzkaller.appspot.com/bug?extid=81c7c6b52649fd07299d +Cc: stable@vger.kernel.org +Link: https://lore.kernel.org/all/ajjoDhAi2y4ArSlz@dev/ +Assisted-by: Claude:claude-opus-4-8 +Signed-off-by: Ian Bridges +Signed-off-by: Helge Deller +Signed-off-by: Greg Kroah-Hartman +--- + drivers/video/fbdev/core/fbsysfs.c | 10 +++++++++- + 1 file changed, 9 insertions(+), 1 deletion(-) + +--- a/drivers/video/fbdev/core/fbsysfs.c ++++ b/drivers/video/fbdev/core/fbsysfs.c +@@ -11,6 +11,7 @@ + #include + + #include "fb_internal.h" ++#include "fbcon.h" + + static int activate(struct fb_info *fb_info, struct fb_var_screeninfo *var) + { +@@ -111,8 +112,15 @@ static ssize_t store_modes(struct device + if (fb_new_modelist(fb_info)) { + fb_destroy_modelist(&fb_info->modelist); + list_splice(&old_list, &fb_info->modelist); +- } else ++ } else { ++ /* ++ * fb_display[i].mode and fb_info->mode both point into the old ++ * list. Clear them before it is freed. ++ */ ++ fbcon_delete_modelist(&old_list); ++ fb_info->mode = NULL; + fb_destroy_modelist(&old_list); ++ } + + unlock_fb_info(fb_info); + console_unlock(); diff --git a/queue-6.18/gcov-use-atomic-counter-updates-to-fix-concurrent-access-crashes.patch b/queue-6.18/gcov-use-atomic-counter-updates-to-fix-concurrent-access-crashes.patch new file mode 100644 index 0000000000..4a4ec9b0f4 --- /dev/null +++ b/queue-6.18/gcov-use-atomic-counter-updates-to-fix-concurrent-access-crashes.patch @@ -0,0 +1,125 @@ +From 56cb9b7d96b28a1173a510ab25354b6599ad3a33 Mon Sep 17 00:00:00 2001 +From: Konstantin Khorenko +Date: Mon, 11 May 2026 12:50:52 +0200 +Subject: gcov: use atomic counter updates to fix concurrent access crashes +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Konstantin Khorenko + +commit 56cb9b7d96b28a1173a510ab25354b6599ad3a33 upstream. + +GCC's GCOV instrumentation can merge global branch counters with loop +induction variables as an optimization. In inflate_fast(), the inner copy +loops get transformed so that the GCOV counter value is loaded multiple +times to compute the loop base address, start index, and end bound. Since +GCOV counters are global (not per-CPU), concurrent execution on different +CPUs causes the counter to change between loads, producing inconsistent +values and out-of-bounds memory writes. + +The crash manifests during IPComp (IP Payload Compression) processing when +inflate_fast() runs concurrently on multiple CPUs: + + BUG: unable to handle page fault for address: ffffd0a3c0902ffa + RIP: inflate_fast+1431 + Call Trace: + zlib_inflate + __deflate_decompress + crypto_comp_decompress + ipcomp_decompress [xfrm_ipcomp] + ipcomp_input [xfrm_ipcomp] + xfrm_input + +At the crash point, the compiler generated three loads from the same +global GCOV counter (__gcov0.inflate_fast+216) to compute base, start, and +end for an indexed loop. Another CPU modified the counter between loads, +making the values inconsistent - the write went 3.4 MB past a 65 KB +buffer. + +Add -fprofile-update=prefer-atomic to CFLAGS_GCOV at the global level in +the top-level Makefile, guarded by a try-run compile test. The test +compiles a minimal program with and without -fprofile-update=prefer-atomic +using the full KBUILD_CFLAGS, then compares undefined symbols in the +resulting object files. If prefer-atomic introduces new undefined +references (such as __atomic_fetch_add_8 on i386 or __aarch64_ldadd8_relax +on arm64 with outline-atomics), the flag is not added -- the kernel does +not link against libatomic. + +On architectures where GCC inlines 64-bit atomic counter updates (x86_64, +s390, ...) the test passes and the flag is enabled, preventing the +compiler from merging counters with loop induction variables and fixing +the observed concurrent-access crash. + +On architectures where the flag would introduce libatomic dependencies, it +is silently omitted and behaviour is no worse than before this patch. + +Move the CFLAGS_GCOV block from its original position (before the arch +Makefile include) to after the core KBUILD_CFLAGS assignments but before +the scripts/Makefile.gcc-plugins include. This placement ensures the +try-run test sees arch-specific flags (-m32, -march=, +-mno-outline-atomics) while avoiding GCC plugin flags (-fplugin=) that +would break the test on clean builds when plugin shared objects do not yet +exist. + +Link: https://lore.kernel.org/20260511105052.417187-2-khorenko@virtuozzo.com +Signed-off-by: Konstantin Khorenko +Tested-by: Arnd Bergmann +Tested-by: Peter Oberparleiter +Reviewed-by: Peter Oberparleiter +Cc: Masahiro Yamada +Cc: Miguel Ojeda +Cc: Mikhail Zaslonko +Cc: Nathan Chancellor +Cc: Pavel Tikhomirov +Cc: Thomas Weißschuh +Cc: +Signed-off-by: Andrew Morton +Signed-off-by: Greg Kroah-Hartman +--- + Makefile | 27 +++++++++++++++++++++------ + 1 file changed, 21 insertions(+), 6 deletions(-) + +--- a/Makefile ++++ b/Makefile +@@ -806,12 +806,6 @@ endif # KBUILD_EXTMOD + # Defaults to vmlinux, but the arch makefile usually adds further targets + all: vmlinux + +-CFLAGS_GCOV := -fprofile-arcs -ftest-coverage +-ifdef CONFIG_CC_IS_GCC +-CFLAGS_GCOV += -fno-tree-loop-im +-endif +-export CFLAGS_GCOV +- + # The arch Makefiles can override CC_FLAGS_FTRACE. We may also append it later. + ifdef CONFIG_FUNCTION_TRACER + CC_FLAGS_FTRACE := -pg +@@ -1082,6 +1076,27 @@ endif + # Ensure compilers do not transform certain loops into calls to wcslen() + KBUILD_CFLAGS += -fno-builtin-wcslen + ++CFLAGS_GCOV := -fprofile-arcs -ftest-coverage ++ifdef CONFIG_CC_IS_GCC ++CFLAGS_GCOV += -fno-tree-loop-im ++# Use atomic counter updates to avoid concurrent-access crashes in GCOV. ++# Only enable if -fprofile-update=prefer-atomic does not introduce new ++# undefined symbols (e.g. libatomic calls that the kernel cannot link). ++CFLAGS_GCOV += $(call try-run,\ ++ echo 'long long x; void f(void){x++;}' | \ ++ $(CC) $(KBUILD_CPPFLAGS) $(KBUILD_CFLAGS) -w -fprofile-arcs \ ++ -ftest-coverage -x c - -c -o "$$TMP.base" && \ ++ echo 'long long x; void f(void){x++;}' | \ ++ $(CC) $(KBUILD_CPPFLAGS) $(KBUILD_CFLAGS) -w -fprofile-arcs \ ++ -ftest-coverage -fprofile-update=prefer-atomic \ ++ -x c - -c -o "$$TMP" && \ ++ $(NM) "$$TMP.base" | grep ' U ' > "$$TMP.ubase" || true ; \ ++ $(NM) "$$TMP" | grep ' U ' > "$$TMP.utest" || true ; \ ++ cmp -s "$$TMP.ubase" "$$TMP.utest",\ ++ -fprofile-update=prefer-atomic) ++endif ++export CFLAGS_GCOV ++ + # change __FILE__ to the relative path to the source directory + ifdef building_out_of_srctree + KBUILD_CPPFLAGS += $(call cc-option,-fmacro-prefix-map=$(srcroot)/=) diff --git a/queue-6.18/keys-fix-overflow-in-keyctl_pkey_params_get_2.patch b/queue-6.18/keys-fix-overflow-in-keyctl_pkey_params_get_2.patch new file mode 100644 index 0000000000..5236b820bb --- /dev/null +++ b/queue-6.18/keys-fix-overflow-in-keyctl_pkey_params_get_2.patch @@ -0,0 +1,65 @@ +From cb481e59ea6cae3b7796ac1d7a22b6b24c3f3c0b Mon Sep 17 00:00:00 2001 +From: Jarkko Sakkinen +Date: Mon, 1 Jun 2026 23:11:54 +0300 +Subject: KEYS: fix overflow in keyctl_pkey_params_get_2() + +From: Jarkko Sakkinen + +commit cb481e59ea6cae3b7796ac1d7a22b6b24c3f3c0b upstream. + +The length for the internal output buffer is calculated incorrectly, which +can result overflow when a too small buffer is provided. + +Fix the bug by allocating internal output with the size of the maximum +length of the cryptographic primitive instead of caller provided size. + +Link: https://lore.kernel.org/keyrings/20260531024914.3712130-1-jarkko@kernel.org/ +Cc: stable@vger.kernel.org # v4.20+ +Fixes: 00d60fd3b932 ("KEYS: Provide keyctls to drive the new key type ops for asymmetric keys [ver #2]") +Reported-by: Alessandro Groppo +Tested-by: Alessandro Groppo +Signed-off-by: Jarkko Sakkinen +Signed-off-by: Greg Kroah-Hartman +--- + security/keys/keyctl_pkey.c | 9 ++++++++- + 1 file changed, 8 insertions(+), 1 deletion(-) + +--- a/security/keys/keyctl_pkey.c ++++ b/security/keys/keyctl_pkey.c +@@ -138,28 +138,35 @@ static int keyctl_pkey_params_get_2(cons + if (uparams.in_len > info.max_dec_size || + uparams.out_len > info.max_enc_size) + return -EINVAL; ++ ++ params->out_len = info.max_enc_size; + break; + case KEYCTL_PKEY_DECRYPT: + if (uparams.in_len > info.max_enc_size || + uparams.out_len > info.max_dec_size) + return -EINVAL; ++ ++ params->out_len = info.max_dec_size; + break; + case KEYCTL_PKEY_SIGN: + if (uparams.in_len > info.max_data_size || + uparams.out_len > info.max_sig_size) + return -EINVAL; ++ ++ params->out_len = info.max_sig_size; + break; + case KEYCTL_PKEY_VERIFY: + if (uparams.in_len > info.max_data_size || + uparams.in2_len > info.max_sig_size) + return -EINVAL; ++ ++ params->out_len = info.max_sig_size; + break; + default: + BUG(); + } + + params->in_len = uparams.in_len; +- params->out_len = uparams.out_len; /* Note: same as in2_len */ + return 0; + } + diff --git a/queue-6.18/keys-pin-request_key_auth-payload-in-instantiate-paths.patch b/queue-6.18/keys-pin-request_key_auth-payload-in-instantiate-paths.patch new file mode 100644 index 0000000000..1d0422e1d1 --- /dev/null +++ b/queue-6.18/keys-pin-request_key_auth-payload-in-instantiate-paths.patch @@ -0,0 +1,215 @@ +From fd15b457a86939c38aa12116adabd8ff686c5e51 Mon Sep 17 00:00:00 2001 +From: Shaomin Chen +Date: Wed, 10 Jun 2026 13:10:05 +0300 +Subject: keys: Pin request_key_auth payload in instantiate paths + +From: Shaomin Chen + +commit fd15b457a86939c38aa12116adabd8ff686c5e51 upstream. + +A: request_key() B: KEYCTL_INSTANTIATE_IOV +================ ========================= + +create auth key +store rka in auth key +wait for helper + get auth key + load rka from auth key + copy user payload + sleep on #PF + +helper completed +detach and free rka +destroy auth key + wake up + use rka->target_key + **USE-AFTER-FREE** + +Give request_key_auth payloads a refcount. Take a payload reference while +authkey->sem stabilizes the payload and revocation state. Hold that +reference across the instantiate and reject paths. Drop the auth key +owning reference from revoke and destroy. + +[jarkko: Replaced the first two paragraphs of text with an actual + concurrency scenario.] +Cc: stable@vger.kernel.org # v5.10+ +Fixes: b5f545c880a2 ("[PATCH] keys: Permit running process to instantiate keys") +Reported-by: Shaomin Chen +Closes: https://lore.kernel.org/r/20260519144403.436694-1-eeesssooo020@gmail.com +Signed-off-by: Shaomin Chen +Signed-off-by: Jarkko Sakkinen +Signed-off-by: Greg Kroah-Hartman +--- + include/keys/request_key_auth-type.h | 2 ++ + security/keys/internal.h | 2 ++ + security/keys/keyctl.c | 24 ++++++++++++++++++------ + security/keys/request_key_auth.c | 33 +++++++++++++++++++++++++++++++-- + 4 files changed, 53 insertions(+), 8 deletions(-) + +--- a/include/keys/request_key_auth-type.h ++++ b/include/keys/request_key_auth-type.h +@@ -9,12 +9,14 @@ + #define _KEYS_REQUEST_KEY_AUTH_TYPE_H + + #include ++#include + + /* + * Authorisation record for request_key(). + */ + struct request_key_auth { + struct rcu_head rcu; ++ refcount_t usage; + struct key *target_key; + struct key *dest_keyring; + const struct cred *cred; +--- a/security/keys/internal.h ++++ b/security/keys/internal.h +@@ -208,6 +208,8 @@ extern struct key *request_key_auth_new( + const void *callout_info, + size_t callout_len, + struct key *dest_keyring); ++struct request_key_auth *request_key_auth_get(struct key *authkey); ++void request_key_auth_put(struct request_key_auth *rka); + + extern struct key *key_get_instantiation_authkey(key_serial_t target_id); + +--- a/security/keys/keyctl.c ++++ b/security/keys/keyctl.c +@@ -1197,9 +1197,13 @@ static long keyctl_instantiate_key_commo + if (!instkey) + goto error; + +- rka = instkey->payload.data[0]; +- if (rka->target_key->serial != id) ++ rka = request_key_auth_get(instkey); ++ if (!rka) { ++ ret = -EKEYREVOKED; + goto error; ++ } ++ if (rka->target_key->serial != id) ++ goto error_put_rka; + + /* pull the payload in if one was supplied */ + payload = NULL; +@@ -1208,7 +1212,7 @@ static long keyctl_instantiate_key_commo + ret = -ENOMEM; + payload = kvmalloc(plen, GFP_KERNEL); + if (!payload) +- goto error; ++ goto error_put_rka; + + ret = -EFAULT; + if (!copy_from_iter_full(payload, plen, from)) +@@ -1234,6 +1238,8 @@ static long keyctl_instantiate_key_commo + + error2: + kvfree_sensitive(payload, plen); ++error_put_rka: ++ request_key_auth_put(rka); + error: + return ret; + } +@@ -1358,15 +1364,19 @@ long keyctl_reject_key(key_serial_t id, + if (!instkey) + goto error; + +- rka = instkey->payload.data[0]; +- if (rka->target_key->serial != id) ++ rka = request_key_auth_get(instkey); ++ if (!rka) { ++ ret = -EKEYREVOKED; + goto error; ++ } ++ if (rka->target_key->serial != id) ++ goto error_put_rka; + + /* find the destination keyring if present (which must also be + * writable) */ + ret = get_instantiation_keyring(ringid, rka, &dest_keyring); + if (ret < 0) +- goto error; ++ goto error_put_rka; + + /* instantiate the key and link it into a keyring */ + ret = key_reject_and_link(rka->target_key, timeout, error, +@@ -1379,6 +1389,8 @@ long keyctl_reject_key(key_serial_t id, + if (ret == 0) + keyctl_change_reqkey_auth(NULL); + ++error_put_rka: ++ request_key_auth_put(rka); + error: + return ret; + } +--- a/security/keys/request_key_auth.c ++++ b/security/keys/request_key_auth.c +@@ -23,6 +23,7 @@ static void request_key_auth_describe(co + static void request_key_auth_revoke(struct key *); + static void request_key_auth_destroy(struct key *); + static long request_key_auth_read(const struct key *, char *, size_t); ++static void request_key_auth_rcu_disposal(struct rcu_head *); + + /* + * The request-key authorisation key type definition. +@@ -116,6 +117,31 @@ static void free_request_key_auth(struct + } + + /* ++ * Take a reference to the request-key authorisation payload so callers can ++ * drop authkey->sem before doing operations that may sleep. ++ */ ++struct request_key_auth *request_key_auth_get(struct key *authkey) ++{ ++ struct request_key_auth *rka; ++ ++ down_read(&authkey->sem); ++ rka = dereference_key_locked(authkey); ++ if (rka && !test_bit(KEY_FLAG_REVOKED, &authkey->flags)) ++ refcount_inc(&rka->usage); ++ else ++ rka = NULL; ++ up_read(&authkey->sem); ++ ++ return rka; ++} ++ ++void request_key_auth_put(struct request_key_auth *rka) ++{ ++ if (rka && refcount_dec_and_test(&rka->usage)) ++ call_rcu(&rka->rcu, request_key_auth_rcu_disposal); ++} ++ ++/* + * Dispose of the request_key_auth record under RCU conditions + */ + static void request_key_auth_rcu_disposal(struct rcu_head *rcu) +@@ -136,8 +162,10 @@ static void request_key_auth_revoke(stru + struct request_key_auth *rka = dereference_key_locked(key); + + kenter("{%d}", key->serial); ++ if (!rka) ++ return; + rcu_assign_keypointer(key, NULL); +- call_rcu(&rka->rcu, request_key_auth_rcu_disposal); ++ request_key_auth_put(rka); + } + + /* +@@ -150,7 +178,7 @@ static void request_key_auth_destroy(str + kenter("{%d}", key->serial); + if (rka) { + rcu_assign_keypointer(key, NULL); +- call_rcu(&rka->rcu, request_key_auth_rcu_disposal); ++ request_key_auth_put(rka); + } + } + +@@ -174,6 +202,7 @@ struct key *request_key_auth_new(struct + rka = kzalloc(sizeof(*rka), GFP_KERNEL); + if (!rka) + goto error; ++ refcount_set(&rka->usage, 1); + rka->callout_info = kmemdup(callout_info, callout_len, GFP_KERNEL); + if (!rka->callout_info) + goto error_free_rka; diff --git a/queue-6.18/kvm-arm64-omit-tag-sync-on-stage-2-mappings-of-the-zero-page.patch b/queue-6.18/kvm-arm64-omit-tag-sync-on-stage-2-mappings-of-the-zero-page.patch new file mode 100644 index 0000000000..ce9546eb58 --- /dev/null +++ b/queue-6.18/kvm-arm64-omit-tag-sync-on-stage-2-mappings-of-the-zero-page.patch @@ -0,0 +1,44 @@ +From 2986a625740599fe6e7635b0586fed2a95bcd1f7 Mon Sep 17 00:00:00 2001 +From: Ard Biesheuvel +Date: Thu, 4 Jun 2026 17:11:56 +0200 +Subject: KVM: arm64: Omit tag sync on stage-2 mappings of the zero page + +From: Ard Biesheuvel + +commit 2986a625740599fe6e7635b0586fed2a95bcd1f7 upstream. + +Commit + + f620d66af316 ("arm64: mte: Do not flag the zero page as PG_mte_tagged") + +removed the PG_mte_tagged flag from the zero page, but missed a KVM code +path that may set this flag on the zero page when it is used in a +stage-2 CoW mapping of anonymous memory. + +So disregard the zero page explicitly in sanitise_mte_tags(). + +Fixes: f620d66af316 ("arm64: mte: Do not flag the zero page as PG_mte_tagged") +Cc: stable@vger.kernel.org # 5.10.x +Suggested-by: Catalin Marinas +Signed-off-by: Ard Biesheuvel +Reviewed-by: Catalin Marinas +Signed-off-by: Will Deacon +Signed-off-by: Greg Kroah-Hartman +--- + arch/arm64/kvm/mmu.c | 5 +++++ + 1 file changed, 5 insertions(+) + +--- a/arch/arm64/kvm/mmu.c ++++ b/arch/arm64/kvm/mmu.c +@@ -1444,6 +1444,11 @@ static void sanitise_mte_tags(struct kvm + if (!kvm_has_mte(kvm)) + return; + ++ if (is_zero_pfn(pfn)) { ++ WARN_ON_ONCE(nr_pages != 1); ++ return; ++ } ++ + if (folio_test_hugetlb(folio)) { + /* Hugetlb has MTE flags set on head page only */ + if (folio_try_hugetlb_mte_tagging(folio)) { diff --git a/queue-6.18/kvm-replace-guest-triggerable-bug_on-in-ioeventfd-datamatch-with-get_unaligned.patch b/queue-6.18/kvm-replace-guest-triggerable-bug_on-in-ioeventfd-datamatch-with-get_unaligned.patch new file mode 100644 index 0000000000..402a662697 --- /dev/null +++ b/queue-6.18/kvm-replace-guest-triggerable-bug_on-in-ioeventfd-datamatch-with-get_unaligned.patch @@ -0,0 +1,116 @@ +From f1edbed787ba67988ed34e0132ca128b052b6ce8 Mon Sep 17 00:00:00 2001 +From: Sean Christopherson +Date: Fri, 12 Jun 2026 15:52:41 -0700 +Subject: KVM: Replace guest-triggerable BUG_ON() in ioeventfd datamatch with get_unaligned() + +From: Sean Christopherson + +commit f1edbed787ba67988ed34e0132ca128b052b6ce8 upstream. + +Drop a BUG_ON() that has been reachable since it was first added, way back +in 2009, and instead use get_unaligned() to perform potentially-unaligned +accesses. + +For a given store, KVM x86's emulator tracks the entire value in the +destination operand, x86_emulate_ctxt.dst. If the destination is memory, +and the target splits multiple pages and/or is emulated MMIO, then KVM +handles each fragment independently. E.g. on a page split starting at page +offset 0xffc, KVM writes 4 bytes to the first page, then the remaining +bytes to the second page, using ctxt->dst as the source for both (with +appropriate offsets). + +If the destination splits a page *and* hits emulated MMIO on the second +page, then KVM will complete the write to the first page, then emulate the +MMIO access to the second page. If there is a datamatch-enabled ioeventfd +at offset 0 of the second page, then KVM will process the remainder of the +store as a potential ioeventfd signal. + +Putting it all together, if the guest emits a store that splits a page +starting at page offset N, and the second page has a datamatch-enabled +ioeventfd at offset 0, then KVM will check for datamatch using +&dst.valptr[N] as the source. Due to dst (and thus dst.valptr) being +32-byte aligned, if N is not aligned to @len, the BUG_ON() fires. + +E.g. with a 16-byte store at page offset 0xffc, to an ioeventfd of len 8, +all initial checks in ioeventfd_in_range() will succeed, and the BUG_ON() +fires due to @val being 4-byte aligned, but not 8-byte aligned. + + ------------[ cut here ]------------ + kernel BUG at arch/x86/kvm/../../../virt/kvm/eventfd.c:783! + Oops: invalid opcode: 0000 [#1] SMP + CPU: 0 UID: 1000 PID: 615 Comm: repro Not tainted 7.1.0-rc2-ff238429d1ea #365 PREEMPT + Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 0.0.0 02/06/2015 + RIP: 0010:ioeventfd_write+0x6c/0x70 [kvm] + Call Trace: + + __kvm_io_bus_write+0x85/0xb0 [kvm] + kvm_io_bus_write+0x53/0x80 [kvm] + vcpu_mmio_write+0x66/0xf0 [kvm] + emulator_read_write_onepage+0x12a/0x540 [kvm] + emulator_read_write+0x109/0x2b0 [kvm] + x86_emulate_insn+0x4f8/0xfb0 [kvm] + x86_emulate_instruction+0x181/0x790 [kvm] + kvm_mmu_page_fault+0x313/0x630 [kvm] + vmx_handle_exit+0x18a/0x590 [kvm_intel] + kvm_arch_vcpu_ioctl_run+0xc81/0x1c90 [kvm] + kvm_vcpu_ioctl+0x2d5/0x970 [kvm] + __x64_sys_ioctl+0x8a/0xd0 + do_syscall_64+0xb7/0x890 + entry_SYSCALL_64_after_hwframe+0x4b/0x53 + RIP: 0033:0x7f19c931a9bf + + Modules linked in: kvm_intel kvm irqbypass + ---[ end trace 0000000000000000 ]--- + +In a perfect world, the fix would be to simply delete the BUG_ON(), as KVM +x86 doesn't perform alignment checks on "normal" memory accesses at CPL0. +Sadly, C99 ruins all the fun; while the x86 architecture plays nice, +dereferencing an unaligned pointer directly is undefined behavior in C, +e.g. triggers splats when running with CONFIG_UBSAN_ALIGNMENT=y. + +Fixes: d34e6b175e61 ("KVM: add ioeventfd support") +Cc: stable@vger.kernel.org +Signed-off-by: Sean Christopherson +Message-ID: <20260612225241.678509-1-seanjc@google.com> +Signed-off-by: Paolo Bonzini +Signed-off-by: Greg Kroah-Hartman +--- + virt/kvm/eventfd.c | 12 +++++------- + 1 file changed, 5 insertions(+), 7 deletions(-) + +--- a/virt/kvm/eventfd.c ++++ b/virt/kvm/eventfd.c +@@ -24,6 +24,7 @@ + #include + #include + #include ++#include + #include + + #include +@@ -780,21 +781,18 @@ ioeventfd_in_range(struct _ioeventfd *p, + return true; + + /* otherwise, we have to actually compare the data */ +- +- BUG_ON(!IS_ALIGNED((unsigned long)val, len)); +- + switch (len) { + case 1: +- _val = *(u8 *)val; ++ _val = get_unaligned((u8 *)val); + break; + case 2: +- _val = *(u16 *)val; ++ _val = get_unaligned((u16 *)val); + break; + case 4: +- _val = *(u32 *)val; ++ _val = get_unaligned((u32 *)val); + break; + case 8: +- _val = *(u64 *)val; ++ _val = get_unaligned((u64 *)val); + break; + default: + return false; diff --git a/queue-6.18/kvm-x86-mmu-ensure-hugepage-is-in-by-slot-before-checking-max-mapping-level.patch b/queue-6.18/kvm-x86-mmu-ensure-hugepage-is-in-by-slot-before-checking-max-mapping-level.patch new file mode 100644 index 0000000000..9d1cd3d81b --- /dev/null +++ b/queue-6.18/kvm-x86-mmu-ensure-hugepage-is-in-by-slot-before-checking-max-mapping-level.patch @@ -0,0 +1,128 @@ +From ef057cbf825e03b63f6edf5980f96abf3c53089d Mon Sep 17 00:00:00 2001 +From: Sean Christopherson +Date: Wed, 29 Apr 2026 09:34:01 -0700 +Subject: KVM: x86/mmu: Ensure hugepage is in by slot before checking max mapping level + +From: Sean Christopherson + +commit ef057cbf825e03b63f6edf5980f96abf3c53089d upstream. + +When recovering hugepages in the shadow MMU, verify that the base gfn of +the shadow page is actually contained within the target memslot, *before* +querying the max mapping level given the shadow page's gfn. Failure to +pre-check the validity of the gfn can lead to an out-of-bounds access to +the slot's lpage_info (which typically manifests as a host #PF because the +lpage_info is vmalloc'd) if the guest creates a hugepage mapping (in its +PTEs) that extends "below" the bounds of a memslot. + +When faulting in memory for a guest, and the size of the guest mapping is +greater than KVM's (current) max mapping, then KVM will create a "direct" +shadow page (direct in that there are no gPTEs to shadow, and so the target +gfn is a direct calculation given the base gfn of the shadow page). The +hugepage recovery flow looks for such direct shadow pages, as forcing 4KiB +mappings when dirty logging generates the guest > host mapping size case. +When the 4KiB restriction is lifted, then KVM can replace the shadow page +with a hugepage. + +But if KVM originally used a smaller mapping than the guest because the +range of memory covered by the guest hugepage exceeds the bounds of a +memslot, then KVM will link a direct shadow page with a gfn that is outside +the bounds of the memslot being used to fault in memory. The rmap entry +added for the leaf mapping is correct and within bounds, but the gfn of the +leaf SPTE's parent shadow page will be out of bounds. + + BUG: unable to handle page fault for address: ffffc90000806ffc + #PF: supervisor read access in kernel mode + #PF: error_code(0x0000) - not-present page + PGD 100000067 P4D 100000067 PUD 1002a7067 PMD 10612f067 PTE 0 + Oops: Oops: 0000 [#1] SMP + CPU: 13 UID: 1000 PID: 757 Comm: mmu_stress_test Not tainted 7.1.0-rc1-48ce1e26eace-x86_pir_to_irr_comments-vm #341 PREEMPT + Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 0.0.0 02/06/2015 + RIP: 0010:kvm_mmu_max_mapping_level+0x79/0x2b0 [kvm] + Call Trace: + + kvm_mmu_recover_huge_pages+0x21b/0x320 [kvm] + kvm_set_memslot+0x1ee/0x590 [kvm] + kvm_set_memory_region.part.0+0x3a1/0x4d0 [kvm] + kvm_vm_ioctl+0x9bf/0x15d0 [kvm] + __x64_sys_ioctl+0x8a/0xd0 + do_syscall_64+0xb7/0xbb0 + entry_SYSCALL_64_after_hwframe+0x4b/0x53 + RIP: 0033:0x7f21c0f1a9bf + + +Don't bother pre-checking the bounds of the potential hugepage, i.e. don't +check that e.g. sp->gfn + KVM_PAGES_PER_HPAGE(sp->role.level + 1) is also +within the memslot, as the checks performed by kvm_mmu_max_mapping_level() +are a superset of the basic bounds checks. I.e. pre-checking the full +range would be a dubious micro-optimization. + +Fixes: 9eba50f8d7fc ("KVM: x86/mmu: Consult max mapping level when zapping collapsible SPTEs") +Cc: stable@vger.kernel.org +Cc: David Matlack +Cc: James Houghton +Cc: Alexander Bulekov +Cc: Fred Griffoul +Cc: Alexander Graf +Cc: David Woodhouse +Cc: Filippo Sironi +Cc: Ivan Orlov +Signed-off-by: Sean Christopherson +Signed-off-by: Paolo Bonzini +Signed-off-by: Greg Kroah-Hartman +--- + arch/x86/kvm/mmu/mmu.c | 18 ++++++++++++------ + include/linux/kvm_host.h | 7 ++++++- + 2 files changed, 18 insertions(+), 7 deletions(-) + +--- a/arch/x86/kvm/mmu/mmu.c ++++ b/arch/x86/kvm/mmu/mmu.c +@@ -7181,13 +7181,19 @@ restart: + sp = sptep_to_sp(sptep); + + /* +- * We cannot do huge page mapping for indirect shadow pages, +- * which are found on the last rmap (level = 1) when not using +- * tdp; such shadow pages are synced with the page table in +- * the guest, and the guest page table is using 4K page size +- * mapping if the indirect sp has level = 1. ++ * Direct shadow page can be replaced by a hugepage if the host ++ * mapping level allows it and the memslot maps all of the host ++ * hugepage. Note! If the memslot maps only part of the ++ * hugepage, sp->gfn may be below slot->base_gfn, and querying ++ * the max mapping level would cause an out-of-bounds lpage_info ++ * access. So the gfn bounds check *must* be done first. ++ * ++ * Indirect shadow pages are created when the guest page tables ++ * are using 4K pages. Since the host mapping is always ++ * constrained by the page size in the guest, indirect shadow ++ * pages are never collapsible. + */ +- if (sp->role.direct && ++ if (sp->role.direct && is_gfn_in_memslot(slot, sp->gfn) && + sp->role.level < kvm_mmu_max_mapping_level(kvm, NULL, slot, sp->gfn)) { + kvm_zap_one_rmap_spte(kvm, rmap_head, sptep); + +--- a/include/linux/kvm_host.h ++++ b/include/linux/kvm_host.h +@@ -1793,6 +1793,11 @@ void kvm_unregister_irq_ack_notifier(str + struct kvm_irq_ack_notifier *kian); + bool kvm_arch_irqfd_allowed(struct kvm *kvm, struct kvm_irqfd *args); + ++static inline bool is_gfn_in_memslot(const struct kvm_memory_slot *slot, gfn_t gfn) ++{ ++ return gfn >= slot->base_gfn && gfn < slot->base_gfn + slot->npages; ++} ++ + /* + * Returns a pointer to the memslot if it contains gfn. + * Otherwise returns NULL. +@@ -1803,7 +1808,7 @@ try_get_memslot(struct kvm_memory_slot * + if (!slot) + return NULL; + +- if (gfn >= slot->base_gfn && gfn < slot->base_gfn + slot->npages) ++ if (is_gfn_in_memslot(slot, gfn)) + return slot; + else + return NULL; diff --git a/queue-6.18/mips-dec-prevent-initial-console-buffer-from-landing-in-xkphys.patch b/queue-6.18/mips-dec-prevent-initial-console-buffer-from-landing-in-xkphys.patch new file mode 100644 index 0000000000..92f4cdabfd --- /dev/null +++ b/queue-6.18/mips-dec-prevent-initial-console-buffer-from-landing-in-xkphys.patch @@ -0,0 +1,116 @@ +From 7fb13fd35110ebe95eb053faf79d018f51144d85 Mon Sep 17 00:00:00 2001 +From: "Maciej W. Rozycki" +Date: Wed, 6 May 2026 23:42:27 +0100 +Subject: MIPS: DEC: Prevent initial console buffer from landing in XKPHYS + +From: Maciej W. Rozycki + +commit 7fb13fd35110ebe95eb053faf79d018f51144d85 upstream. + +In 64-bit configurations calling the initial console output handler from +a kernel thread other than the initial one will result in a situation +where the stack has been placed in the XKPHYS 64-bit memory segment and +consequently so has been the buffer allocated there that is used as the +argument corresponding to the `%s' output conversion specifier for the +firmware's printf() entry point. + +This 64-bit address will then be truncated by 32-bit firmware, resulting +in an attempt to access the wrong memory location, which in turn will +cause all kinds of unpredictable behaviour, such as a kernel crash: + + Console: colour dummy device 160x64 + Calibrating delay loop... 49.36 BogoMIPS (lpj=192512) + pid_max: default: 32768 minimum: 301 + CPU 0 Unable to handle kernel paging request at virtual address 000000000203bd00, epc == ffffffffbfc08364, ra == ffffffffbfc08800 + Oops[#1]: + CPU: 0 PID: 0 Comm: swapper Not tainted 5.18.0-rc2-00254-gfb649bda6f56-dirty #121 + $ 0 : 0000000000000000 0000000000000001 0000000000000023 ffffffff80684ba0 + $ 4 : 000000000203bd00 ffffffffbfc0f3b4 ffffffffffffffff 0000000000000073 + $ 8 : 0a303d7469000000 0000000000000000 0000000000000073 ffffffffbfc0f473 + $12 : 0000000000000002 0000000000000000 ffffffff80684c1c 0000000000000000 + $16 : 0000000000000000 ffffffff80596dc9 0000000000000000 ffffffffbfc09240 + $20 : ffffffff80684c40 ffffffffbfc0f400 000000000000002d 000000000000002b + $24 : ffffffffffffffbf 000000000203bd00 + $28 : ffffffff805f0000 ffffffff80684b58 0000000000000030 ffffffffbfc08800 + Hi : 0000000000000000 + Lo : 0000000000000aa8 + epc : ffffffffbfc08364 0xffffffffbfc08364 + ra : ffffffffbfc08800 0xffffffffbfc08800 + Status: 140120e2 KX SX UX KERNEL EXL + Cause : 00000008 (ExcCode 02) + BadVA : 000000000203bd00 + PrId : 00000430 (R4000SC) + Modules linked in: + Process swapper (pid: 0, threadinfo=(____ptrval____), task=(____ptrval____), tls=0000000000000000) + Stack : 0000000000000000 0000000000000000 0000000000000000 0000004d0000004d + 80684cc0806a2a40 80596dc80000004d 8061000000000000 bfc0850c80684c38 + 0000000000000000 000000000203bd00 0000000000000000 0000000000000000 + 0000000000000000 00000000bfc0f3b4 0000000000000000 0000000000000000 + 0000000000000000 0000000000000000 0000000000000000 0000000000000000 + 0000000000000000 0000000000000000 0000000000000000 0000000000000000 + 0000002500000000 0000000000000000 0000000000000000 802c1a7400000000 + 0203bd0080596dc8 0203bd4d69000000 6c61632000000018 5f746567646e6172 + 6c616320625f6d6f 5f736e5f6d6f7266 206361323778302b 303d74696e726320 + 806a0a38806b0000 806a0a38806b0000 00000000806b0000 80683c58806b0000 + ... + Call Trace: + + Code: a082ffff 03e00008 00601021 <80820000> 00001821 10400005 24840001 80820000 24630001 + + ---[ end trace 0000000000000000 ]--- + Kernel panic - not syncing: Fatal exception in interrupt + + KN04 V2.1k (PC: 0xa0026768, SP: 0x806848e8) + >> + +In this case the pointer in $4 was truncated from 0x980000000203bd00 to +0x000000000203bd00. + +This may happen when no final console driver has been enabled in the +configuration and consequently the initial console continues being used +late into bootstrap or with an upcoming change that will switch the zs +driver to use a platform device, which in turn will make the console +handover happen only after other kernel threads have already been +started. + +Fix the issue by making the buffer static and initdata, and therefore +placed in the CKSEG0 32-bit compatibility segment, observing that the +console output handler is called with the console lock held, implying +no need for this code to be reentrant. Add an assertion to verify the +buffer actually has been placed in a compatibility segment. + +Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") +Signed-off-by: Maciej W. Rozycki +Cc: stable@vger.kernel.org # v2.6.12+ +Signed-off-by: Thomas Bogendoerfer +Signed-off-by: Greg Kroah-Hartman +--- + arch/mips/dec/prom/console.c | 7 +++++-- + 1 file changed, 5 insertions(+), 2 deletions(-) + +--- a/arch/mips/dec/prom/console.c ++++ b/arch/mips/dec/prom/console.c +@@ -2,8 +2,9 @@ + /* + * DECstation PROM-based early console support. + * +- * Copyright (C) 2004, 2007 Maciej W. Rozycki ++ * Copyright (C) 2004, 2007, 2026 Maciej W. Rozycki + */ ++#include + #include + #include + #include +@@ -14,9 +15,11 @@ + static void __init prom_console_write(struct console *con, const char *s, + unsigned int c) + { +- char buf[81]; ++ static char buf[81] __initdata = { 0 }; + unsigned int chunk = sizeof(buf) - 1; + ++ BUG_ON((long)buf != (int)(long)buf); ++ + while (c > 0) { + if (chunk > c) + chunk = c; diff --git a/queue-6.18/ntb-epf-avoid-pci_iounmap-with-offset-when-peer_spad-and-config-share-bar.patch b/queue-6.18/ntb-epf-avoid-pci_iounmap-with-offset-when-peer_spad-and-config-share-bar.patch new file mode 100644 index 0000000000..cf6df664f9 --- /dev/null +++ b/queue-6.18/ntb-epf-avoid-pci_iounmap-with-offset-when-peer_spad-and-config-share-bar.patch @@ -0,0 +1,56 @@ +From d876153680e3d721d385e554def919bce3d18c74 Mon Sep 17 00:00:00 2001 +From: Koichiro Den +Date: Wed, 4 Mar 2026 11:05:27 +0900 +Subject: NTB: epf: Avoid pci_iounmap() with offset when PEER_SPAD and CONFIG share BAR + +From: Koichiro Den + +commit d876153680e3d721d385e554def919bce3d18c74 upstream. + +When BAR_PEER_SPAD and BAR_CONFIG share one PCI BAR, the module teardown +path ends up calling pci_iounmap() on the same iomem with some offset, +which is unnecessary and triggers a kernel warning like the following: + + Trying to vunmap() nonexistent vm area (0000000069a5ffe8) + WARNING: mm/vmalloc.c:3470 at vunmap+0x58/0x68, CPU#5: modprobe/2937 + [...] + Call trace: + vunmap+0x58/0x68 (P) + iounmap+0x34/0x48 + pci_iounmap+0x2c/0x40 + ntb_epf_pci_remove+0x44/0x80 [ntb_hw_epf] + pci_device_remove+0x48/0xf8 + device_remove+0x50/0x88 + device_release_driver_internal+0x1c8/0x228 + driver_detach+0x50/0xb0 + bus_remove_driver+0x74/0x100 + driver_unregister+0x34/0x68 + pci_unregister_driver+0x34/0xa0 + ntb_epf_pci_driver_exit+0x14/0xfe0 [ntb_hw_epf] + [...] + +Fix it by unmapping only when PEER_SPAD and CONFIG use difference bars. + +Cc: stable@vger.kernel.org +Fixes: e75d5ae8ab88 ("NTB: epf: Allow more flexibility in the memory BAR map method") +Reviewed-by: Frank Li +Signed-off-by: Koichiro Den +Reviewed-by: Dave Jiang +Signed-off-by: Jon Mason +Signed-off-by: Greg Kroah-Hartman +--- + drivers/ntb/hw/epf/ntb_hw_epf.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/drivers/ntb/hw/epf/ntb_hw_epf.c ++++ b/drivers/ntb/hw/epf/ntb_hw_epf.c +@@ -646,7 +646,8 @@ static void ntb_epf_deinit_pci(struct nt + struct pci_dev *pdev = ndev->ntb.pdev; + + pci_iounmap(pdev, ndev->ctrl_reg); +- pci_iounmap(pdev, ndev->peer_spad_reg); ++ if (ndev->barno_map[BAR_PEER_SPAD] != ndev->barno_map[BAR_CONFIG]) ++ pci_iounmap(pdev, ndev->peer_spad_reg); + pci_iounmap(pdev, ndev->db_reg); + + pci_release_regions(pdev); diff --git a/queue-6.18/series b/queue-6.18/series index c40ff68ed4..611428ea2a 100644 --- a/queue-6.18/series +++ b/queue-6.18/series @@ -39,3 +39,35 @@ net-skmsg-preserve-sg.copy-across-sg-transforms.patch net-ip_gre-require-cap_net_admin-in-the-device-netns-for-changelink.patch apparmor-mediate-the-implicit-connect-of-tcp-fast-open-sendmsg.patch apparmor-fix-use-after-free-in-rawdata-dedup-loop.patch +ntb-epf-avoid-pci_iounmap-with-offset-when-peer_spad-and-config-share-bar.patch +fbdev-fix-use-after-free-in-store_modes.patch +block-invalidate-cached-plug-timestamp-after-task-switch.patch +kvm-arm64-omit-tag-sync-on-stage-2-mappings-of-the-zero-page.patch +err.h-use-__always_inline-on-all-error-pointer-helpers.patch +gcov-use-atomic-counter-updates-to-fix-concurrent-access-crashes.patch +keys-fix-overflow-in-keyctl_pkey_params_get_2.patch +keys-pin-request_key_auth-payload-in-instantiate-paths.patch +userfaultfd-ensure-mremap_userfaultfd_fail-releases-mmap_changing.patch +wifi-mt76-mt76x2u-add-support-for-elecom-wdc-867su3s.patch +wifi-mt76-mt7925-don-t-disable-ap-bss-when-removing-tdls-peer.patch +wifi-ath11k-fix-warning-when-unbinding.patch +wifi-rtlwifi-rtl8821ae-fix-c2h-bit-location-in-rx-descriptor.patch +wifi-rtw88-increase-tx-report-timeout-to-fix-race-condition.patch +wifi-rtw88-usb-fix-memory-leaks-on-usb-write-failures.patch +wifi-iwlwifi-mvm-fix-race-condition-in-ptp-removal.patch +wifi-iwlwifi-mld-fix-race-condition-in-ptp-removal.patch +wifi-iwlwifi-mld-validate-sta_mask-before-ffs-in-ba-session-handlers.patch +f2fs-pass-correct-iostat-type-for-single-node-writes.patch +f2fs-validate-orphan-inode-entry-count.patch +f2fs-validate-compress-cache-inode-only-when-enabled.patch +f2fs-fix-to-round-down-start-offset-of-fallocate-for-pin-file.patch +f2fs-validate-acl-entry-sizes-in-f2fs_acl_from_disk.patch +f2fs-fix-incorrect-fi_no_extent-handling-in-__destroy_extent_node.patch +f2fs-keep-atomic-write-retry-from-zeroing-original-data.patch +block-avoid-mounting-the-bdev-pseudo-filesystem-in-userspace.patch +bpf-use-kvfree-for-replaced-sysctl-write-buffer.patch +mips-dec-prevent-initial-console-buffer-from-landing-in-xkphys.patch +exfat-fix-potential-use-after-free-in-exfat_find_dir_entry.patch +kvm-x86-mmu-ensure-hugepage-is-in-by-slot-before-checking-max-mapping-level.patch +kvm-replace-guest-triggerable-bug_on-in-ioeventfd-datamatch-with-get_unaligned.patch +crypto-nx-fix-nx_crypto_ctx_exit-argument.patch diff --git a/queue-6.18/userfaultfd-ensure-mremap_userfaultfd_fail-releases-mmap_changing.patch b/queue-6.18/userfaultfd-ensure-mremap_userfaultfd_fail-releases-mmap_changing.patch new file mode 100644 index 0000000000..3efb356777 --- /dev/null +++ b/queue-6.18/userfaultfd-ensure-mremap_userfaultfd_fail-releases-mmap_changing.patch @@ -0,0 +1,48 @@ +From 0496a59745b0723ea74274db16fd5c8b1379b9a9 Mon Sep 17 00:00:00 2001 +From: "Mike Rapoport (Microsoft)" +Date: Wed, 13 May 2026 11:14:16 +0300 +Subject: userfaultfd: ensure mremap_userfaultfd_fail() releases mmap_changing + +From: Mike Rapoport (Microsoft) + +commit 0496a59745b0723ea74274db16fd5c8b1379b9a9 upstream. + +Sashiko says: + + mremap_userfaultfd_prep() increments ctx->mmap_changing to stall + concurrent operations, but mremap_userfaultfd_fail() does not + decrement it before dropping the context reference. + +If an mremap operation fails, ctx->mmap_changing remains elevated. This +will causes subsequent userfaultfd operations like a UFFDIO_COPY to fail +with -EAGAIN. + +Decrement ctx->mmap_changing in mremap_userfaultfd_fail(). + +Link: https://sashiko.dev/#/patchset/20260430113512.115938-1-rppt@kernel.org +Link: https://lore.kernel.org/20260513081416.495963-1-rppt@kernel.org +Fixes: df2cc96e7701 ("userfaultfd: prevent non-cooperative events vs mcopy_atomic races") +Signed-off-by: Mike Rapoport (Microsoft) +Reviewed-by: David Hildenbrand (Arm) +Cc: Al Viro +Cc: Christian Brauner +Cc: Jan Kara +Cc: Peter Xu +Cc: +Signed-off-by: Andrew Morton +Signed-off-by: Greg Kroah-Hartman +--- + fs/userfaultfd.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/fs/userfaultfd.c ++++ b/fs/userfaultfd.c +@@ -767,6 +767,8 @@ void mremap_userfaultfd_fail(struct vm_u + if (!ctx) + return; + ++ atomic_dec(&ctx->mmap_changing); ++ VM_WARN_ON_ONCE(atomic_read(&ctx->mmap_changing) < 0); + userfaultfd_ctx_put(ctx); + } + diff --git a/queue-6.18/wifi-ath11k-fix-warning-when-unbinding.patch b/queue-6.18/wifi-ath11k-fix-warning-when-unbinding.patch new file mode 100644 index 0000000000..139b9e6a2c --- /dev/null +++ b/queue-6.18/wifi-ath11k-fix-warning-when-unbinding.patch @@ -0,0 +1,49 @@ +From 8b7a26b6681922a38cd5a7829ace61f8e54df9b7 Mon Sep 17 00:00:00 2001 +From: Jose Ignacio Tornos Martinez +Date: Mon, 20 Apr 2026 13:01:29 +0200 +Subject: wifi: ath11k: fix warning when unbinding + +From: Jose Ignacio Tornos Martinez + +commit 8b7a26b6681922a38cd5a7829ace61f8e54df9b7 upstream. + +If there is an error during some initialization related to firmware, +the buffers dp->tx_ring[i].tx_status are released. +However this is released again when the device is unbinded (ath11k_pci), +and we get: +WARNING: CPU: 0 PID: 6231 at mm/slub.c:4368 free_large_kmalloc+0x57/0x90 +Call Trace: +free_large_kmalloc +ath11k_dp_free +ath11k_core_deinit +ath11k_pci_remove +... + +The issue is always reproducible from a VM because the MSI addressing +initialization is failing. + +In order to fix the issue, just set the buffers to NULL after releasing in +order to avoid the double free. + +Fixes: d5c65159f289 ("ath11k: driver for Qualcomm IEEE 802.11ax devices") +Cc: stable@vger.kernel.org +Signed-off-by: Jose Ignacio Tornos Martinez +Reviewed-by: Baochen Qiang +Reviewed-by: Rameshkumar Sundaram +Link: https://patch.msgid.link/20260420110130.509670-1-jtornosm@redhat.com +Signed-off-by: Jeff Johnson +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/wireless/ath/ath11k/dp.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/net/wireless/ath/ath11k/dp.c ++++ b/drivers/net/wireless/ath/ath11k/dp.c +@@ -1042,6 +1042,7 @@ void ath11k_dp_free(struct ath11k_base * + idr_destroy(&dp->tx_ring[i].txbuf_idr); + spin_unlock_bh(&dp->tx_ring[i].tx_idr_lock); + kfree(dp->tx_ring[i].tx_status); ++ dp->tx_ring[i].tx_status = NULL; + } + + /* Deinit any SOC level resource */ diff --git a/queue-6.18/wifi-iwlwifi-mld-fix-race-condition-in-ptp-removal.patch b/queue-6.18/wifi-iwlwifi-mld-fix-race-condition-in-ptp-removal.patch new file mode 100644 index 0000000000..5e9a25a543 --- /dev/null +++ b/queue-6.18/wifi-iwlwifi-mld-fix-race-condition-in-ptp-removal.patch @@ -0,0 +1,46 @@ +From e1fc08598aa34b28359831e768076f56632720c1 Mon Sep 17 00:00:00 2001 +From: Junjie Cao +Date: Thu, 12 Feb 2026 20:50:35 +0800 +Subject: wifi: iwlwifi: mld: fix race condition in PTP removal + +From: Junjie Cao + +commit e1fc08598aa34b28359831e768076f56632720c1 upstream. + +iwl_mld_ptp_remove() calls cancel_delayed_work_sync() only after +ptp_clock_unregister() and clearing ptp_data state (ptp_clock, +last_gp2, wrap_counter). + +This creates a race where the delayed work iwl_mld_ptp_work() can +execute between ptp_clock_unregister() and cancel_delayed_work_sync(), +observing partially cleared PTP state. + +Move cancel_delayed_work_sync() before ptp_clock_unregister() to +ensure the delayed work is fully stopped before any PTP cleanup +begins. + +Cc: stable@vger.kernel.org +Reviewed-by: Simon Horman +Reviewed-by: Vadim Fedorenko +Signed-off-by: Junjie Cao +Link: https://patch.msgid.link/20260212125035.1345718-2-junjie.cao@intel.com +Signed-off-by: Miri Korenblit +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/wireless/intel/iwlwifi/mld/ptp.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/net/wireless/intel/iwlwifi/mld/ptp.c ++++ b/drivers/net/wireless/intel/iwlwifi/mld/ptp.c +@@ -319,10 +319,10 @@ void iwl_mld_ptp_remove(struct iwl_mld * + mld->ptp_data.ptp_clock_info.name, + ptp_clock_index(mld->ptp_data.ptp_clock)); + ++ cancel_delayed_work_sync(&mld->ptp_data.dwork); + ptp_clock_unregister(mld->ptp_data.ptp_clock); + mld->ptp_data.ptp_clock = NULL; + mld->ptp_data.last_gp2 = 0; + mld->ptp_data.wrap_counter = 0; +- cancel_delayed_work_sync(&mld->ptp_data.dwork); + } + } diff --git a/queue-6.18/wifi-iwlwifi-mld-validate-sta_mask-before-ffs-in-ba-session-handlers.patch b/queue-6.18/wifi-iwlwifi-mld-validate-sta_mask-before-ffs-in-ba-session-handlers.patch new file mode 100644 index 0000000000..47231a90db --- /dev/null +++ b/queue-6.18/wifi-iwlwifi-mld-validate-sta_mask-before-ffs-in-ba-session-handlers.patch @@ -0,0 +1,59 @@ +From f056fc2b927448d37eca6b6cacc3d1b0f67b20d2 Mon Sep 17 00:00:00 2001 +From: Junrui Luo +Date: Thu, 2 Apr 2026 14:48:07 +0800 +Subject: wifi: iwlwifi: mld: validate sta_mask before ffs() in BA session handlers + +From: Junrui Luo + +commit f056fc2b927448d37eca6b6cacc3d1b0f67b20d2 upstream. + +Three BA session handlers use ffs(ba_data->sta_mask) - 1 to derive a +station ID without checking that sta_mask is non-zero. When sta_mask is +zero, ffs() returns 0 and the subtraction wraps to 0xFFFFFFFF, causing +an out-of-bounds access on fw_id_to_link_sta[]. + +Add WARN_ON_ONCE(!ba_data->sta_mask) guards before each ffs() call, +consistent with the existing check in iwl_mld_ampdu_rx_start(). + +Reported-by: Yuhao Jiang +Cc: stable@vger.kernel.org +Signed-off-by: Junrui Luo +Link: https://patch.msgid.link/SYBPR01MB788115C6CE873271A9A15A25AF51A@SYBPR01MB7881.ausprd01.prod.outlook.com +Signed-off-by: Miri Korenblit +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/wireless/intel/iwlwifi/mld/agg.c | 9 +++++++++ + 1 file changed, 9 insertions(+) + +--- a/drivers/net/wireless/intel/iwlwifi/mld/agg.c ++++ b/drivers/net/wireless/intel/iwlwifi/mld/agg.c +@@ -64,6 +64,9 @@ static void iwl_mld_release_frames_from_ + } + + /* pick any STA ID to find the pointer */ ++ if (WARN_ON_ONCE(!ba_data->sta_mask)) ++ goto out_unlock; ++ + sta_id = ffs(ba_data->sta_mask) - 1; + link_sta = rcu_dereference(mld->fw_id_to_link_sta[sta_id]); + if (WARN_ON_ONCE(IS_ERR_OR_NULL(link_sta) || !link_sta->sta)) +@@ -166,6 +169,9 @@ void iwl_mld_del_ba(struct iwl_mld *mld, + goto out_unlock; + + /* pick any STA ID to find the pointer */ ++ if (WARN_ON_ONCE(!ba_data->sta_mask)) ++ goto out_unlock; ++ + sta_id = ffs(ba_data->sta_mask) - 1; + link_sta = rcu_dereference(mld->fw_id_to_link_sta[sta_id]); + if (WARN_ON_ONCE(IS_ERR_OR_NULL(link_sta) || !link_sta->sta)) +@@ -347,6 +353,9 @@ static void iwl_mld_rx_agg_session_expir + } + + /* timer expired, pick any STA ID to find the pointer */ ++ if (WARN_ON_ONCE(!ba_data->sta_mask)) ++ goto unlock; ++ + sta_id = ffs(ba_data->sta_mask) - 1; + link_sta = rcu_dereference(ba_data->mld->fw_id_to_link_sta[sta_id]); + diff --git a/queue-6.18/wifi-iwlwifi-mvm-fix-race-condition-in-ptp-removal.patch b/queue-6.18/wifi-iwlwifi-mvm-fix-race-condition-in-ptp-removal.patch new file mode 100644 index 0000000000..d88a2f00c4 --- /dev/null +++ b/queue-6.18/wifi-iwlwifi-mvm-fix-race-condition-in-ptp-removal.patch @@ -0,0 +1,47 @@ +From 65150c9cc3e06ab54bc4e8134a47f6f5d095a4e3 Mon Sep 17 00:00:00 2001 +From: Junjie Cao +Date: Thu, 12 Feb 2026 20:50:34 +0800 +Subject: wifi: iwlwifi: mvm: fix race condition in PTP removal + +From: Junjie Cao + +commit 65150c9cc3e06ab54bc4e8134a47f6f5d095a4e3 upstream. + +iwl_mvm_ptp_remove() calls cancel_delayed_work_sync() only after +ptp_clock_unregister() and clearing ptp_data state (ptp_clock, +ptp_clock_info, last_gp2). + +This creates a race where the delayed work iwl_mvm_ptp_work() can +execute between ptp_clock_unregister() and cancel_delayed_work_sync(), +observing partially cleared PTP state. + +Move cancel_delayed_work_sync() before ptp_clock_unregister() to +ensure the delayed work is fully stopped before any PTP cleanup +begins. + +Cc: stable@vger.kernel.org +Reviewed-by: Simon Horman +Reviewed-by: Vadim Fedorenko +Signed-off-by: Junjie Cao +Link: https://patch.msgid.link/20260212125035.1345718-1-junjie.cao@intel.com +Signed-off-by: Miri Korenblit +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/wireless/intel/iwlwifi/mvm/ptp.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/net/wireless/intel/iwlwifi/mvm/ptp.c ++++ b/drivers/net/wireless/intel/iwlwifi/mvm/ptp.c +@@ -323,11 +323,11 @@ void iwl_mvm_ptp_remove(struct iwl_mvm * + mvm->ptp_data.ptp_clock_info.name, + ptp_clock_index(mvm->ptp_data.ptp_clock)); + ++ cancel_delayed_work_sync(&mvm->ptp_data.dwork); + ptp_clock_unregister(mvm->ptp_data.ptp_clock); + mvm->ptp_data.ptp_clock = NULL; + memset(&mvm->ptp_data.ptp_clock_info, 0, + sizeof(mvm->ptp_data.ptp_clock_info)); + mvm->ptp_data.last_gp2 = 0; +- cancel_delayed_work_sync(&mvm->ptp_data.dwork); + } + } diff --git a/queue-6.18/wifi-mt76-mt76x2u-add-support-for-elecom-wdc-867su3s.patch b/queue-6.18/wifi-mt76-mt76x2u-add-support-for-elecom-wdc-867su3s.patch new file mode 100644 index 0000000000..9b20946419 --- /dev/null +++ b/queue-6.18/wifi-mt76-mt76x2u-add-support-for-elecom-wdc-867su3s.patch @@ -0,0 +1,34 @@ +From f4ce0664e9f0387873b181777891741c33e19465 Mon Sep 17 00:00:00 2001 +From: Zenm Chen +Date: Tue, 7 Apr 2026 23:44:30 +0800 +Subject: wifi: mt76: mt76x2u: Add support for ELECOM WDC-867SU3S + +From: Zenm Chen + +commit f4ce0664e9f0387873b181777891741c33e19465 upstream. + +Add the ID 056e:400a to the table to support an additional MT7612U +adapter: ELECOM WDC-867SU3S. + +Compile tested only. + +Cc: stable@vger.kernel.org # 5.10.x +Signed-off-by: Zenm Chen +Acked-by: Lorenzo Bianconi +Link: https://patch.msgid.link/20260407154430.9184-1-zenmchen@gmail.com +Signed-off-by: Felix Fietkau +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/wireless/mediatek/mt76/mt76x2/usb.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/net/wireless/mediatek/mt76/mt76x2/usb.c ++++ b/drivers/net/wireless/mediatek/mt76/mt76x2/usb.c +@@ -16,6 +16,7 @@ static const struct usb_device_id mt76x2 + { USB_DEVICE(0x0e8d, 0x7612) }, /* Aukey USBAC1200 - Alfa AWUS036ACM */ + { USB_DEVICE(0x057c, 0x8503) }, /* Avm FRITZ!WLAN AC860 */ + { USB_DEVICE(0x7392, 0xb711) }, /* Edimax EW 7722 UAC */ ++ { USB_DEVICE(0x056e, 0x400a) }, /* ELECOM WDC-867SU3S */ + { USB_DEVICE(0x0e8d, 0x7632) }, /* HC-M7662BU1 */ + { USB_DEVICE(0x0471, 0x2126) }, /* LiteOn WN4516R module, nonstandard USB connector */ + { USB_DEVICE(0x0471, 0x7600) }, /* LiteOn WN4519R module, nonstandard USB connector */ diff --git a/queue-6.18/wifi-mt76-mt7925-don-t-disable-ap-bss-when-removing-tdls-peer.patch b/queue-6.18/wifi-mt76-mt7925-don-t-disable-ap-bss-when-removing-tdls-peer.patch new file mode 100644 index 0000000000..cfba1a7db1 --- /dev/null +++ b/queue-6.18/wifi-mt76-mt7925-don-t-disable-ap-bss-when-removing-tdls-peer.patch @@ -0,0 +1,69 @@ +From 37d65384aa6f9cbe45f4052b13b378af1aab3e95 Mon Sep 17 00:00:00 2001 +From: ElXreno +Date: Wed, 6 May 2026 04:39:16 +0300 +Subject: wifi: mt76: mt7925: don't disable AP BSS when removing TDLS peer + +From: ElXreno + +commit 37d65384aa6f9cbe45f4052b13b378af1aab3e95 upstream. + +On a STATION vif, removing a TDLS peer takes the mt7925_mac_sta_remove +-> mt7925_mac_sta_remove_links path. The first loop in that function +calls mt7925_mcu_add_bss_info(..., enable=false) for every link of the +station being removed. For a non-MLO STATION vif there is exactly one +link, link 0, whose bss_conf is the AP's. TDLS peers do not have their +own bss_conf - they share the AP's BSS. + +The result is that every TDLS peer teardown sends a BSS_INFO_UPDATE +with enable=0 for the AP's BSS to the firmware, which wipes the AP-side +rate-control context. The connection stays associated and TX from the +host still works at the negotiated rate, but the AP's downlink to us +collapses to the lowest mandatory OFDM rate (HE-MCS 0 / 6 Mbit/s OFDM) +and only slowly recovers as rate adaptation re-learns under sustained +traffic. With brief or bursty traffic the link can stay at 6-72 Mbit/s +indefinitely, requiring a manual reconnect. + +mt7925_mac_link_sta_remove() already guards its own +mt7925_mcu_add_bss_info(..., false) call with +"vif->type == NL80211_IFTYPE_STATION && !link_sta->sta->tdls". +Add the equivalent guard at the top of the cleanup loop in +mt7925_mac_sta_remove_links(), above the link_sta / link_conf / +mlink / mconf lookups, so TDLS peer teardown skips the loop body +entirely without doing the per-link work that would just be thrown +away. + +Verified on mt7925e by triggering Samsung-S938B auto-TDLS via iperf3 +and watching iw rx bitrate after teardown: + + Before: rx bitrate collapses to 6.0-72.0 Mbit/s, oscillates 17/72/ + 137/288/432 Mbit/s for 30+ seconds, no full recovery without + a manual reassoc. + After: rx bitrate stays at 1200.9 Mbit/s HE-MCS 11 NSS 2 80 MHz + across the entire TDLS lifecycle. + +bpftrace confirms a single mt7925_mcu_add_bss_info(enable=0) call per +teardown before the fix; zero such calls after. + +Fixes: 3878b4333602 ("wifi: mt76: mt7925: update mt7925_mac_link_sta_[add, assoc, remove] for MLO") +Cc: stable@vger.kernel.org +Signed-off-by: ElXreno +Assisted-by: Claude:claude-opus-4-7 bpftrace +Link: https://patch.msgid.link/20260506-mt7925-tdls-fixes-v2-2-46aa826ba8bb@gmail.com +Signed-off-by: Felix Fietkau +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/wireless/mediatek/mt76/mt7925/main.c | 3 +++ + 1 file changed, 3 insertions(+) + +--- a/drivers/net/wireless/mediatek/mt76/mt7925/main.c ++++ b/drivers/net/wireless/mediatek/mt76/mt7925/main.c +@@ -1144,6 +1144,9 @@ mt7925_mac_sta_remove_links(struct mt792 + if (vif->type == NL80211_IFTYPE_AP) + break; + ++ if (vif->type == NL80211_IFTYPE_STATION && sta->tdls) ++ continue; ++ + link_sta = mt792x_sta_to_link_sta(vif, sta, link_id); + if (!link_sta) + continue; diff --git a/queue-6.18/wifi-rtlwifi-rtl8821ae-fix-c2h-bit-location-in-rx-descriptor.patch b/queue-6.18/wifi-rtlwifi-rtl8821ae-fix-c2h-bit-location-in-rx-descriptor.patch new file mode 100644 index 0000000000..1f59c9a2d0 --- /dev/null +++ b/queue-6.18/wifi-rtlwifi-rtl8821ae-fix-c2h-bit-location-in-rx-descriptor.patch @@ -0,0 +1,39 @@ +From 83d38df6929118c3f996b9e3351c2d5014073d87 Mon Sep 17 00:00:00 2001 +From: Bitterblue Smith +Date: Sat, 25 Apr 2026 22:32:58 +0300 +Subject: wifi: rtlwifi: rtl8821ae: Fix C2H bit location in RX descriptor + +From: Bitterblue Smith + +commit 83d38df6929118c3f996b9e3351c2d5014073d87 upstream. + +Bit 28 of double word 2 in the RX descriptor indicates if the packet is +a normal 802.11 frame, or a message from the wifi firmware to the +driver (Card 2 Host). + +Commit f5678bfe1cdc ("rtlwifi: rtl8821ae: Replace local bit manipulation +macros") mistakenly made the driver look for this bit in double word 1, +causing packet loss and Bluetooth coexistence problems. + +Fixes: f5678bfe1cdc ("rtlwifi: rtl8821ae: Replace local bit manipulation macros") +Cc: +Signed-off-by: Bitterblue Smith +Acked-by: Ping-Ke Shih +Signed-off-by: Ping-Ke Shih +Link: https://patch.msgid.link/04da7398-cedb-425a-a810-5772ab10139d@gmail.com +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/wireless/realtek/rtlwifi/rtl8821ae/trx.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/trx.h ++++ b/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/trx.h +@@ -291,7 +291,7 @@ static inline int get_rx_desc_paggr(__le + + static inline int get_rx_status_desc_rpt_sel(__le32 *__pdesc) + { +- return le32_get_bits(*(__pdesc + 1), BIT(28)); ++ return le32_get_bits(*(__pdesc + 2), BIT(28)); + } + + static inline int get_rx_desc_rxmcs(__le32 *__pdesc) diff --git a/queue-6.18/wifi-rtw88-increase-tx-report-timeout-to-fix-race-condition.patch b/queue-6.18/wifi-rtw88-increase-tx-report-timeout-to-fix-race-condition.patch new file mode 100644 index 0000000000..8045054fbb --- /dev/null +++ b/queue-6.18/wifi-rtw88-increase-tx-report-timeout-to-fix-race-condition.patch @@ -0,0 +1,62 @@ +From c80788f7c5aed8d420366b821f867a8a353d83a5 Mon Sep 17 00:00:00 2001 +From: Luka Gejak +Date: Mon, 18 May 2026 16:23:10 +0200 +Subject: wifi: rtw88: increase TX report timeout to fix race condition + +From: Luka Gejak + +commit c80788f7c5aed8d420366b821f867a8a353d83a5 upstream. + +The driver expects the firmware to report TX status within 500ms. +However, a timeout can be triggered when the hardware performs +background scans while under TX load. During these scans, the firmware +stays off-channel for periods exceeding 500ms, delaying the delivery of +TX reports back to the driver. + +When this occurs, the purge timer fires prematurely and drops the +tracking skbs from the queue. This results in the host stack +interpreting the missing status as packet loss, leading to TCP window +collapse. In testing with iperf3, this causes throughput to drop from +~90 Mbps to near-zero for approximately 2 seconds until the connection +recovers. + +Increase RTW_TX_PROBE_TIMEOUT to 2500ms for RTL8723DU. This duration is +sufficient to accommodate off-channel dwell time during full background +scans, ensuring the purge timer only trips during genuine firmware +lockups and preventing unnecessary TCP retransmission cycles. + +Fixes: a82dfd33d123 ("wifi: rtw88: Add common USB chip support") +Cc: stable@vger.kernel.org +Acked-by: Ping-Ke Shih +Tested-by: Luka Gejak +Signed-off-by: Luka Gejak +Signed-off-by: Ping-Ke Shih +Link: https://patch.msgid.link/20260518142311.10328-1-luka.gejak@linux.dev +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/wireless/realtek/rtw88/tx.c | 7 ++++++- + 1 file changed, 6 insertions(+), 1 deletion(-) + +--- a/drivers/net/wireless/realtek/rtw88/tx.c ++++ b/drivers/net/wireless/realtek/rtw88/tx.c +@@ -196,6 +196,7 @@ void rtw_tx_report_purge_timer(struct ti + void rtw_tx_report_enqueue(struct rtw_dev *rtwdev, struct sk_buff *skb, u8 sn) + { + struct rtw_tx_report *tx_report = &rtwdev->tx_report; ++ unsigned long timeout = RTW_TX_PROBE_TIMEOUT; + unsigned long flags; + u8 *drv_data; + +@@ -207,7 +208,11 @@ void rtw_tx_report_enqueue(struct rtw_de + __skb_queue_tail(&tx_report->queue, skb); + spin_unlock_irqrestore(&tx_report->q_lock, flags); + +- mod_timer(&tx_report->purge_timer, jiffies + RTW_TX_PROBE_TIMEOUT); ++ if (rtwdev->chip->id == RTW_CHIP_TYPE_8723D && ++ rtwdev->hci.type == RTW_HCI_TYPE_USB) ++ timeout = msecs_to_jiffies(2500); ++ ++ mod_timer(&tx_report->purge_timer, jiffies + timeout); + } + EXPORT_SYMBOL(rtw_tx_report_enqueue); + diff --git a/queue-6.18/wifi-rtw88-usb-fix-memory-leaks-on-usb-write-failures.patch b/queue-6.18/wifi-rtw88-usb-fix-memory-leaks-on-usb-write-failures.patch new file mode 100644 index 0000000000..63b2fda990 --- /dev/null +++ b/queue-6.18/wifi-rtw88-usb-fix-memory-leaks-on-usb-write-failures.patch @@ -0,0 +1,79 @@ +From 6b964941bbfe6e0f18b1a5e008486dbb62df440a Mon Sep 17 00:00:00 2001 +From: Luka Gejak +Date: Mon, 18 May 2026 16:23:11 +0200 +Subject: wifi: rtw88: usb: fix memory leaks on USB write failures + +From: Luka Gejak + +commit 6b964941bbfe6e0f18b1a5e008486dbb62df440a upstream. + +When rtw_usb_write_port() fails to submit a USB Request Block (URB) +(e.g., due to device disconnect or ENOMEM), the completion callback is +never executed. + +Currently, the driver ignores the return value of rtw_usb_write_port() +in rtw_usb_write_data() and rtw_usb_tx_agg_skb(). Because these +functions rely on the completion callback to free the socket buffers +(skbs) and the transaction control block (txcb), a submission failure +results in: +1. A memory leak of the allocated skb in rtw_usb_write_data(). +2. A memory leak of the txcb structure and all aggregated skbs in + rtw_usb_tx_agg_skb(). + +Fix this by checking the return value of rtw_usb_write_port(). If it +fails, explicitly free the skb in rtw_usb_write_data(), and properly +purge the tx_ack_queue and free the txcb in rtw_usb_tx_agg_skb(). + +The issue was discovered in practice during device disconnect/reconnect +scenarios and memory pressure conditions. Tested by verifying normal TX +operation continues after the fix without regressions. + +Fixes: a82dfd33d123 ("wifi: rtw88: Add common USB chip support") +Cc: stable@vger.kernel.org +Acked-by: Ping-Ke Shih +Tested-by: Luka Gejak +Signed-off-by: Luka Gejak +Signed-off-by: Ping-Ke Shih +Link: https://patch.msgid.link/20260518142311.10328-2-luka.gejak@linux.dev +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/wireless/realtek/rtw88/usb.c | 13 +++++++++++-- + 1 file changed, 11 insertions(+), 2 deletions(-) + +--- a/drivers/net/wireless/realtek/rtw88/usb.c ++++ b/drivers/net/wireless/realtek/rtw88/usb.c +@@ -399,6 +399,7 @@ static bool rtw_usb_tx_agg_skb(struct rt + int agg_num = 0; + unsigned int align_next = 0; + u8 qsel; ++ int ret; + + if (skb_queue_empty(list)) + return false; +@@ -456,7 +457,13 @@ queue: + tx_desc = (struct rtw_tx_desc *)skb_head->data; + qsel = le32_get_bits(tx_desc->w1, RTW_TX_DESC_W1_QSEL); + +- rtw_usb_write_port(rtwdev, qsel, skb_head, rtw_usb_write_port_tx_complete, txcb); ++ ret = rtw_usb_write_port(rtwdev, qsel, skb_head, ++ rtw_usb_write_port_tx_complete, txcb); ++ if (ret) { ++ ieee80211_purge_tx_queue(rtwdev->hw, &txcb->tx_ack_queue); ++ kfree(txcb); ++ return false; ++ } + + return true; + } +@@ -518,8 +525,10 @@ static int rtw_usb_write_data(struct rtw + + ret = rtw_usb_write_port(rtwdev, qsel, skb, + rtw_usb_write_port_complete, skb); +- if (unlikely(ret)) ++ if (unlikely(ret)) { + rtw_err(rtwdev, "failed to do USB write, ret=%d\n", ret); ++ dev_kfree_skb_any(skb); ++ } + + return ret; + }