In the Linux kernel, the following vulnerability has been resolved:
smb: client: fix potential deadlock when reconnecting channels
Fix cifssignalcifsdforreconnect() to take the correct lock order and prevent the following deadlock from happening
====================================================== WARNING: possible circular locking dependency detected
cifsd/6055 is trying to acquire lock: ffff88810ad56038 (&tcpses->srvlock){+.+.}-{3:3}, at: cifssignalcifsdforreconnect+0x134/0x200
but task is already holding lock: ffff888119c64330 (&retbuf->chanlock){+.+.}-{3:3}, at: cifssignalcifsdforreconnect+0xcf/0x200
which lock already depends on the new lock.
the existing dependency chain (in reverse order) is:
-> #2 (&retbuf->chanlock){+.+.}-{3:3}: validatechain+0x1cf/0x270 _lockacquire+0x60e/0x780 lockacquire.part.0+0xb4/0x1f0 rawspinlock+0x2f/0x40 cifssetupsession+0x81/0x4b0 cifsgetsmbses+0x771/0x900 cifsmountgetsession+0x7e/0x170 cifsmount+0x92/0x2d0 cifssmb3domount+0x161/0x460 smb3gettree+0x55/0x90 vfsgettree+0x46/0x180 donewmount+0x1b0/0x2e0 pathmount+0x6ee/0x740 domount+0x98/0xe0 _dosysmount+0x148/0x180 dosyscall64+0xa4/0x260 entrySYSCALL64afterhwframe+0x76/0x7e
-> #1 (&retbuf->seslock){+.+.}-{3:3}: validatechain+0x1cf/0x270 _lockacquire+0x60e/0x780 lockacquire.part.0+0xb4/0x1f0 rawspinlock+0x2f/0x40 cifsmatchsuper+0x101/0x320 sget+0xab/0x270 cifssmb3domount+0x1e0/0x460 smb3gettree+0x55/0x90 vfsgettree+0x46/0x180 donewmount+0x1b0/0x2e0 pathmount+0x6ee/0x740 domount+0x98/0xe0 _dosysmount+0x148/0x180 dosyscall64+0xa4/0x260 entrySYSCALL64after_hwframe+0x76/0x7e
-> #0 (&tcpses->srvlock){+.+.}-{3:3}: checknoncircular+0x95/0xc0 checkprevadd+0x115/0x2f0 validatechain+0x1cf/0x270 _lockacquire+0x60e/0x780 lockacquire.part.0+0xb4/0x1f0 _rawspinlock+0x2f/0x40 cifssignalcifsdforreconnect+0x134/0x200 _cifsreconnect+0x8f/0x500 cifshandlestandard+0x112/0x280 cifsdemultiplexthread+0x64d/0xbc0 kthread+0x2f7/0x310 retfromfork+0x2a/0x230 retfromforkasm+0x1a/0x30
other info that might help us debug this:
Chain exists of: &tcpses->srvlock --> &retbuf->seslock --> &retbuf->chanlock
Possible unsafe locking scenario:
CPU0 CPU1
---- ----
lock(&retbuf->chanlock); lock(&retbuf->seslock); lock(&retbuf->chanlock); lock(&tcpses->srvlock);
* DEADLOCK *
3 locks held by cifsd/6055: #0: ffffffff857de398 (&cifstcpseslock){+.+.}-{3:3}, at: cifssignalcifsdforreconnect+0x7b/0x200 #1: ffff888119c64060 (&retbuf->seslock){+.+.}-{3:3}, at: cifssignalcifsdforreconnect+0x9c/0x200 #2: ffff888119c64330 (&retbuf->chanlock){+.+.}-{3:3}, at: cifssignalcifsdfor_reconnect+0xcf/0x200