{"id":"CVE-2026-64112","state":"PUBLISHED","title":"rbd: eliminate a race in lock_dwork draining on unmap","description":"In the Linux kernel, the following vulnerability has been resolved:\n\nrbd: eliminate a race in lock_dwork draining on unmap\n\nGiven how rbd_lock_add_request() and rbd_img_exclusive_lock() are\nwritten, lock_dwork may be (re)queued more than it's actually needed:\nfor example in case a new I/O request comes in while we are in the\nmiddle of rbd_acquire_lock() on behalf of another I/O request.  This is\nexpected and with rbd_release_lock() preemptively canceling lock_dwork\nis benign under normal operation.\n\nA more problematic example is maybe_kick_acquire():\n\n    if (have_requests || delayed_work_pending(&rbd_dev->lock_dwork)) {\n            dout(\"%s rbd_dev %p kicking lock_dwork\\n\", __func__, rbd_dev);\n            mod_delayed_work(rbd_dev->task_wq, &rbd_dev->lock_dwork, 0);\n    }\n\nIt's not unrealistic for lock_dwork to get canceled right after\ndelayed_work_pending() returns true and for mod_delayed_work() to\nrequeue it right there anyway.  This is a classic TOCTOU race.\n\nWhen it comes to unmapping the image, there is an implicit assumption\nof no self-initiated exclusive lock activity past the point of return\nfrom rbd_dev_image_unlock() which unlocks the lock if it happens to be\nheld.  This unlock is assumed to be final and lock_dwork (as well as\nall other exclusive lock tasks, really) isn't expected to get queued\nagain.  However, lock_dwork is canceled only in cancel_tasks_sync()\n(i.e. later in the unmap sequence) and on top of that the cancellation\ncan get in effect nullified by maybe_kick_acquire().  This may result\nin rbd_acquire_lock() executing after rbd_dev_device_release() and\nrbd_dev_image_release() run and free and/or reset a bunch of things.\nOne of the possible failure modes then is a violated\n\n    rbd_assert(rbd_image_format_valid(rbd_dev->image_format));\n\nin rbd_dev_header_info() which is called via rbd_dev_refresh() from\nrbd_post_acquire_action().\n\nRedo exclusive lock task draining to provide saner semantics and try\nto meet the assumptions around rbd_dev_image_unlock().","publishedAt":"2026-07-19T15:40:13.652Z","updatedAt":"2026-10-19T20:28:12.366Z","severity":{"score":7.8,"label":"High","version":"3.1","vector":"CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H","source":"Linux"},"assigner":"Linux","products":["Linux Linux"],"affected":[{"vendor":"Linux","product":"Linux","defaultStatus":"unaffected","versions":[{"version":"fd22aef8b47cfc068448df65c1183698b0abd815","status":"affected","lessThan":"3427d7ae38337066ce88b68302e285d344ab756b","versionType":"git"},{"version":"fd22aef8b47cfc068448df65c1183698b0abd815","status":"affected","lessThan":"9dcd4f5c99b491c37be90b0bd9988db48225fb75","versionType":"git"},{"version":"fd22aef8b47cfc068448df65c1183698b0abd815","status":"affected","lessThan":"9400efc76b42c751211974a25c91d2c19c65b01b","versionType":"git"},{"version":"fd22aef8b47cfc068448df65c1183698b0abd815","status":"affected","lessThan":"9fc75b71fdd38465c76c6f6a884cdd4ae3c72d90","versionType":"git"}],"repo":"https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git","programFiles":["drivers/block/rbd.c"]},{"vendor":"Linux","product":"Linux","defaultStatus":"affected","versions":[{"version":"4.12","status":"affected"},{"version":"0","status":"unaffected","lessThan":"4.12","versionType":"semver"},{"version":"6.12.92","status":"unaffected","lessThanOrEqual":"6.12.*","versionType":"semver"},{"version":"6.18.34","status":"unaffected","lessThanOrEqual":"6.18.*","versionType":"semver"},{"version":"7.0.11","status":"unaffected","lessThanOrEqual":"7.0.*","versionType":"semver"},{"version":"7.1","status":"unaffected","lessThanOrEqual":"*","versionType":"original_commit_for_fix"}],"repo":"https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git","programFiles":["drivers/block/rbd.c"]}],"references":["https://git.kernel.org/stable/c/3427d7ae38337066ce88b68302e285d344ab756b","https://git.kernel.org/stable/c/9dcd4f5c99b491c37be90b0bd9988db48225fb75","https://git.kernel.org/stable/c/9400efc76b42c751211974a25c91d2c19c65b01b","https://git.kernel.org/stable/c/9fc75b71fdd38465c76c6f6a884cdd4ae3c72d90"],"weaknesses":["CWE-362"],"ingestedAt":"2026-10-29T20:12:41.951Z","source":{"repository":"CVEProject/cvelistV5","path":"cves/2026/64xxx/CVE-2026-64112.json","commit":"556c9d3a8cd17e218bb8e452ba7cd619a384ff47"},"raw":{"dataType":"CVE_RECORD","dataVersion":"5.2","cveMetadata":{"cveId":"CVE-2026-64112","state":"PUBLISHED","datePublished":"2026-07-19T15:40:13.652Z","dateUpdated":"2026-10-19T20:28:12.366Z","assignerShortName":"Linux","assignerOrgId":"416baaa9-dc9f-4396-8d5f-8c081fb06d67","dateReserved":"2026-07-19T07:54:57.035Z"},"containers":{"cna":{"title":"rbd: eliminate a race in lock_dwork draining on unmap","descriptions":[{"lang":"en","value":"In the Linux kernel, the following vulnerability has been resolved:\n\nrbd: eliminate a race in lock_dwork draining on unmap\n\nGiven how rbd_lock_add_request() and rbd_img_exclusive_lock() are\nwritten, lock_dwork may be (re)queued more than it's actually needed:\nfor example in case a new I/O request comes in while we are in the\nmiddle of rbd_acquire_lock() on behalf of another I/O request.  This is\nexpected and with rbd_release_lock() preemptively canceling lock_dwork\nis benign under normal operation.\n\nA more problematic example is maybe_kick_acquire():\n\n    if (have_requests || delayed_work_pending(&rbd_dev->lock_dwork)) {\n            dout(\"%s rbd_dev %p kicking lock_dwork\\n\", __func__, rbd_dev);\n            mod_delayed_work(rbd_dev->task_wq, &rbd_dev->lock_dwork, 0);\n    }\n\nIt's not unrealistic for lock_dwork to get canceled right after\ndelayed_work_pending() returns true and for mod_delayed_work() to\nrequeue it right there anyway.  This is a classic TOCTOU race.\n\nWhen it comes to unmapping the image, there is an implicit assumption\nof no self-initiated exclusive lock activity past the point of return\nfrom rbd_dev_image_unlock() which unlocks the lock if it happens to be\nheld.  This unlock is assumed to be final and lock_dwork (as well as\nall other exclusive lock tasks, really) isn't expected to get queued\nagain.  However, lock_dwork is canceled only in cancel_tasks_sync()\n(i.e. later in the unmap sequence) and on top of that the cancellation\ncan get in effect nullified by maybe_kick_acquire().  This may result\nin rbd_acquire_lock() executing after rbd_dev_device_release() and\nrbd_dev_image_release() run and free and/or reset a bunch of things.\nOne of the possible failure modes then is a violated\n\n    rbd_assert(rbd_image_format_valid(rbd_dev->image_format));\n\nin rbd_dev_header_info() which is called via rbd_dev_refresh() from\nrbd_post_acquire_action().\n\nRedo exclusive lock task draining to provide saner semantics and try\nto meet the assumptions around rbd_dev_image_unlock()."}],"affected":[{"vendor":"Linux","product":"Linux","defaultStatus":"unaffected","versions":[{"version":"fd22aef8b47cfc068448df65c1183698b0abd815","status":"affected","lessThan":"3427d7ae38337066ce88b68302e285d344ab756b","versionType":"git"},{"version":"fd22aef8b47cfc068448df65c1183698b0abd815","status":"affected","lessThan":"9dcd4f5c99b491c37be90b0bd9988db48225fb75","versionType":"git"},{"version":"fd22aef8b47cfc068448df65c1183698b0abd815","status":"affected","lessThan":"9400efc76b42c751211974a25c91d2c19c65b01b","versionType":"git"},{"version":"fd22aef8b47cfc068448df65c1183698b0abd815","status":"affected","lessThan":"9fc75b71fdd38465c76c6f6a884cdd4ae3c72d90","versionType":"git"}],"repo":"https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git","programFiles":["drivers/block/rbd.c"]},{"vendor":"Linux","product":"Linux","defaultStatus":"affected","versions":[{"version":"4.12","status":"affected"},{"version":"0","status":"unaffected","lessThan":"4.12","versionType":"semver"},{"version":"6.12.92","status":"unaffected","lessThanOrEqual":"6.12.*","versionType":"semver"},{"version":"6.18.34","status":"unaffected","lessThanOrEqual":"6.18.*","versionType":"semver"},{"version":"7.0.11","status":"unaffected","lessThanOrEqual":"7.0.*","versionType":"semver"},{"version":"7.1","status":"unaffected","lessThanOrEqual":"*","versionType":"original_commit_for_fix"}],"repo":"https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git","programFiles":["drivers/block/rbd.c"]}],"references":[{"url":"https://git.kernel.org/stable/c/3427d7ae38337066ce88b68302e285d344ab756b"},{"url":"https://git.kernel.org/stable/c/9dcd4f5c99b491c37be90b0bd9988db48225fb75"},{"url":"https://git.kernel.org/stable/c/9400efc76b42c751211974a25c91d2c19c65b01b"},{"url":"https://git.kernel.org/stable/c/9fc75b71fdd38465c76c6f6a884cdd4ae3c72d90"}],"metrics":[{"cvssV3_1":{"version":"3.1","vectorString":"CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H","baseScore":7.8,"baseSeverity":"HIGH"},"scenarios":[{"lang":"en","value":"AV:L - Exploitation requires writing to /sys/bus/rbd/remove (or the equivalent error-path teardown during map), which is a local sysfs syscall path; network-delivered Ceph lock notifications can assist the race but cannot complete exploitation without this local unmap action.\nAC:L - The attacker controls both sides of the TOCTOU race by concurrently unmapping the device (sysfs remove) while driving lock activity through block I/O or lock-notification handling, making the race winnable with repeated attempts.\nPR:L - Both map and unmap operations require CAP_SYS_ADMIN, which is obtainable by an unprivileged user via user namespaces (unshare -Urn); per kernel CNA guidance this is PR:L rather than PR:H.\nUI:N - No victim interaction is required; the attacker can trigger the race programmatically through concurrent sysfs unmap and I/O or lock-notification activity.\nS:U - Impact is confined to kernel memory corruption and crash on the host running the RBD client; it does not cross a VM, container, or IOMMU security boundary.\nC:H - The bug allows rbd_acquire_lock() to operate on an rbd_device after rbd_dev_image_release() has freed and reset fields, constituting a use-after-free that can expose or dereference freed kernel heap data.\nI:H - Use-after-free on rbd_device and associated header structures provides memory corruption primitives that could be leveraged for arbitrary kernel writes or control-flow hijacking, not merely a clean crash.\nA:H - A confirmed failure mode is rbd_assert() triggering BUG() (kernel panic), and the underlying UAF can also cause oops or hang during post-teardown lock acquisition."}]}],"providerMetadata":{"shortName":"Linux","orgId":"416baaa9-dc9f-4396-8d5f-8c081fb06d67","dateUpdated":"2026-08-05T12:39:21.112Z"},"cpeApplicability":[{"nodes":[{"operator":"OR","negate":false,"cpeMatch":[{"vulnerable":true,"criteria":"cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:*","versionStartIncluding":"4.12","versionEndExcluding":"6.12.92"},{"vulnerable":true,"criteria":"cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:*","versionStartIncluding":"4.12","versionEndExcluding":"6.18.34"},{"vulnerable":true,"criteria":"cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:*","versionStartIncluding":"4.12","versionEndExcluding":"7.0.11"},{"vulnerable":true,"criteria":"cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:*","versionStartIncluding":"4.12","versionEndExcluding":"7.1"}]}]}],"x_generator":{"engine":"bippy-1.2.0"}},"adp":[{"title":"CISA ADP Vulnrichment","metrics":[{"other":{"type":"ssvc","content":{"id":"CVE-2026-64112","role":"CISA Coordinator","options":[{"Exploitation":"none"},{"Automatable":"no"},{"Technical Impact":"total"}],"version":"2.0.3","timestamp":"2026-10-16T15:36:26.577928Z"}}}],"problemTypes":[{"descriptions":[{"cweId":"CWE-362","lang":"en","type":"CWE","description":"CWE-362 Concurrent Execution using Shared Resource with Improper Synchronization ('Race Condition')"}]}],"providerMetadata":{"shortName":"CISA-ADP","orgId":"134c704f-9b21-4f2e-91b3-4a467353bcc0","dateUpdated":"2026-10-19T20:28:12.366Z"}}]}}}