CVE-2025-68756

Source
https://nvd.nist.gov/vuln/detail/CVE-2025-68756
Import Source
https://storage.googleapis.com/cve-osv-conversion/osv-output/CVE-2025-68756.json
JSON Data
https://api.osv.dev/v1/vulns/CVE-2025-68756
Downstream
Published
2026-01-05T09:32:29.824Z
Modified
2026-01-11T20:19:44.992543Z
Summary
block: Use RCU in blk_mq_[un]quiesce_tagset() instead of set->tag_list_lock
Details

In the Linux kernel, the following vulnerability has been resolved:

block: Use RCU in blkmq[un]quiescetagset() instead of set->taglist_lock

blkmq{add,del}queuetagset() functions add and remove queues from tagset, the functions make sure that tagset and queues are marked as shared when two or more queues are attached to the same tagset. Initially a tagset starts as unshared and when the number of added queues reaches two, blkmqaddqueuetagset() marks it as shared along with all the queues attached to it. When the number of attached queues drops to 1 blkmqdelqueuetag_set() need to mark both the tagset and the remaining queues as unshared.

Both functions need to freeze current queues in tagset before setting on unsetting BLKMQFTAGQUEUESHARED flag. While doing so, both functions hold set->taglistlock mutex, which makes sense as we do not want queues to be added or deleted in the process. This used to work fine until commit 98d81f0df70c ("nvme: use blkmq[un]quiescetagset") made the nvme driver quiesce tagset instead of quiscing individual queues. blkmqquiescetagset() does the job and quiesce the queues in set->taglist while holding set->taglistlock also.

This results in deadlock between two threads with these stacktraces:

_schedule+0x47c/0xbb0 ? timerqueueadd+0x66/0xb0 schedule+0x1c/0xa0 schedulepreemptdisabled+0xa/0x10 _mutexlock.constprop.0+0x271/0x600 blkmqquiescetagset+0x25/0xc0 nvmedevdisable+0x9c/0x250 nvmetimeout+0x1fc/0x520 blkmqhandleexpired+0x5c/0x90 btiter+0x7e/0x90 blkmqqueuetagbusyiter+0x27e/0x550 ? _blkmqcompleterequestremote+0x10/0x10 ? _blkmqcompleterequestremote+0x10/0x10 ? _callrcucommon.constprop.0+0x1c0/0x210 blkmqtimeoutwork+0x12d/0x170 processonework+0x12e/0x2d0 workerthread+0x288/0x3a0 ? rescuerthread+0x480/0x480 kthread+0xb8/0xe0 ? kthreadpark+0x80/0x80 retfromfork+0x2d/0x50 ? kthreadpark+0x80/0x80 retfromforkasm+0x11/0x20

_schedule+0x47c/0xbb0 ? xasfind+0x161/0x1a0 schedule+0x1c/0xa0 blkmqfreezequeuewait+0x3d/0x70 ? destroyscheddomainsrcu+0x30/0x30 blkmqupdatetagsetshared+0x44/0x80 blkmqexitqueue+0x141/0x150 delgendisk+0x25a/0x2d0 nvmensremove+0xc9/0x170 nvmeremovenamespaces+0xc7/0x100 nvmeremove+0x62/0x150 pcideviceremove+0x23/0x60 devicereleasedriverinternal+0x159/0x200 unbindstore+0x99/0xa0 kernfsfopwriteiter+0x112/0x1e0 vfswrite+0x2b1/0x3d0 ksyswrite+0x4e/0xb0 dosyscall64+0x5b/0x160 entrySYSCALL64afterhwframe+0x4b/0x53

The top stacktrace is showing nvmetimeout() called to handle nvme command timeout. timeout handler is trying to disable the controller and as a first step, it needs to blkmqquiescetagset() to tell blk-mq not to call queue callback handlers. The thread is stuck waiting for set->taglistlock as it tries to walk the queues in set->tag_list.

The lock is held by the second thread in the bottom stack which is waiting for one of queues to be frozen. The queue usage counter will drop to zero after nvme_timeout() finishes, and this will not happen because the thread will wait for this mutex forever.

