{"dataType":"CVE_RECORD","dataVersion":"5.2","cveMetadata":{"cveId":"CVE-2025-68756","assignerOrgId":"416baaa9-dc9f-4396-8d5f-8c081fb06d67","state":"PUBLISHED","assignerShortName":"Linux","dateReserved":"2025-12-24T10:30:51.033Z","datePublished":"2026-01-05T09:32:29.824Z","dateUpdated":"2026-05-11T21:52:44.585Z"},"containers":{"cna":{"providerMetadata":{"orgId":"416baaa9-dc9f-4396-8d5f-8c081fb06d67","shortName":"Linux","dateUpdated":"2026-05-11T21:52:44.585Z"},"descriptions":[{"lang":"en","value":"In the Linux kernel, the following vulnerability has been resolved:\n\nblock: Use RCU in blk_mq_[un]quiesce_tagset() instead of set->tag_list_lock\n\nblk_mq_{add,del}_queue_tag_set() functions add and remove queues from\ntagset, the functions make sure that tagset and queues are marked as\nshared when two or more queues are attached to the same tagset.\nInitially a tagset starts as unshared and when the number of added\nqueues reaches two, blk_mq_add_queue_tag_set() marks it as shared along\nwith all the queues attached to it. When the number of attached queues\ndrops to 1 blk_mq_del_queue_tag_set() need to mark both the tagset and\nthe remaining queues as unshared.\n\nBoth functions need to freeze current queues in tagset before setting on\nunsetting BLK_MQ_F_TAG_QUEUE_SHARED flag. While doing so, both functions\nhold set->tag_list_lock mutex, which makes sense as we do not want\nqueues to be added or deleted in the process. This used to work fine\nuntil commit 98d81f0df70c (\"nvme: use blk_mq_[un]quiesce_tagset\")\nmade the nvme driver quiesce tagset instead of quiscing individual\nqueues. blk_mq_quiesce_tagset() does the job and quiesce the queues in\nset->tag_list while holding set->tag_list_lock also.\n\nThis results in deadlock between two threads with these stacktraces:\n\n  __schedule+0x47c/0xbb0\n  ? timerqueue_add+0x66/0xb0\n  schedule+0x1c/0xa0\n  schedule_preempt_disabled+0xa/0x10\n  __mutex_lock.constprop.0+0x271/0x600\n  blk_mq_quiesce_tagset+0x25/0xc0\n  nvme_dev_disable+0x9c/0x250\n  nvme_timeout+0x1fc/0x520\n  blk_mq_handle_expired+0x5c/0x90\n  bt_iter+0x7e/0x90\n  blk_mq_queue_tag_busy_iter+0x27e/0x550\n  ? __blk_mq_complete_request_remote+0x10/0x10\n  ? __blk_mq_complete_request_remote+0x10/0x10\n  ? __call_rcu_common.constprop.0+0x1c0/0x210\n  blk_mq_timeout_work+0x12d/0x170\n  process_one_work+0x12e/0x2d0\n  worker_thread+0x288/0x3a0\n  ? rescuer_thread+0x480/0x480\n  kthread+0xb8/0xe0\n  ? kthread_park+0x80/0x80\n  ret_from_fork+0x2d/0x50\n  ? kthread_park+0x80/0x80\n  ret_from_fork_asm+0x11/0x20\n\n  __schedule+0x47c/0xbb0\n  ? xas_find+0x161/0x1a0\n  schedule+0x1c/0xa0\n  blk_mq_freeze_queue_wait+0x3d/0x70\n  ? destroy_sched_domains_rcu+0x30/0x30\n  blk_mq_update_tag_set_shared+0x44/0x80\n  blk_mq_exit_queue+0x141/0x150\n  del_gendisk+0x25a/0x2d0\n  nvme_ns_remove+0xc9/0x170\n  nvme_remove_namespaces+0xc7/0x100\n  nvme_remove+0x62/0x150\n  pci_device_remove+0x23/0x60\n  device_release_driver_internal+0x159/0x200\n  unbind_store+0x99/0xa0\n  kernfs_fop_write_iter+0x112/0x1e0\n  vfs_write+0x2b1/0x3d0\n  ksys_write+0x4e/0xb0\n  do_syscall_64+0x5b/0x160\n  entry_SYSCALL_64_after_hwframe+0x4b/0x53\n\nThe top stacktrace is showing nvme_timeout() called to handle nvme\ncommand timeout. timeout handler is trying to disable the controller and\nas a first step, it needs to blk_mq_quiesce_tagset() to tell blk-mq not\nto call queue callback handlers. The thread is stuck waiting for\nset->tag_list_lock as it tries to walk the queues in set->tag_list.\n\nThe lock is held by the second thread in the bottom stack which is\nwaiting for one of queues to be frozen. The queue usage counter will\ndrop to zero after nvme_timeout() finishes, and this will not happen\nbecause the thread will wait for this mutex forever.\n\nGiven that [un]quiescing queue is an operation that does not need to\nsleep, update blk_mq_[un]quiesce_tagset() to use RCU instead of taking\nset->tag_list_lock, update blk_mq_{add,del}_queue_tag_set() to use RCU\nsafe list operations. Also, delete INIT_LIST_HEAD(&q->tag_set_list)\nin blk_mq_del_queue_tag_set() because we can not re-initialize it while\nthe list is being traversed under RCU. The deleted queue will not be\nadded/deleted to/from a tagset and it will be freed in blk_free_queue()\nafter the end of RCU grace period."}],"affected":[{"product":"Linux","vendor":"Linux","defaultStatus":"unaffected","repo":"https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git","programFiles":["block/blk-mq.c"],"versions":[{"version":"98d81f0df70ce6fc48517d938026e3c684b9051a","lessThan":"ca8764c0ea1fb825f17f19704af55e9e02c9f768","status":"affected","versionType":"git"},{"version":"98d81f0df70ce6fc48517d938026e3c684b9051a","lessThan":"3baeec23a82e7ee9691f434c6ab0ab1387326108","status":"affected","versionType":"git"},{"version":"98d81f0df70ce6fc48517d938026e3c684b9051a","lessThan":"6e8d363786765a81e35083e0909e076796468edf","status":"affected","versionType":"git"},{"version":"98d81f0df70ce6fc48517d938026e3c684b9051a","lessThan":"ef0cd7b694928573f6569e61c14f5f059253162e","status":"affected","versionType":"git"},{"version":"98d81f0df70ce6fc48517d938026e3c684b9051a","lessThan":"59e25ef2b413c72da6686d431e7759302cfccafa","status":"affected","versionType":"git"}]},{"product":"Linux","vendor":"Linux","defaultStatus":"affected","repo":"https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git","programFiles":["block/blk-mq.c"],"versions":[{"version":"6.2","status":"affected"},{"version":"0","lessThan":"6.2","status":"unaffected","versionType":"semver"},{"version":"6.6.120","lessThanOrEqual":"6.6.*","status":"unaffected","versionType":"semver"},{"version":"6.12.63","lessThanOrEqual":"6.12.*","status":"unaffected","versionType":"semver"},{"version":"6.17.13","lessThanOrEqual":"6.17.*","status":"unaffected","versionType":"semver"},{"version":"6.18.2","lessThanOrEqual":"6.18.*","status":"unaffected","versionType":"semver"},{"version":"6.19","lessThanOrEqual":"*","status":"unaffected","versionType":"original_commit_for_fix"}]}],"cpeApplicability":[{"nodes":[{"operator":"OR","negate":false,"cpeMatch":[{"vulnerable":true,"criteria":"cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:*","versionStartIncluding":"6.2","versionEndExcluding":"6.6.120"},{"vulnerable":true,"criteria":"cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:*","versionStartIncluding":"6.2","versionEndExcluding":"6.12.63"},{"vulnerable":true,"criteria":"cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:*","versionStartIncluding":"6.2","versionEndExcluding":"6.17.13"},{"vulnerable":true,"criteria":"cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:*","versionStartIncluding":"6.2","versionEndExcluding":"6.18.2"},{"vulnerable":true,"criteria":"cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:*","versionStartIncluding":"6.2","versionEndExcluding":"6.19"}]}]}],"references":[{"url":"https://git.kernel.org/stable/c/ca8764c0ea1fb825f17f19704af55e9e02c9f768"},{"url":"https://git.kernel.org/stable/c/3baeec23a82e7ee9691f434c6ab0ab1387326108"},{"url":"https://git.kernel.org/stable/c/6e8d363786765a81e35083e0909e076796468edf"},{"url":"https://git.kernel.org/stable/c/ef0cd7b694928573f6569e61c14f5f059253162e"},{"url":"https://git.kernel.org/stable/c/59e25ef2b413c72da6686d431e7759302cfccafa"}],"title":"block: Use RCU in blk_mq_[un]quiesce_tagset() instead of set->tag_list_lock","x_generator":{"engine":"bippy-1.2.0"}}}}