mirror of
https://github.com/hardkernel/linux.git
synced 2026-03-25 03:50:24 +09:00
smb: client: fix potential cfid UAF in smb2_query_info_compound
commit 5c76f9961c170552c1d07c830b5e145475151600 upstream. When smb2_query_info_compound() retries, a previously allocated cfid may have been freed in the first attempt. Because cfid wasn't reset on replay, later cleanup could act on a stale pointer, leading to a potential use-after-free. Reinitialize cfid to NULL under the replay label. Example trace (trimmed): refcount_t: underflow; use-after-free. WARNING: CPU: 1 PID: 11224 at ../lib/refcount.c:28 refcount_warn_saturate+0x9c/0x110 [...] RIP: 0010:refcount_warn_saturate+0x9c/0x110 [...] Call Trace: <TASK> smb2_query_info_compound+0x29c/0x5c0 [cifs f90b72658819bd21c94769b6a652029a07a7172f] ? step_into+0x10d/0x690 ? __legitimize_path+0x28/0x60 smb2_queryfs+0x6a/0xf0 [cifs f90b72658819bd21c94769b6a652029a07a7172f] smb311_queryfs+0x12d/0x140 [cifs f90b72658819bd21c94769b6a652029a07a7172f] ? kmem_cache_alloc+0x18a/0x340 ? getname_flags+0x46/0x1e0 cifs_statfs+0x9f/0x2b0 [cifs f90b72658819bd21c94769b6a652029a07a7172f] statfs_by_dentry+0x67/0x90 vfs_statfs+0x16/0xd0 user_statfs+0x54/0xa0 __do_sys_statfs+0x20/0x50 do_syscall_64+0x58/0x80 Cc: stable@kernel.org Fixes: 4f1fffa237692 ("cifs: commands that are retried should have replay flag set") Reviewed-by: Paulo Alcantara (Red Hat) <pc@manguebit.com> Acked-by: Shyam Prasad N <sprasad@microsoft.com> Reviewed-by: Enzo Matsumiya <ematsumiya@suse.de> Signed-off-by: Henrique Carvalho <henrique.carvalho@suse.com> Signed-off-by: Steve French <stfrench@microsoft.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
committed by
Greg Kroah-Hartman
parent
6dbd3d9573
commit
939c4e3300
@@ -2663,11 +2663,12 @@ smb2_query_info_compound(const unsigned int xid, struct cifs_tcon *tcon,
|
||||
struct cifs_fid fid;
|
||||
int rc;
|
||||
__le16 *utf16_path;
|
||||
struct cached_fid *cfid = NULL;
|
||||
struct cached_fid *cfid;
|
||||
int retries = 0, cur_sleep = 1;
|
||||
|
||||
replay_again:
|
||||
/* reinitialize for possible replay */
|
||||
cfid = NULL;
|
||||
flags = CIFS_CP_CREATE_CLOSE_OP;
|
||||
oplock = SMB2_OPLOCK_LEVEL_NONE;
|
||||
server = cifs_pick_channel(ses);
|
||||
|
||||
Reference in New Issue
Block a user