Given that [un]quiescing queue is an operation that does not need to sleep, update blkmq[un]quiescetagset() to use RCU instead of taking set->taglistlock, update blkmq{add,del}queuetagset() to use RCU safe list operations. Also, delete INITLISTHEAD(&q->tagsetlist) in blkmqdelqueuetagset() because we can not re-initialize it while the list is being traversed under RCU. The deleted queue will not be added/deleted to/from a tagset and it will be freed in blkfree_queue() after the end of RCU grace period.

Database specific
{
    "osv_generated_from": "https://github.com/CVEProject/cvelistV5/tree/main/cves/2025/68xxx/CVE-2025-68756.json",
    "cna_assigner": "Linux"
}
References

Affected packages

Git / git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git

Affected ranges

Type
GIT
Repo
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
Events
Introduced
98d81f0df70ce6fc48517d938026e3c684b9051a
Fixed
ca8764c0ea1fb825f17f19704af55e9e02c9f768
Fixed
3baeec23a82e7ee9691f434c6ab0ab1387326108
Fixed
6e8d363786765a81e35083e0909e076796468edf
Fixed
ef0cd7b694928573f6569e61c14f5f059253162e
Fixed
59e25ef2b413c72da6686d431e7759302cfccafa

Affected versions

v6.*

v6.1
v6.1-rc3
v6.1-rc4
v6.1-rc5
v6.1-rc6
v6.1-rc7
v6.1-rc8
v6.10
v6.10-rc1
v6.10-rc2
v6.10-rc3
v6.10-rc4
v6.10-rc5
v6.10-rc6
v6.10-rc7
v6.11
v6.11-rc1
v6.11-rc2
v6.11-rc3
v6.11-rc4
v6.11-rc5
v6.11-rc6
v6.11-rc7
v6.12
v6.12-rc1
v6.12-rc2
v6.12-rc3
v6.12-rc4
v6.12-rc5
v6.12-rc6
v6.12-rc7
v6.12.1
v6.12.10
v6.12.11
v6.12.12
v6.12.13
v6.12.14
v6.12.15
v6.12.16
v6.12.17
v6.12.18
v6.12.19
v6.12.2
v6.12.20
v6.12.21
v6.12.22
v6.12.23
v6.12.24
v6.12.25
v6.12.26
v6.12.27
v6.12.28
v6.12.29
v6.12.3
v6.12.30
v6.12.31
v6.12.32
v6.12.33
v6.12.34
v6.12.35
v6.12.36
v6.12.37
v6.12.38
v6.12.39
v6.12.4
v6.12.40
v6.12.41
v6.12.42
v6.12.43
v6.12.44
v6.12.45
v6.12.46
v6.12.47
v6.12.48
v6.12.49
v6.12.5
v6.12.50
v6.12.51
v6.12.52
v6.12.53
v6.12.54
v6.12.55
v6.12.56
v6.12.57
v6.12.58
v6.12.59
v6.12.6
v6.12.60
v6.12.61
v6.12.62
v6.12.7
v6.12.8
v6.12.9
v6.13
v6.13-rc1
v6.13-rc2
v6.13-rc3
v6.13-rc4
v6.13-rc5
v6.13-rc6
v6.13-rc7
v6.14
v6.14-rc1
v6.14-rc2
v6.14-rc3
v6.14-rc4
v6.14-rc5
v6.14-rc6
v6.14-rc7
v6.15
v6.15-rc1
v6.15-rc2
v6.15-rc3
v6.15-rc4
v6.15-rc5
v6.15-rc6
v6.15-rc7
v6.16
v6.16-rc1
v6.16-rc2
v6.16-rc3
v6.16-rc4
v6.16-rc5
v6.16-rc6
v6.16-rc7
v6.17
v6.17-rc1
v6.17-rc2
v6.17-rc3
v6.17-rc4
v6.17-rc5
v6.17-rc6
v6.17-rc7
v6.17.1
v6.17.10
v6.17.11
v6.17.12
v6.17.2
v6.17.3
v6.17.4
v6.17.5
v6.17.6
v6.17.7
v6.17.8
v6.17.9
v6.18
v6.18-rc1
v6.18-rc2
v6.18-rc3
v6.18-rc4
v6.18-rc5
v6.18-rc6
v6.18-rc7
v6.18.1
v6.2
v6.2-rc1
v6.2-rc2
v6.2-rc3
v6.2-rc4
v6.2-rc5
v6.2-rc6
v6.2-rc7
v6.2-rc8
v6.3
v6.3-rc1
v6.3-rc2
v6.3-rc3
v6.3-rc4
v6.3-rc5
v6.3-rc6
v6.3-rc7
v6.4
v6.4-rc1
v6.4-rc2
v6.4-rc3
v6.4-rc4
v6.4-rc5
v6.4-rc6
v6.4-rc7
v6.5
v6.5-rc1
v6.5-rc2
v6.5-rc3
v6.5-rc4
v6.5-rc5
v6.5-rc6
v6.5-rc7
v6.6
v6.6-rc1
v6.6-rc2
v6.6-rc3
v6.6-rc4
v6.6-rc5
v6.6-rc6
v6.6-rc7
v6.6.1
v6.6.10
v6.6.100
v6.6.101
v6.6.102
v6.6.103
v6.6.104
v6.6.105
v6.6.106
v6.6.107
v6.6.108
v6.6.109
v6.6.11
v6.6.110
v6.6.111
v6.6.112
v6.6.113
v6.6.114
v6.6.115
v6.6.116
v6.6.117
v6.6.118
v6.6.119
v6.6.12
v6.6.13
v6.6.14
v6.6.15
v6.6.16
v6.6.17
v6.6.18
v6.6.19
v6.6.2
v6.6.20
v6.6.21
v6.6.22
v6.6.23
v6.6.24
v6.6.25
v6.6.26
v6.6.27
v6.6.28
v6.6.29
v6.6.3
v6.6.30
v6.6.31
v6.6.32
v6.6.33
v6.6.34
v6.6.35
v6.6.36
v6.6.37
v6.6.38
v6.6.39
v6.6.4
v6.6.40
v6.6.41
v6.6.42
v6.6.43
v6.6.44
v6.6.45
v6.6.46
v6.6.47
v6.6.48
v6.6.49
v6.6.5
v6.6.50
v6.6.51
v6.6.52
v6.6.53
v6.6.54
v6.6.55
v6.6.56
v6.6.57
v6.6.58
v6.6.59
v6.6.6
v6.6.60
v6.6.61
v6.6.62
v6.6.63
v6.6.64
v6.6.65
v6.6.66
v6.6.67
v6.6.68
v6.6.69
v6.6.7
v6.6.70
v6.6.71
v6.6.72
v6.6.73
v6.6.74
v6.6.75
v6.6.76
v6.6.77
v6.6.78
v6.6.79
v6.6.8
v6.6.80
v6.6.81
v6.6.82
v6.6.83
v6.6.84
v6.6.85
v6.6.86
v6.6.87
v6.6.88
v6.6.89
v6.6.9
v6.6.90
v6.6.91
v6.6.92
v6.6.93
v6.6.94
v6.6.95
v6.6.96
v6.6.97
v6.6.98
v6.6.99
v6.7
v6.7-rc1
v6.7-rc2
v6.7-rc3
v6.7-rc4
v6.7-rc5
v6.7-rc6
v6.7-rc7
v6.7-rc8
v6.8
v6.8-rc1
v6.8-rc2
v6.8-rc3
v6.8-rc4
v6.8-rc5
v6.8-rc6
v6.8-rc7
v6.9
v6.9-rc1
v6.9-rc2
v6.9-rc3
v6.9-rc4
v6.9-rc5
v6.9-rc6
v6.9-rc7

Database specific

source

"https://storage.googleapis.com/cve-osv-conversion/osv-output/CVE-2025-68756.json"

Linux / Kernel

Package

Name
Kernel

Affected ranges

Type
ECOSYSTEM
Events
Introduced
6.2.0
Fixed
6.6.120
Type
ECOSYSTEM
Events
Introduced
6.7.0
Fixed
6.12.63
Type
ECOSYSTEM
Events
Introduced
6.13.0
Fixed
6.17.13
Type
ECOSYSTEM
Events
Introduced
6.18.0
Fixed
6.18.2

Database specific

source

"https://storage.googleapis.com/cve-osv-conversion/osv-output/CVE-2025-68756.json"