Skip to content

Commit b0b7332

Browse files
kzall0csmfrench
authored andcommitted
cifs: Fix null-ptr-deref by static initializing global lock
A kernel panic can be triggered by reading /proc/fs/cifs/debug_dirs. The crash is a null-ptr-deref inside spin_lock(), caused by the use of the uninitialized global spinlock cifs_tcp_ses_lock. init_cifs() └── cifs_proc_init() └── // User can access /proc/fs/cifs/debug_dirs here └── cifs_debug_dirs_proc_show() └── spin_lock(&cifs_tcp_ses_lock); // Uninitialized! KASAN: null-ptr-deref in range [0x0000000000000000-0x0000000000000007] Mem abort info: ESR = 0x0000000096000005 EC = 0x25: DABT (current EL), IL = 32 bits SET = 0, FnV = 0 EA = 0, S1PTW = 0 FSC = 0x05: level 1 translation fault Data abort info: ISV = 0, ISS = 0x00000005, ISS2 = 0x00000000 CM = 0, WnR = 0, TnD = 0, TagAccess = 0 GCS = 0, Overlay = 0, DirtyBit = 0, Xs = 0 [dfff800000000000] address between user and kernel address ranges Internal error: Oops: 0000000096000005 [#1] SMP Modules linked in: CPU: 3 UID: 0 PID: 16435 Comm: stress-ng-procf Not tainted 6.16.0-10385-g79f14b5d84c6 #37 PREEMPT Hardware name: QEMU KVM Virtual Machine, BIOS 2025.02-8ubuntu1 06/11/2025 pstate: 23400005 (nzCv daif +PAN -UAO +TCO +DIT -SSBS BTYPE=--) pc : do_raw_spin_lock+0x84/0x2cc lr : _raw_spin_lock+0x24/0x34 sp : ffff8000966477e0 x29: ffff800096647860 x28: ffff800096647b88 x27: ffff0001c0c22070 x26: ffff0003eb2b60c8 x25: ffff0001c0c22018 x24: dfff800000000000 x23: ffff0000f624e000 x22: ffff0003eb2b6020 x21: ffff0000f624e768 x20: 0000000000000004 x19: 0000000000000000 x18: 0000000000000000 x17: 0000000000000000 x16: ffff8000804b9600 x15: ffff700012cc8f04 x14: 1ffff00012cc8f04 x13: 0000000000000004 x12: ffffffffffffffff x11: 1ffff00012cc8f00 x10: ffff80008d9af0d2 x9 : f3f3f304f1f1f1f1 x8 : 0000000000000000 x7 : 7365733c203e6469 x6 : 20656572743c2023 x5 : ffff0000e0ce0044 x4 : ffff80008a4deb6e x3 : ffff8000804b9718 x2 : 0000000000000001 x1 : 0000000000000000 x0 : 0000000000000000 Call trace: do_raw_spin_lock+0x84/0x2cc (P) _raw_spin_lock+0x24/0x34 cifs_debug_dirs_proc_show+0x1ac/0x4c0 seq_read_iter+0x3b0/0xc28 proc_reg_read_iter+0x178/0x2a8 vfs_read+0x5f8/0x88c ksys_read+0x120/0x210 __arm64_sys_read+0x7c/0x90 invoke_syscall+0x98/0x2b8 el0_svc_common+0x130/0x23c do_el0_svc+0x48/0x58 el0_svc+0x40/0x140 el0t_64_sync_handler+0x84/0x12c el0t_64_sync+0x1ac/0x1b0 Code: aa0003f3 f9000feb f2fe7e69 f8386969 (38f86908) ---[ end trace 0000000000000000 ]--- The root cause is an initialization order problem. The lock is declared as a global variable and intended to be initialized during module startup. However, the procfs entry that uses this lock can be accessed by userspace before the spin_lock_init() call has run. This creates a race window where reading the proc file will attempt to use the lock before it is initialized, leading to the crash. For a global lock with a static lifetime, the correct and robust approach is to use compile-time initialization. Fixes: 844e5c0 ("smb3 client: add way to show directory leases for improved debugging") Signed-off-by: Yunseong Kim <[email protected]> Signed-off-by: Steve French <[email protected]>
1 parent 1cdd5a2 commit b0b7332

File tree

1 file changed

+2
-4
lines changed

1 file changed

+2
-4
lines changed

fs/smb/client/cifsfs.c

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ unsigned int global_secflags = CIFSSEC_DEF;
7777
unsigned int GlobalCurrentXid; /* protected by GlobalMid_Lock */
7878
unsigned int GlobalTotalActiveXid; /* prot by GlobalMid_Lock */
7979
unsigned int GlobalMaxActiveXid; /* prot by GlobalMid_Lock */
80-
spinlock_t GlobalMid_Lock; /* protects above & list operations on midQ entries */
80+
DEFINE_SPINLOCK(GlobalMid_Lock); /* protects above & list operations on midQ entries */
8181

8282
/*
8383
* Global counters, updated atomically
@@ -97,7 +97,7 @@ atomic_t total_buf_alloc_count;
9797
atomic_t total_small_buf_alloc_count;
9898
#endif/* STATS2 */
9999
struct list_head cifs_tcp_ses_list;
100-
spinlock_t cifs_tcp_ses_lock;
100+
DEFINE_SPINLOCK(cifs_tcp_ses_lock);
101101
static const struct super_operations cifs_super_ops;
102102
unsigned int CIFSMaxBufSize = CIFS_MAX_MSGSIZE;
103103
module_param(CIFSMaxBufSize, uint, 0444);
@@ -1863,8 +1863,6 @@ init_cifs(void)
18631863
GlobalCurrentXid = 0;
18641864
GlobalTotalActiveXid = 0;
18651865
GlobalMaxActiveXid = 0;
1866-
spin_lock_init(&cifs_tcp_ses_lock);
1867-
spin_lock_init(&GlobalMid_Lock);
18681866

18691867
cifs_lock_secret = get_random_u32();
18701868

0 commit comments

Comments
 (0)