--- /dev/null
+From a7a8fe56e932a36f43e031b398aef92341bf5ea0 Mon Sep 17 00:00:00 2001
+From: Wang Zhaolong <wangzhaolong1@huawei.com>
+Date: Fri, 16 May 2025 17:12:55 +0800
+Subject: smb: client: Fix use-after-free in cifs_fill_dirent
+
+From: Wang Zhaolong <wangzhaolong1@huawei.com>
+
+commit a7a8fe56e932a36f43e031b398aef92341bf5ea0 upstream.
+
+There is a race condition in the readdir concurrency process, which may
+access the rsp buffer after it has been released, triggering the
+following KASAN warning.
+
+ ==================================================================
+ BUG: KASAN: slab-use-after-free in cifs_fill_dirent+0xb03/0xb60 [cifs]
+ Read of size 4 at addr ffff8880099b819c by task a.out/342975
+
+ CPU: 2 UID: 0 PID: 342975 Comm: a.out Not tainted 6.15.0-rc6+ #240 PREEMPT(full)
+ Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.16.1-2.fc37 04/01/2014
+ Call Trace:
+ <TASK>
+ dump_stack_lvl+0x53/0x70
+ print_report+0xce/0x640
+ kasan_report+0xb8/0xf0
+ cifs_fill_dirent+0xb03/0xb60 [cifs]
+ cifs_readdir+0x12cb/0x3190 [cifs]
+ iterate_dir+0x1a1/0x520
+ __x64_sys_getdents+0x134/0x220
+ do_syscall_64+0x4b/0x110
+ entry_SYSCALL_64_after_hwframe+0x76/0x7e
+ RIP: 0033:0x7f996f64b9f9
+ Code: ff c3 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 44 00 00 48 89 f8 48 89
+ f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01
+ f0 ff ff 0d f7 c3 0c 00 f7 d8 64 89 8
+ RSP: 002b:00007f996f53de78 EFLAGS: 00000207 ORIG_RAX: 000000000000004e
+ RAX: ffffffffffffffda RBX: 00007f996f53ecdc RCX: 00007f996f64b9f9
+ RDX: 0000000000000000 RSI: 0000000000000000 RDI: 0000000000000003
+ RBP: 00007f996f53dea0 R08: 0000000000000000 R09: 0000000000000000
+ R10: 0000000000000000 R11: 0000000000000207 R12: ffffffffffffff88
+ R13: 0000000000000000 R14: 00007ffc8cd9a500 R15: 00007f996f51e000
+ </TASK>
+
+ Allocated by task 408:
+ kasan_save_stack+0x20/0x40
+ kasan_save_track+0x14/0x30
+ __kasan_slab_alloc+0x6e/0x70
+ kmem_cache_alloc_noprof+0x117/0x3d0
+ mempool_alloc_noprof+0xf2/0x2c0
+ cifs_buf_get+0x36/0x80 [cifs]
+ allocate_buffers+0x1d2/0x330 [cifs]
+ cifs_demultiplex_thread+0x22b/0x2690 [cifs]
+ kthread+0x394/0x720
+ ret_from_fork+0x34/0x70
+ ret_from_fork_asm+0x1a/0x30
+
+ Freed by task 342979:
+ kasan_save_stack+0x20/0x40
+ kasan_save_track+0x14/0x30
+ kasan_save_free_info+0x3b/0x60
+ __kasan_slab_free+0x37/0x50
+ kmem_cache_free+0x2b8/0x500
+ cifs_buf_release+0x3c/0x70 [cifs]
+ cifs_readdir+0x1c97/0x3190 [cifs]
+ iterate_dir+0x1a1/0x520
+ __x64_sys_getdents64+0x134/0x220
+ do_syscall_64+0x4b/0x110
+ entry_SYSCALL_64_after_hwframe+0x76/0x7e
+
+ The buggy address belongs to the object at ffff8880099b8000
+ which belongs to the cache cifs_request of size 16588
+ The buggy address is located 412 bytes inside of
+ freed 16588-byte region [ffff8880099b8000, ffff8880099bc0cc)
+
+ The buggy address belongs to the physical page:
+ page: refcount:0 mapcount:0 mapping:0000000000000000 index:0x0 pfn:0x99b8
+ head: order:3 mapcount:0 entire_mapcount:0 nr_pages_mapped:0 pincount:0
+ anon flags: 0x80000000000040(head|node=0|zone=1)
+ page_type: f5(slab)
+ raw: 0080000000000040 ffff888001e03400 0000000000000000 dead000000000001
+ raw: 0000000000000000 0000000000010001 00000000f5000000 0000000000000000
+ head: 0080000000000040 ffff888001e03400 0000000000000000 dead000000000001
+ head: 0000000000000000 0000000000010001 00000000f5000000 0000000000000000
+ head: 0080000000000003 ffffea0000266e01 00000000ffffffff 00000000ffffffff
+ head: ffffffffffffffff 0000000000000000 00000000ffffffff 0000000000000008
+ page dumped because: kasan: bad access detected
+
+ Memory state around the buggy address:
+ ffff8880099b8080: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
+ ffff8880099b8100: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
+ >ffff8880099b8180: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
+ ^
+ ffff8880099b8200: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
+ ffff8880099b8280: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
+ ==================================================================
+
+POC is available in the link [1].
+
+The problem triggering process is as follows:
+
+Process 1 Process 2
+-----------------------------------------------------------------
+cifs_readdir
+ /* file->private_data == NULL */
+ initiate_cifs_search
+ cifsFile = kzalloc(sizeof(struct cifsFileInfo), GFP_KERNEL);
+ smb2_query_dir_first ->query_dir_first()
+ SMB2_query_directory
+ SMB2_query_directory_init
+ cifs_send_recv
+ smb2_parse_query_directory
+ srch_inf->ntwrk_buf_start = (char *)rsp;
+ srch_inf->srch_entries_start = (char *)rsp + ...
+ srch_inf->last_entry = (char *)rsp + ...
+ srch_inf->smallBuf = true;
+ find_cifs_entry
+ /* if (cfile->srch_inf.ntwrk_buf_start) */
+ cifs_small_buf_release(cfile->srch_inf // free
+
+ cifs_readdir ->iterate_shared()
+ /* file->private_data != NULL */
+ find_cifs_entry
+ /* in while (...) loop */
+ smb2_query_dir_next ->query_dir_next()
+ SMB2_query_directory
+ SMB2_query_directory_init
+ cifs_send_recv
+ compound_send_recv
+ smb_send_rqst
+ __smb_send_rqst
+ rc = -ERESTARTSYS;
+ /* if (fatal_signal_pending()) */
+ goto out;
+ return rc
+ /* if (cfile->srch_inf.last_entry) */
+ cifs_save_resume_key()
+ cifs_fill_dirent // UAF
+ /* if (rc) */
+ return -ENOENT;
+
+Fix this by ensuring the return code is checked before using pointers
+from the srch_inf.
+
+Link: https://bugzilla.kernel.org/show_bug.cgi?id=220131 [1]
+Fixes: a364bc0b37f1 ("[CIFS] fix saving of resume key before CIFSFindNext")
+Cc: stable@vger.kernel.org
+Reviewed-by: Paulo Alcantara (Red Hat) <pc@manguebit.com>
+Signed-off-by: Wang Zhaolong <wangzhaolong1@huawei.com>
+Signed-off-by: Steve French <stfrench@microsoft.com>
+Signed-off-by: Wang Zhaolong <wangzhaolong1@huawei.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/cifs/readdir.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/fs/cifs/readdir.c
++++ b/fs/cifs/readdir.c
+@@ -778,11 +778,11 @@ find_cifs_entry(const unsigned int xid,
+ rc = server->ops->query_dir_next(xid, tcon, &cfile->fid,
+ search_flags,
+ &cfile->srch_inf);
++ if (rc)
++ return -ENOENT;
+ /* FindFirst/Next set last_entry to NULL on malformed reply */
+ if (cfile->srch_inf.last_entry)
+ cifs_save_resume_key(cfile->srch_inf.last_entry, cfile);
+- if (rc)
+- return -ENOENT;
+ }
+ if (index_to_find < cfile->srch_inf.index_of_last_entry) {
+ /* we found the buffer that contains the entry */
--- /dev/null
+From e48f9d849bfdec276eebf782a84fd4dfbe1c14c0 Mon Sep 17 00:00:00 2001
+From: Wang Zhaolong <wangzhaolong1@huawei.com>
+Date: Fri, 16 May 2025 17:12:56 +0800
+Subject: smb: client: Reset all search buffer pointers when releasing buffer
+
+From: Wang Zhaolong <wangzhaolong1@huawei.com>
+
+commit e48f9d849bfdec276eebf782a84fd4dfbe1c14c0 upstream.
+
+Multiple pointers in struct cifs_search_info (ntwrk_buf_start,
+srch_entries_start, and last_entry) point to the same allocated buffer.
+However, when freeing this buffer, only ntwrk_buf_start was set to NULL,
+while the other pointers remained pointing to freed memory.
+
+This is defensive programming to prevent potential issues with stale
+pointers. While the active UAF vulnerability is fixed by the previous
+patch, this change ensures consistent pointer state and more robust error
+handling.
+
+Signed-off-by: Wang Zhaolong <wangzhaolong1@huawei.com>
+Cc: stable@vger.kernel.org
+Reviewed-by: Paulo Alcantara (Red Hat) <pc@manguebit.com>
+Signed-off-by: Steve French <stfrench@microsoft.com>
+Signed-off-by: Wang Zhaolong <wangzhaolong1@huawei.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/cifs/readdir.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+--- a/fs/cifs/readdir.c
++++ b/fs/cifs/readdir.c
+@@ -755,7 +755,10 @@ find_cifs_entry(const unsigned int xid,
+ else
+ cifs_buf_release(cfile->srch_inf.
+ ntwrk_buf_start);
++ /* Reset all pointers to the network buffer to prevent stale references */
+ cfile->srch_inf.ntwrk_buf_start = NULL;
++ cfile->srch_inf.srch_entries_start = NULL;
++ cfile->srch_inf.last_entry = NULL;
+ }
+ rc = initiate_cifs_search(xid, file, full_path);
+ if (rc) {