--- /dev/null
+From 4c21b5927d4364bfe7365f2700da5fea0ed0d004 Mon Sep 17 00:00:00 2001
+From: Dawei Feng <dawei.feng@seu.edu.cn>
+Date: Wed, 3 Jun 2026 18:53:16 +0800
+Subject: bpf: use kvfree() for replaced sysctl write buffer
+
+From: Dawei Feng <dawei.feng@seu.edu.cn>
+
+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:
+ <TASK>
+ ? __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
+ ...
+ </TASK>
+
+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 <emil@etsalapatis.com>
+Reviewed-by: Jiayuan Chen <jiayuan.chen@linux.dev>
+Acked-by: Yonghong Song <yonghong.song@linux.dev>
+Signed-off-by: Zilin Guan <zilin@seu.edu.cn>
+Signed-off-by: Dawei Feng <dawei.feng@seu.edu.cn>
+Link: https://lore.kernel.org/r/20260603105317.944304-3-dawei.feng@seu.edu.cn
+Signed-off-by: Alexei Starovoitov <ast@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ kernel/bpf/cgroup.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/kernel/bpf/cgroup.c
++++ b/kernel/bpf/cgroup.c
+@@ -1776,7 +1776,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 {
--- /dev/null
+From 94bfc7f3b0c7c33331ba4ff6cc64ff309dfcbce8 Mon Sep 17 00:00:00 2001
+From: Arnd Bergmann <arnd@arndb.de>
+Date: Tue, 26 May 2026 12:18:41 +0200
+Subject: err.h: use __always_inline on all error pointer helpers
+
+From: Arnd Bergmann <arnd@arndb.de>
+
+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 <arnd@arndb.de>
+Reviewed-by: Alexander Lobakin <aleksander.lobakin@intel.com>
+Reviewed-by: Nathan Chancellor <nathan@kernel.org>
+Tested-by: Tamir Duberstein <tamird@kernel.org>
+Cc: Alexander Gordeev <agordeev@linux.ibm.com>
+Cc: Andriy Shevchenko <andriy.shevchenko@linux.intel.com>
+Cc: Ansuel Smith <ansuelsmth@gmail.com>
+Cc: Bjorn Andersson <andersson@kernel.org>
+Cc: Heiko Carstens <hca@linux.ibm.com>
+Cc: Vasily Gorbik <gor@linux.ibm.com>
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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;
+ }
+@@ -46,7 +46,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;
+ }
+@@ -56,7 +56,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);
+ }
+@@ -67,7 +67,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);
+ }
+@@ -79,7 +79,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;
+@@ -102,7 +102,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);
--- /dev/null
+From 3f5f8ee9917cc2b9076ac533492d8a200edcabb8 Mon Sep 17 00:00:00 2001
+From: Michael Bommarito <michael.bommarito@gmail.com>
+Date: Wed, 22 Apr 2026 11:58:44 -0400
+Subject: exfat: fix potential use-after-free in exfat_find_dir_entry()
+
+From: Michael Bommarito <michael.bommarito@gmail.com>
+
+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 <michael.bommarito@gmail.com>
+Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/exfat/dir.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+--- a/fs/exfat/dir.c
++++ b/fs/exfat/dir.c
+@@ -1079,12 +1079,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;
+ }
+@@ -1095,6 +1095,7 @@ rewind:
+ uniname += EXFAT_FILE_NAME_LEN;
+
+ len = exfat_extract_uni_name(ep, entry_uniname);
++ brelse(bh);
+ name_len += len;
+
+ unichar = *(uniname+len);
+@@ -1113,6 +1114,7 @@ rewind:
+ continue;
+ }
+
++ brelse(bh);
+ if (entry_type &
+ (TYPE_CRITICAL_SEC | TYPE_BENIGN_SEC)) {
+ if (step == DIRENT_STEP_SECD) {
--- /dev/null
+From 1f70ddb28a3c71df124da5fa4040c808116d6bb9 Mon Sep 17 00:00:00 2001
+From: Yongpeng Yang <yangyongpeng@xiaomi.com>
+Date: Mon, 27 Apr 2026 21:10:51 +0800
+Subject: f2fs: fix incorrect FI_NO_EXTENT handling in __destroy_extent_node()
+
+From: Yongpeng Yang <yangyongpeng@xiaomi.com>
+
+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 <chao@kernel.org>
+Suggested-by: Chao Yu <chao@kernel.org>
+Signed-off-by: Yongpeng Yang <yangyongpeng@xiaomi.com>
+Reviewed-by: Chao Yu <chao@kernel.org>
+Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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
+@@ -87,10 +87,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;
+@@ -603,14 +602,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;
+ }
+
+@@ -640,12 +635,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;
+
--- /dev/null
+From 4275b59673eb60b02eec3997816c83f1f4b909c4 Mon Sep 17 00:00:00 2001
+From: Sunmin Jeong <s_min.jeong@samsung.com>
+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 <s_min.jeong@samsung.com>
+
+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 <yunji0.kang@samsung.com>
+Reviewed-by: Yeongjin Gil <youngjin.gil@samsung.com>
+Reviewed-by: Sungjong Seo <sj1557.seo@samsung.com>
+Signed-off-by: Sunmin Jeong <s_min.jeong@samsung.com>
+Reviewed-by: Chao Yu <chao@kernel.org>
+Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/f2fs/file.c | 9 ++++++++-
+ 1 file changed, 8 insertions(+), 1 deletion(-)
+
+--- a/fs/f2fs/file.c
++++ b/fs/f2fs/file.c
+@@ -1826,8 +1826,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:
+ if (has_not_enough_free_secs(sbi, 0,
--- /dev/null
+From 6d874b65aadce56ac78f76129dbcfc2599b638f8 Mon Sep 17 00:00:00 2001
+From: Wenjie Qi <qwjhust@gmail.com>
+Date: Wed, 27 May 2026 20:06:28 +0800
+Subject: f2fs: keep atomic write retry from zeroing original data
+
+From: Wenjie Qi <qwjhust@gmail.com>
+
+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 <qiwenjie@xiaomi.com>
+Reviewed-by: Chao Yu <chao@kernel.org>
+Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/f2fs/data.c | 16 +++++++++++-----
+ 1 file changed, 11 insertions(+), 5 deletions(-)
+
+--- a/fs/f2fs/data.c
++++ b/fs/f2fs/data.c
+@@ -3527,6 +3527,7 @@ static int prepare_atomic_write_begin(st
+ pgoff_t index = page->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))
+@@ -3536,9 +3537,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))
+@@ -3551,10 +3554,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;
--- /dev/null
+From c4810ada31e80cbe4011467c4f3b1e93f94134f3 Mon Sep 17 00:00:00 2001
+From: Zhang Cen <rollkingzzc@gmail.com>
+Date: Mon, 15 Jun 2026 15:19:54 +0800
+Subject: f2fs: validate ACL entry sizes in f2fs_acl_from_disk()
+
+From: Zhang Cen <rollkingzzc@gmail.com>
+
+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 <rollkingzzc@gmail.com>
+Reviewed-by: Chao Yu <chao@kernel.org>
+Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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,
--- /dev/null
+From 5073c66a96a9c23c0c2533ed4ed06e42f9021208 Mon Sep 17 00:00:00 2001
+From: Wenjie Qi <qwjhust@gmail.com>
+Date: Thu, 21 May 2026 11:16:18 +0800
+Subject: f2fs: validate compress cache inode only when enabled
+
+From: Wenjie Qi <qwjhust@gmail.com>
+
+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 <qiwenjie@xiaomi.com>
+Reviewed-by: Chao Yu <chao@kernel.org>
+Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/f2fs/inode.c | 9 +++++++--
+ 1 file changed, 7 insertions(+), 2 deletions(-)
+
+--- a/fs/f2fs/inode.c
++++ b/fs/f2fs/inode.c
+@@ -544,8 +544,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)
--- /dev/null
+From 2c1c805c65fb7dc7524e20376d6987721e73a0b1 Mon Sep 17 00:00:00 2001
+From: Ian Bridges <icb@fastmail.org>
+Date: Thu, 25 Jun 2026 23:50:48 -0500
+Subject: fbdev: fix use-after-free in store_modes()
+
+From: Ian Bridges <icb@fastmail.org>
+
+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 <icb@fastmail.org>
+Signed-off-by: Helge Deller <deller@gmx.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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 <linux/major.h>
+
+ #include "fb_internal.h"
++#include "fbcon.h"
+
+ #define FB_SYSFS_FLAG_ATTR 1
+
+@@ -113,8 +114,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();
--- /dev/null
+From cb481e59ea6cae3b7796ac1d7a22b6b24c3f3c0b Mon Sep 17 00:00:00 2001
+From: Jarkko Sakkinen <jarkko@kernel.org>
+Date: Mon, 1 Jun 2026 23:11:54 +0300
+Subject: KEYS: fix overflow in keyctl_pkey_params_get_2()
+
+From: Jarkko Sakkinen <jarkko@kernel.org>
+
+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 <ale.grpp@gmail.com>
+Tested-by: Alessandro Groppo <ale.grpp@gmail.com>
+Signed-off-by: Jarkko Sakkinen <jarkko@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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;
+ }
+
--- /dev/null
+From fd15b457a86939c38aa12116adabd8ff686c5e51 Mon Sep 17 00:00:00 2001
+From: Shaomin Chen <eeesssooo020@gmail.com>
+Date: Wed, 10 Jun 2026 13:10:05 +0300
+Subject: keys: Pin request_key_auth payload in instantiate paths
+
+From: Shaomin Chen <eeesssooo020@gmail.com>
+
+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 <eeesssooo020@gmail.com>
+Closes: https://lore.kernel.org/r/20260519144403.436694-1-eeesssooo020@gmail.com
+Signed-off-by: Shaomin Chen <eeesssooo020@gmail.com>
+Signed-off-by: Jarkko Sakkinen <jarkko@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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 <linux/key.h>
++#include <linux/refcount.h>
+
+ /*
+ * 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
+@@ -215,6 +215,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
+@@ -1196,9 +1196,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;
+@@ -1207,7 +1211,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))
+@@ -1233,6 +1237,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;
--- /dev/null
+From 7fb13fd35110ebe95eb053faf79d018f51144d85 Mon Sep 17 00:00:00 2001
+From: "Maciej W. Rozycki" <macro@orcam.me.uk>
+Date: Wed, 6 May 2026 23:42:27 +0100
+Subject: MIPS: DEC: Prevent initial console buffer from landing in XKPHYS
+
+From: Maciej W. Rozycki <macro@orcam.me.uk>
+
+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 <macro@orcam.me.uk>
+Cc: stable@vger.kernel.org # v2.6.12+
+Signed-off-by: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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 <linux/bug.h>
+ #include <linux/console.h>
+ #include <linux/init.h>
+ #include <linux/kernel.h>
+@@ -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;
--- /dev/null
+From d876153680e3d721d385e554def919bce3d18c74 Mon Sep 17 00:00:00 2001
+From: Koichiro Den <den@valinux.co.jp>
+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 <den@valinux.co.jp>
+
+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 <Frank.Li@nxp.com>
+Signed-off-by: Koichiro Den <den@valinux.co.jp>
+Reviewed-by: Dave Jiang <dave.jiang@intel.com>
+Signed-off-by: Jon Mason <jdmason@kudzu.us>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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);
net-skmsg-preserve-sg.copy-across-sg-transforms.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
+err.h-use-__always_inline-on-all-error-pointer-helpers.patch
+keys-fix-overflow-in-keyctl_pkey_params_get_2.patch
+keys-pin-request_key_auth-payload-in-instantiate-paths.patch
+wifi-mt76-mt76x2u-add-support-for-elecom-wdc-867su3s.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
+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
+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
--- /dev/null
+From 8b7a26b6681922a38cd5a7829ace61f8e54df9b7 Mon Sep 17 00:00:00 2001
+From: Jose Ignacio Tornos Martinez <jtornosm@redhat.com>
+Date: Mon, 20 Apr 2026 13:01:29 +0200
+Subject: wifi: ath11k: fix warning when unbinding
+
+From: Jose Ignacio Tornos Martinez <jtornosm@redhat.com>
+
+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 <jtornosm@redhat.com>
+Reviewed-by: Baochen Qiang <baochen.qiang@oss.qualcomm.com>
+Reviewed-by: Rameshkumar Sundaram <rameshkumar.sundaram@oss.qualcomm.com>
+Link: https://patch.msgid.link/20260420110130.509670-1-jtornosm@redhat.com
+Signed-off-by: Jeff Johnson <jeff.johnson@oss.qualcomm.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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
+@@ -1039,6 +1039,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 */
--- /dev/null
+From 65150c9cc3e06ab54bc4e8134a47f6f5d095a4e3 Mon Sep 17 00:00:00 2001
+From: Junjie Cao <junjie.cao@intel.com>
+Date: Thu, 12 Feb 2026 20:50:34 +0800
+Subject: wifi: iwlwifi: mvm: fix race condition in PTP removal
+
+From: Junjie Cao <junjie.cao@intel.com>
+
+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 <horms@kernel.org>
+Reviewed-by: Vadim Fedorenko <vadim.fedorenko@linux.dev>
+Signed-off-by: Junjie Cao <junjie.cao@intel.com>
+Link: https://patch.msgid.link/20260212125035.1345718-1-junjie.cao@intel.com
+Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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
+@@ -316,11 +316,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);
+ }
+ }
--- /dev/null
+From f4ce0664e9f0387873b181777891741c33e19465 Mon Sep 17 00:00:00 2001
+From: Zenm Chen <zenmchen@gmail.com>
+Date: Tue, 7 Apr 2026 23:44:30 +0800
+Subject: wifi: mt76: mt76x2u: Add support for ELECOM WDC-867SU3S
+
+From: Zenm Chen <zenmchen@gmail.com>
+
+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 <zenmchen@gmail.com>
+Acked-by: Lorenzo Bianconi <lorenzo@kernel.org>
+Link: https://patch.msgid.link/20260407154430.9184-1-zenmchen@gmail.com
+Signed-off-by: Felix Fietkau <nbd@nbd.name>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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 */
--- /dev/null
+From 83d38df6929118c3f996b9e3351c2d5014073d87 Mon Sep 17 00:00:00 2001
+From: Bitterblue Smith <rtl8821cerfe2@gmail.com>
+Date: Sat, 25 Apr 2026 22:32:58 +0300
+Subject: wifi: rtlwifi: rtl8821ae: Fix C2H bit location in RX descriptor
+
+From: Bitterblue Smith <rtl8821cerfe2@gmail.com>
+
+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: <stable@vger.kernel.org>
+Signed-off-by: Bitterblue Smith <rtl8821cerfe2@gmail.com>
+Acked-by: Ping-Ke Shih <pkshih@realtek.com>
+Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
+Link: https://patch.msgid.link/04da7398-cedb-425a-a810-5772ab10139d@gmail.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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)
--- /dev/null
+From c80788f7c5aed8d420366b821f867a8a353d83a5 Mon Sep 17 00:00:00 2001
+From: Luka Gejak <luka.gejak@linux.dev>
+Date: Mon, 18 May 2026 16:23:10 +0200
+Subject: wifi: rtw88: increase TX report timeout to fix race condition
+
+From: Luka Gejak <luka.gejak@linux.dev>
+
+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 <pkshih@realtek.com>
+Tested-by: Luka Gejak <luka.gejak@linux.dev>
+Signed-off-by: Luka Gejak <luka.gejak@linux.dev>
+Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
+Link: https://patch.msgid.link/20260518142311.10328-1-luka.gejak@linux.dev
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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
+@@ -190,6 +190,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;
+
+@@ -201,7 +202,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);
+
--- /dev/null
+From 6b964941bbfe6e0f18b1a5e008486dbb62df440a Mon Sep 17 00:00:00 2001
+From: Luka Gejak <luka.gejak@linux.dev>
+Date: Mon, 18 May 2026 16:23:11 +0200
+Subject: wifi: rtw88: usb: fix memory leaks on USB write failures
+
+From: Luka Gejak <luka.gejak@linux.dev>
+
+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 <pkshih@realtek.com>
+Tested-by: Luka Gejak <luka.gejak@linux.dev>
+Signed-off-by: Luka Gejak <luka.gejak@linux.dev>
+Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
+Link: https://patch.msgid.link/20260518142311.10328-2-luka.gejak@linux.dev
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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
+@@ -339,6 +339,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;
+@@ -394,7 +395,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;
+ }
+@@ -458,8 +465,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;
+ }