]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
ksmbd: fix use-after-free in __close_file_table_ids()
authorNamjae Jeon <linkinjeon@kernel.org>
Wed, 22 Jul 2026 01:04:19 +0000 (10:04 +0900)
committerSteve French <stfrench@microsoft.com>
Thu, 30 Jul 2026 23:45:57 +0000 (18:45 -0500)
A ksmbd_file can remain alive after logical close while another session
holds a temporary reference obtained through ksmbd_lookup_fd_inode().
ksmbd_close_fd() currently marks the file closed and drops the idr-owned
reference, but leaves the pointer published in the closing session's idr
until the final reference is dropped.

If the foreign holder performs the final ksmbd_fd_put(), __put_fd_final()
supplies the foreign session's file table to __ksmbd_close_fd(). The object
is then freed without being removed from its owner's idr, and the owner
session later dereferences the stale pointer during file-table teardown.

Remove the volatile id from the owner's idr while ksmbd_close_fd() still
holds that table's lock, and clear volatile_id before dropping
the idr-owned reference. A later foreign final put then only performs
physical destruction and cannot remove the object from the wrong table.

Fixes: 8510a043d334 ("ksmbd: increment reference count of parent fp")
Reported-by: Yunseong Kim <yunseong.kim@est.tech>
Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
Signed-off-by: Steve French <stfrench@microsoft.com>
fs/smb/server/vfs_cache.c

index d95c405eab115f0d12ae9800552b1a19228edd5c..a141025581afe2f13f9da2afa08c5f8c524db25b 100644 (file)
@@ -697,6 +697,8 @@ int ksmbd_close_fd(struct ksmbd_work *work, u64 id)
                        fp = NULL;
                else {
                        fp->f_state = FP_CLOSED;
+                       idr_remove(ft->idr, id);
+                       fp->volatile_id = KSMBD_NO_FID;
                        closed = true;
                        if (!atomic_dec_and_test(&fp->refcount))
                                fp = NULL;