Re: [PATCH] ksmbd: serialize directory emptiness checks with readdir

From: Namjae Jeon

Date: Thu Oct 22 2026 - 19:51:15 EST


On Fri, Oct 23, 2026 at 2:39 AM Yongjun Gwon <d3bugee@xxxxxxxxx> wrote:
>
> SMB2 QUERY_DIRECTORY holds fp->readdir_lock while it calls iterate_dir()
> on fp->filp. An SMB2 SET_INFO request with FILE_DISPOSITION_INFORMATION
> can resolve the same FileId and call ksmbd_vfs_empty_dir() on the same
> filp without that lock.
>
> iterate_dir()'s inode read lock permits concurrent readers and does not
> serialize per-file iterator state. ext4 stores its dx readdir cursor and
> fname RB tree in file->private_data. Concurrent reset or refill can
> therefore free a fname node while the other worker still traverses it or
> retains its RB-tree link, resulting in use-after-free accesses.
>
> An authenticated SMB client with list and delete rights on a directory in
> a writable KSMBD share backed by ext4 can trigger this when the directory
> takes the dx readdir path. The client overlaps an SMB2 QUERY_DIRECTORY
> request with an SMB2 SET_INFO request carrying FILE_DISPOSITION_INFORMATION
> on one live FileId.
>
> In one x86_64 SMP KASAN multi-shot guest using ksmbd-for-next at
> 171df27077fb, the unmodified kernel reported a cross-worker use-after-free
> before a panic. The first report's access and free stacks show the two
> request paths directly (trimmed):
>
> BUG: KASAN: slab-use-after-free in ext4_htree_store_dirent+0x488/0x550
> Read of size 8 by task kworker/2:0/29
> Workqueue: ksmbd-io handle_ksmbd_work
> Call Trace:
> ext4_htree_store_dirent+0x488/0x550
> htree_dirblock_to_tree+0x535/0x990
> ext4_htree_fill_tree+0x319/0xba0
> ext4_readdir+0x175a/0x2f40
> iterate_dir+0x1b6/0x630
> smb2_query_dir+0x1003/0x1cc0
>
> Freed by task 279:
> free_rb_tree_fname+0x67/0xc0
> ext4_readdir+0x13a9/0x2f40
> iterate_dir+0x1b6/0x630
> ksmbd_vfs_empty_dir+0xa2/0x100
> smb2_set_info+0x2ffa/0x45d0
>
> Take fp->readdir_lock across the entire emptiness check. This places both
> iterators over that handle's filp in the same lock domain while
> preserving the disposition status handling. The exact code change
> completed a warning-free x86_64 KASAN bzImage build. Tracing three request
> pairs showed that the two iterate_dir() calls no longer overlapped and the
> expected statuses were preserved. A further 1,600 reproducer iterations
> completed with expected statuses and no KASAN report, Oops, or panic.
>
> The reproducer and complete guest configuration are available privately
> to maintainers on request.
>
> Fixes: e2f34481b24d ("cifsd: add server-side procedures for SMB3")
> Cc: stable@xxxxxxxxxxxxxxx
> Assisted-by: LLM
> Signed-off-by: Yongjun Gwon <d3bugee@xxxxxxxxx>
Applied it to #ksmbd-for-next.
Thanks!