CVE-2026-90172: smb: smbdirect: destroy QP before mem pools on accept failure
In the Linux kernel, the following vulnerability has been resolved:
smb: smbdirect: destroy QP before mem pools on accept failure
On the rdmaacceptfailed error path of smbdirectacceptconnectrequest(), the receive io posted just above is owned by the QP (recvio is set to NULL after a successful post). The error path fell through to smbdirectconnectiondestroymempools() before smbdirectconnectiondestroyqp(), so the mem pools and the recvio slab cache were destroyed while that recvio was still outstanding on the QP.
The drain in smbdirectconnectiondestroyqp() (ibdrainqp()) is what runs the recv completion that returns the recvio to the free list, so destroying the pools first leaves the object outstanding at kmemcachedestroy() time ("Slab cache still has objects") and later frees it into an already-destroyed mempool (mempoolfreebulk NULL-pointer dereference).
Give rdmaacceptfailed its own teardown that drains the QP first, then destroys the mem pools, and returns. The remaining labels (postrecviofailed onward) run before the recvio was ever posted, so they keep the mem-pools-then-qp order.
The outstanding recvio at kmemcachedestroy() time:
[ 3487.344647] ============================================================================= [ 3487.349942] BUG smbdirectrecviocacheffff88811ba99000 (Not tainted): Objects remaining on kmemcacheshutdown() [ 3487.356078] ----------------------------------------------------------------------------- [ 3487.356078] [ 3487.356738] Object 0xffff8881511c3440 @offset=13376 [ 3487.358464] Allocated in mempoolallocnoprof+0x18c/0x290 age=1194 cpu=6 pid=22254 [ 3487.361197] mempoolallocnoprof+0x18c/0x290 [ 3487.361542] smbdirectconnectioncreatemempools+0x405/0x780 [ 3487.361972] smbdirectacceptconnectrequest+0x5a8/0x1b80 [ 3487.362359] smbdirectlistenrdmaeventhandler+0x1579/0x1b90 [ 3487.362779] cmacmeventhandler+0x9c/0x230 [ 3487.363096] cmaibreqhandler+0x2682/0x45d0 [ 3487.363414] cmprocesswork+0x56/0x3d0 [ 3487.363676] cmworkhandler+0x8a0e/0xd000 [ 3487.367496] processscheduledworks+0xa07/0x13a0 [ 3487.367859] workerthread+0x7c9/0xc80 [ 3487.368148] kthread+0x341/0x430 [ 3487.368407] retfromfork+0x3a8/0x7a0 [ 3487.368704] retfromforkasm+0x1a/0x30 [ 3487.370307] Slab 0xffffea0005447000 objects=19 used=1 fp=0xffff8881511c0040 flags=0x100000000000240(workingset|head|node=0|zone=2) [ 3487.372840] ------------[ cut here ]------------ [ 3487.373195] WARNING: mm/slub.c:1244 at slaberr+0x1a/0x30, CPU#6: kworker/6:84/22254 [ 3487.373759] Modules linked in: [ 3487.373993] CPU: 6 UID: 0 PID: 22254 Comm: kworker/6:84 Tainted: G B 7.1.0-next-20260623+ #88 PREEMPT(lazy) [ 3487.374778] Tainted: [B]=BADPAGE [ 3487.377830] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.17.0-debian-1.17.0-1 04/01/2014 [ 3487.378515] Workqueue: ibcm cmworkhandler [ 3487.378820] RIP: 0010:slaberr+0x1a/0x30 [ 3487.379129] Code: 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 0f 1f 44 00 00 e8 36 00 00 00 bf 05 00 00 00 be 01 00 00 00 e8 f7 75 45 00 90 <0f> 0b 90 c3 cc cc cc cc cc 66 66 66 66 2e 0f 1f 84 00 00 00 00 00 [ 3487.383255] RSP: 0018:ffff888220fc7050 EFLAGS: 00010093 [ 3487.383643] RAX: ffffffff8168e60a RBX: ffff88810955e640 RCX: ffff88821c381d80 [ 3487.384158] RDX: 0000000000000000 RSI: 0000000000000008 RDI: ffffffff870fa080 [ 3487.384662] RBP: ffff888220fc7068 R08: ffffffff870fa087 R09: 1ffffffff0e1f410 [ 3487.385192] R10: dffffc0000000000 R11: fffffbfff0e1f411 R12: ffffea0005447210 [ 3487.385674] R13: ffffea0005447000 R14: ffff888220fc7068 R15: ffff88812a8ab300 [ 3487.388932] FS: 0000000000000000(0000) GS:ffff888427e76000(0000) knlGS:0000000000000000 [ 3487.389529] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 3487.389934] CR2: 00007ffcf2d84fd8 CR3: 0000000111d64006 CR4: 0000000000f72ef0 [ 3487.390440] PKRU: 55555554 [ 3487.390641] Call Trace: [ 3487.390826] <TASK> [ 3 ---truncated---
Affected Software
Remediation
Recommended actions to resolve this vulnerability, in priority order.
- Configuration
On the rdma_accept_failed error path in smbdirect_accept_connect_request(), ensure you teardown/drain the QP first (e.g., add a dedicated rdma_accept_failed teardown that drains the QP via smbdirect_connection_destroy_qp()/ib_drain_qp()), and only then call smbdirect_connection_destroy_mem_pools() to destroy the recv_io slab cache/mempools. This prevents outstanding recv_io objects from being freed into an already-destroyed mempool and avoids the NULL-pointer dereference / slab cache warnings.
Linux kernel smb: smbdirect accept-failure teardown order (smbdirect_connection_destroy_qp vs smbdirect_connection_destroy_mem_pools) = destroy QP before destroying mem pools
Event History
Frequently Asked Questions
Which systems are exposed to this failure path?
Systems using the Linux kernel SMB Direct (smbdirect) RDMA connection path are exposed when an incoming connection reaches the rdma_accept_failed path after a receive I/O has been successfully posted to the queue pair.
What condition is required to trigger the issue?
An RDMA accept failure must occur after the receive I/O is posted and owned by the queue pair. The affected teardown order then destroys memory pools before draining and destroying the queue pair.
What can happen if the vulnerable error path is reached?
The outstanding receive I/O can remain present when its slab cache is destroyed, and its later completion can free memory into an already-destroyed mempool. The description identifies a resulting mempool_free_bulk NULL-pointer dereference.
Is the normal post-receive failure cleanup path affected?
No. The post_recv_io_failed and later cleanup labels run before the receive I/O has been posted, so they retain the memory-pools-then-queue-pair teardown order.