CVE-2025-23143
Publication date:
01/05/2025
In the Linux kernel, the following vulnerability has been resolved:<br />
<br />
net: Fix null-ptr-deref by sock_lock_init_class_and_name() and rmmod.<br />
<br />
When I ran the repro [0] and waited a few seconds, I observed two<br />
LOCKDEP splats: a warning immediately followed by a null-ptr-deref. [1]<br />
<br />
Reproduction Steps:<br />
<br />
1) Mount CIFS<br />
2) Add an iptables rule to drop incoming FIN packets for CIFS<br />
3) Unmount CIFS<br />
4) Unload the CIFS module<br />
5) Remove the iptables rule<br />
<br />
At step 3), the CIFS module calls sock_release() for the underlying<br />
TCP socket, and it returns quickly. However, the socket remains in<br />
FIN_WAIT_1 because incoming FIN packets are dropped.<br />
<br />
At this point, the module&#39;s refcnt is 0 while the socket is still<br />
alive, so the following rmmod command succeeds.<br />
<br />
# ss -tan<br />
State Recv-Q Send-Q Local Address:Port Peer Address:Port<br />
FIN-WAIT-1 0 477 10.0.2.15:51062 10.0.0.137:445<br />
<br />
# lsmod | grep cifs<br />
cifs 1159168 0<br />
<br />
This highlights a discrepancy between the lifetime of the CIFS module<br />
and the underlying TCP socket. Even after CIFS calls sock_release()<br />
and it returns, the TCP socket does not die immediately in order to<br />
close the connection gracefully.<br />
<br />
While this is generally fine, it causes an issue with LOCKDEP because<br />
CIFS assigns a different lock class to the TCP socket&#39;s sk->sk_lock<br />
using sock_lock_init_class_and_name().<br />
<br />
Once an incoming packet is processed for the socket or a timer fires,<br />
sk->sk_lock is acquired.<br />
<br />
Then, LOCKDEP checks the lock context in check_wait_context(), where<br />
hlock_class() is called to retrieve the lock class. However, since<br />
the module has already been unloaded, hlock_class() logs a warning<br />
and returns NULL, triggering the null-ptr-deref.<br />
<br />
If LOCKDEP is enabled, we must ensure that a module calling<br />
sock_lock_init_class_and_name() (CIFS, NFS, etc) cannot be unloaded<br />
while such a socket is still alive to prevent this issue.<br />
<br />
Let&#39;s hold the module reference in sock_lock_init_class_and_name()<br />
and release it when the socket is freed in sk_prot_free().<br />
<br />
Note that sock_lock_init() clears sk->sk_owner for svc_create_socket()<br />
that calls sock_lock_init_class_and_name() for a listening socket,<br />
which clones a socket by sk_clone_lock() without GFP_ZERO.<br />
<br />
[0]:<br />
CIFS_SERVER="10.0.0.137"<br />
CIFS_PATH="//${CIFS_SERVER}/Users/Administrator/Desktop/CIFS_TEST"<br />
DEV="enp0s3"<br />
CRED="/root/WindowsCredential.txt"<br />
<br />
MNT=$(mktemp -d /tmp/XXXXXX)<br />
mount -t cifs ${CIFS_PATH} ${MNT} -o vers=3.0,credentials=${CRED},cache=none,echo_interval=1<br />
<br />
iptables -A INPUT -s ${CIFS_SERVER} -j DROP<br />
<br />
for i in $(seq 10);<br />
do<br />
umount ${MNT}<br />
rmmod cifs<br />
sleep 1<br />
done<br />
<br />
rm -r ${MNT}<br />
<br />
iptables -D INPUT -s ${CIFS_SERVER} -j DROP<br />
<br />
[1]:<br />
DEBUG_LOCKS_WARN_ON(1)<br />
WARNING: CPU: 10 PID: 0 at kernel/locking/lockdep.c:234 hlock_class (kernel/locking/lockdep.c:234 kernel/locking/lockdep.c:223)<br />
Modules linked in: cifs_arc4 nls_ucs2_utils cifs_md4 [last unloaded: cifs]<br />
CPU: 10 UID: 0 PID: 0 Comm: swapper/10 Not tainted 6.14.0 #36<br />
Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.16.0-0-gd239552ce722-prebuilt.qemu.org 04/01/2014<br />
RIP: 0010:hlock_class (kernel/locking/lockdep.c:234 kernel/locking/lockdep.c:223)<br />
...<br />
Call Trace:<br />
<br />
__lock_acquire (kernel/locking/lockdep.c:4853 kernel/locking/lockdep.c:5178)<br />
lock_acquire (kernel/locking/lockdep.c:469 kernel/locking/lockdep.c:5853 kernel/locking/lockdep.c:5816)<br />
_raw_spin_lock_nested (kernel/locking/spinlock.c:379)<br />
tcp_v4_rcv (./include/linux/skbuff.h:1678 ./include/net/tcp.h:2547 net/ipv4/tcp_ipv4.c:2350)<br />
...<br />
<br />
BUG: kernel NULL pointer dereference, address: 00000000000000c4<br />
PF: supervisor read access in kernel mode<br />
PF: error_code(0x0000) - not-present page<br />
PGD 0<br />
Oops: Oops: 0000 [#1] PREEMPT SMP NOPTI<br />
CPU: 10 UID: 0 PID: 0 Comm: swapper/10 Tainted: G W 6.14.0 #36<br />
Tainted: [W]=WARN<br />
Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.16.0-0-gd239552ce722-prebuilt.qemu.org 04/01/2014<br />
RIP: 0010:__lock_acquire (kernel/<br />
---truncated---
Severity CVSS v4.0: Pending analysis
Last modification:
05/11/2025