{"id":"CVE-2025-21850","state":"PUBLISHED","title":"nvmet: Fix crash when a namespace is disabled","description":"In the Linux kernel, the following vulnerability has been resolved:\n\nnvmet: Fix crash when a namespace is disabled\n\nThe namespace percpu counter protects pending I/O, and we can\nonly safely diable the namespace once the counter drop to zero.\nOtherwise we end up with a crash when running blktests/nvme/058\n(eg for loop transport):\n\n[ 2352.930426] [  T53909] Oops: general protection fault, probably for non-canonical address 0xdffffc0000000005: 0000 [#1] PREEMPT SMP KASAN PTI\n[ 2352.930431] [  T53909] KASAN: null-ptr-deref in range [0x0000000000000028-0x000000000000002f]\n[ 2352.930434] [  T53909] CPU: 3 UID: 0 PID: 53909 Comm: kworker/u16:5 Tainted: G        W          6.13.0-rc6 #232\n[ 2352.930438] [  T53909] Tainted: [W]=WARN\n[ 2352.930440] [  T53909] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.16.3-3.fc41 04/01/2014\n[ 2352.930443] [  T53909] Workqueue: nvmet-wq nvme_loop_execute_work [nvme_loop]\n[ 2352.930449] [  T53909] RIP: 0010:blkcg_set_ioprio+0x44/0x180\n\nas the queue is already torn down when calling submit_bio();\n\nSo we need to init the percpu counter in nvmet_ns_enable(), and\nwait for it to drop to zero in nvmet_ns_disable() to avoid having\nI/O pending after the namespace has been disabled.","publishedAt":"2025-03-12T09:42:05.761Z","updatedAt":"2026-08-05T11:54:53.966Z","severity":{"score":9.8,"label":"Critical","version":"3.1","vector":"CVSS:3.1/AV:N/AC:L/PR:N/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":"74d16965d7ac378d28ebd833ae6d6a097186a4ec","status":"affected","lessThan":"cc0607594f6813342b27c752c6fb6f6eb9980cb5","versionType":"git"},{"version":"74d16965d7ac378d28ebd833ae6d6a097186a4ec","status":"affected","lessThan":"4082326807072b71496501b6a0c55ffe8d5092a5","versionType":"git"}],"repo":"https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git","programFiles":["drivers/nvme/target/core.c"]},{"vendor":"Linux","product":"Linux","defaultStatus":"affected","versions":[{"version":"6.13","status":"affected"},{"version":"0","status":"unaffected","lessThan":"6.13","versionType":"semver"},{"version":"6.13.5","status":"unaffected","lessThanOrEqual":"6.13.*","versionType":"semver"},{"version":"6.14","status":"unaffected","lessThanOrEqual":"*","versionType":"original_commit_for_fix"}],"repo":"https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git","programFiles":["drivers/nvme/target/core.c"]}],"references":["https://git.kernel.org/stable/c/cc0607594f6813342b27c752c6fb6f6eb9980cb5","https://git.kernel.org/stable/c/4082326807072b71496501b6a0c55ffe8d5092a5"],"weaknesses":["CWE-835"],"ingestedAt":"2026-10-29T20:08:39.238Z","source":{"repository":"CVEProject/cvelistV5","path":"cves/2025/21xxx/CVE-2025-21850.json","commit":"556c9d3a8cd17e218bb8e452ba7cd619a384ff47"},"raw":{"dataType":"CVE_RECORD","dataVersion":"5.2","cveMetadata":{"cveId":"CVE-2025-21850","state":"PUBLISHED","datePublished":"2025-03-12T09:42:05.761Z","dateUpdated":"2026-08-05T11:54:53.966Z","assignerShortName":"Linux","assignerOrgId":"416baaa9-dc9f-4396-8d5f-8c081fb06d67","dateReserved":"2024-12-29T08:45:45.779Z"},"containers":{"cna":{"title":"nvmet: Fix crash when a namespace is disabled","descriptions":[{"lang":"en","value":"In the Linux kernel, the following vulnerability has been resolved:\n\nnvmet: Fix crash when a namespace is disabled\n\nThe namespace percpu counter protects pending I/O, and we can\nonly safely diable the namespace once the counter drop to zero.\nOtherwise we end up with a crash when running blktests/nvme/058\n(eg for loop transport):\n\n[ 2352.930426] [  T53909] Oops: general protection fault, probably for non-canonical address 0xdffffc0000000005: 0000 [#1] PREEMPT SMP KASAN PTI\n[ 2352.930431] [  T53909] KASAN: null-ptr-deref in range [0x0000000000000028-0x000000000000002f]\n[ 2352.930434] [  T53909] CPU: 3 UID: 0 PID: 53909 Comm: kworker/u16:5 Tainted: G        W          6.13.0-rc6 #232\n[ 2352.930438] [  T53909] Tainted: [W]=WARN\n[ 2352.930440] [  T53909] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.16.3-3.fc41 04/01/2014\n[ 2352.930443] [  T53909] Workqueue: nvmet-wq nvme_loop_execute_work [nvme_loop]\n[ 2352.930449] [  T53909] RIP: 0010:blkcg_set_ioprio+0x44/0x180\n\nas the queue is already torn down when calling submit_bio();\n\nSo we need to init the percpu counter in nvmet_ns_enable(), and\nwait for it to drop to zero in nvmet_ns_disable() to avoid having\nI/O pending after the namespace has been disabled."}],"affected":[{"vendor":"Linux","product":"Linux","defaultStatus":"unaffected","versions":[{"version":"74d16965d7ac378d28ebd833ae6d6a097186a4ec","status":"affected","lessThan":"cc0607594f6813342b27c752c6fb6f6eb9980cb5","versionType":"git"},{"version":"74d16965d7ac378d28ebd833ae6d6a097186a4ec","status":"affected","lessThan":"4082326807072b71496501b6a0c55ffe8d5092a5","versionType":"git"}],"repo":"https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git","programFiles":["drivers/nvme/target/core.c"]},{"vendor":"Linux","product":"Linux","defaultStatus":"affected","versions":[{"version":"6.13","status":"affected"},{"version":"0","status":"unaffected","lessThan":"6.13","versionType":"semver"},{"version":"6.13.5","status":"unaffected","lessThanOrEqual":"6.13.*","versionType":"semver"},{"version":"6.14","status":"unaffected","lessThanOrEqual":"*","versionType":"original_commit_for_fix"}],"repo":"https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git","programFiles":["drivers/nvme/target/core.c"]}],"references":[{"url":"https://git.kernel.org/stable/c/cc0607594f6813342b27c752c6fb6f6eb9980cb5"},{"url":"https://git.kernel.org/stable/c/4082326807072b71496501b6a0c55ffe8d5092a5"}],"metrics":[{"cvssV3_1":{"version":"3.1","vectorString":"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H","baseScore":9.8,"baseSeverity":"CRITICAL"},"scenarios":[{"lang":"en","value":"AV:N - The buggy code is in nvmet core, shared by nvmet-tcp (TCP/4420) and nvmet-rdma, and the in-flight request that holds the stale namespace reference is created and timed by a remote NVMe-oF initiator — `nvmet_req_init()` takes the ref on the command-capsule PDU and the target waits for the host's H2C data PDUs before executing. The remote peer therefore both holds the reference and picks the moment of the stale dereference.\nAC:L - The attacker can park a write command so the namespace percpu-ref is held indefinitely and then deliver the data PDU at will, so no race must be \"won\" and no memory-layout condition applies; on a loaded target there is always outstanding I/O anyway. In orchestrated NVMe-oF deployments the attacker also drives the disable side through ordinary volume detach, making both halves attacker-controlled.\nPR:N - nvmet performs no cryptographic authentication by default — admission is a plaintext host-NQN string compare (`nvmet_host_allowed()`) or `allow_any_host=1`, both trivially satisfied by an unauthenticated peer. Issuing normal read/write commands on a connection the attacker establishes requires no privilege on the target host.\nUI:N - In the realistic orchestrated/multi-tenant deployment the attacker triggers the namespace disable itself via a control-plane volume detach while holding stalled I/O, so no other user participates. Namespace disable is also routine automated reconfiguration rather than a discrete victim action.\nS:U - The corruption and its consequences are confined to the target host's kernel; no VM, IOMMU, or sandbox authority boundary is crossed.\nC:H - This is a use-after-free of `struct file`, the bvec mempool, and PR `pc_ref` slab objects, all reachable from a request whose contents the attacker controls; reclaiming those allocations with attacker-chosen data yields kernel memory disclosure via read/compare responses. Per kernel guidance, UAF is scored High for confidentiality.\nI:H - The file-backed path performs an indirect call through `req->ns->file->f_op->write_iter` on a freed file, a direct control-flow-hijack primitive, and the PR path performs a `percpu_ref_put()` write into kfree'd memory. Both are exploitable write/execute primitives after heap grooming.\nA:H - The bug reproduces as an immediate kernel oops — a general protection fault in `blkcg_set_ioprio()` from `submit_bio()` on a torn-down request queue, as recorded in the fix commit. A remote initiator can trigger this deterministically, panicking the storage target."}]}],"providerMetadata":{"shortName":"Linux","orgId":"416baaa9-dc9f-4396-8d5f-8c081fb06d67","dateUpdated":"2026-08-05T11:54:53.966Z"},"cpeApplicability":[{"nodes":[{"operator":"OR","negate":false,"cpeMatch":[{"vulnerable":true,"criteria":"cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:*","versionStartIncluding":"6.13","versionEndExcluding":"6.13.5"},{"vulnerable":true,"criteria":"cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:*","versionStartIncluding":"6.13","versionEndExcluding":"6.14"}]}]}],"x_generator":{"engine":"bippy-1.2.0"}},"adp":[{"title":"CISA ADP Vulnrichment","metrics":[{"cvssV3_1":{"scope":"UNCHANGED","version":"3.1","baseScore":5.5,"attackVector":"LOCAL","baseSeverity":"MEDIUM","vectorString":"CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:N/I:N/A:H","integrityImpact":"NONE","userInteraction":"NONE","attackComplexity":"LOW","availabilityImpact":"HIGH","privilegesRequired":"LOW","confidentialityImpact":"NONE"}},{"other":{"type":"ssvc","content":{"id":"CVE-2025-21850","role":"CISA Coordinator","options":[{"Exploitation":"none"},{"Automatable":"no"},{"Technical Impact":"partial"}],"version":"2.0.3","timestamp":"2025-10-01T19:26:16.776927Z"}}}],"problemTypes":[{"descriptions":[{"cweId":"CWE-835","lang":"en","type":"CWE","description":"CWE-835 Loop with Unreachable Exit Condition ('Infinite Loop')"}]}],"providerMetadata":{"shortName":"CISA-ADP","orgId":"134c704f-9b21-4f2e-91b3-4a467353bcc0","dateUpdated":"2025-10-01T19:26:38.884Z"}}]}}}