In the Linux kernel, the following vulnerability has been resolved:
nbd: fix race between nbdallocconfig() and module removal
When nbd module is being removing, nbdallocconfig() may be called concurrently by nbdgenlconnect(), although trymoduleget() will return false, but nbdallocconfig() doesn't handle it.
The race may lead to the leak of nbdconfig and its related resources (e.g, recvworkq) and oops in nbdreadstat() due to the unload of nbd module as shown below:
BUG: kernel NULL pointer dereference, address: 0000000000000040 Oops: 0000 [#1] SMP PTI CPU: 5 PID: 13840 Comm: kworker/u17:33 Not tainted 5.14.0+ #1 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996) Workqueue: knbd16-recv recvwork [nbd] RIP: 0010:nbdreadstat.cold+0x130/0x1a4 [nbd] Call Trace: recvwork+0x3b/0xb0 [nbd] processonework+0x1ed/0x390 workerthread+0x4a/0x3d0 kthread+0x12a/0x150 retfrom_fork+0x22/0x30
Fixing it by checking the return value of trymoduleget() in nbdallocconfig(). As nbdallocconfig() may return ERRPTR(-ENODEV), assign nbd->config only when nbdalloc_config() succeeds to ensure the value of nbd->config is binary (valid or NULL).
Also adding a debug message to check the reference counter of nbd_config during module removal.