ANT-2026-ZRDQDR79 · util-linux/util-linux
use-after-free medium
CVE-2026-13595 GHSA-qpmf-9p9c-455w
Severity Claude critical · Security research firm high · Maintainer medium
Discovered by Claude Mythos Preview
Anthropic's analysis, sealed at approval. Disclosure to the maintainer was performed by Calif.
ANT-2026-ZRDQDR79: Heap-use-after-free in blkid_partition_get_start at partitions.c:1447 via nested BSD disklabel in DOS partition table
A heap-use-after-free (READ) was detected in util-linux's libblkid library through the OSS-Fuzz test-blkid-fuzz harness. libblkid handles probing of block device content types (filesystem superblocks, partition tables) and is invoked by blkid, udev, and automount infrastructure. An attacker who can present a crafted block device image to the system — via USB insertion, virtual disk attachment, or placing a disk image where automounting will scan it — can trigger the read of freed memory during probing. The READ-type UAF most likely yields information disclosure or denial of service, with code execution possible but harder given heap layout dependencies.
Target
Project: util-linux
Location: blkid_partition_get_start() at libblkid/src/partitions/partitions.c:1447
Technical Details
ASAN reports a READ-type heap-use-after-free during libblkid's probing of a crafted input, indicating internal probing data structures are freed and then accessed again. No specific ASAN size/address line or stack frames were provided in the report; the root-cause function and exact freed object are not identified. ASAN READ heap-UAF detections are highly reliable with near-zero false-positive rates due to precise allocator instrumentation.
Crash trace (truncated — full trace in attached crash.log):
INFO: Running with entropic power schedule (0xFF, 100).
INFO: Seed: 2157158283
INFO: Loaded 1 modules (9192 inline 8-bit counters): 9192 [0x568d75257fc8, 0x568d7525a3b0),
INFO: Loaded 1 PC tables (9192 PCs): 9192 [0x568d7525a3b0,0x568d7527e230),
/out/test_blkid_fuzz: Running 1 inputs 1 time(s) each.
Running: /tmp/poc
EXIT_CODE:1
=== ASAN Report ===
=================================================================
==27==ERROR: AddressSanitizer: heap-use-after-free on address 0x75a1663e0200 at pc 0x568d75141f54 bp 0x7fff11ca9940 sp 0x7fff11ca9938
READ of size 8 at 0x75a1663e0200 thread T0
#0 0x568d75141f53 in blkid_partition_get_start /src/util-linux/libblkid/src/partitions/partitions.c:1447:28
#1 0x568d7517ea47 in probe_bsd_pt /src/util-linux/libblkid/src/partitions/bsd.c:132:17
#2 0x568d751428a7 in idinfo_probe /src/util-linux/libblkid/src/partitions/partitions.c:560:8
#3 0x568d751422f8 in blkid_partitions_do_subprobe /src/util-linux/libblkid/src/partitions/partitions.c:719:7
#4 0x568d75180320 in probe_dos_pt /src/util-linux/libblkid/src/partitions/dos.c:342:10
#5 0x568d751428a7 in idinfo_probe /src/util-linux/libblkid/src/partitions/partitions.c:560:8
#6 0x568d751403a6 in partitions_probe /src/util-linux/libblkid/src/partitions/partitions.c:620:8
#7 0x568d7512ff22 in blkid_probe_get_binary_data /src/util-linux/libblkid/src/probe.c:391:7
[... 60 more frames — full trace in crash.log]
Reproduction
- Craft a malicious filesystem/partition image that triggers the UAF code path in libblkid probing
- Present the image to the target: insert USB storage, attach a virtual disk, or place the image where automount infrastructure scans it
- libblkid (invoked by blkid/udev/udisks, typically as root) probes the device and reads freed heap memory
- Result: crash (DoS), potential information disclosure, or — with favorable heap layout and chaining — possible escalation
[No reproducer or sanitizer output attached — request from security-cvd@anthropic.com if needed.]
Acknowledgement
This vulnerability was discovered by Claude, Anthropic's AI assistant, and triaged by the Anthropic security team in collaboration with Anthropic Research. Please direct questions to security-cvd@anthropic.com and reference ANT-2026-ZRDQDR79.
Reference: ANT-2026-ZRDQDR79
Anthropic CVD Policy: https://www.anthropic.com/coordinated-vulnerability-disclosure
Triage and disclosure were performed by Calif.
- Verdict
- true positive
- Severity
- high
The change that resolved this finding.
diff --git a/libblkid/src/partitions/partitions.c b/libblkid/src/partitions/partitions.c
index f95fe898f33..a428c6d6c16 100644
--- a/libblkid/src/partitions/partitions.c
+++ b/libblkid/src/partitions/partitions.c
@@ -199,7 +199,7 @@ struct blkid_struct_partlist {
int nparts; /* number of partitions */
int nparts_max; /* max.number of partitions */
- blkid_partition parts; /* array of partitions */
+ blkid_partition *parts; /* array of pointers to partitions */
struct list_head l_tabs; /* list of partition tables */
};
@@ -358,13 +358,16 @@ static void reset_partlist(blkid_partlist ls)
free_parttables(ls);
if (ls->next_partno) {
- /* already initialized - reset */
- int tmp_nparts = ls->nparts_max;
- blkid_partition tmp_parts = ls->parts;
+ /* already initialized - free individually allocated partitions */
+ int i, tmp_nparts_max = ls->nparts_max;
+ blkid_partition *tmp_parts = ls->parts;
+
+ for (i = 0; i < ls->nparts; i++)
+ free(ls->parts[i]);
memset(ls, 0, sizeof(struct blkid_struct_partlist));
- ls->nparts_max = tmp_nparts;
+ ls->nparts_max = tmp_nparts_max;
ls->parts = tmp_parts;
}
@@ -399,6 +402,7 @@ static void partitions_free_data(blkid_probe pr __attribute__((__unused__)),
void *data)
{
blkid_partlist ls = (blkid_partlist) data;
+ int i;
if (!ls)
return;
@@ -406,6 +410,8 @@ static void partitions_free_data(blkid_probe pr __attribute__((__unused__)),
free_parttables(ls);
/* deallocate partitions and partlist */
+ for (i = 0; i < ls->nparts; i++)
+ free(ls->parts[i]);
free(ls->parts);
free(ls);
}
@@ -439,15 +445,17 @@ static blkid_partition new_partition(blkid_partlist ls, blkid_parttable tab)
* generic Linux machine -- let's start with 32 partitions.
*/
void *tmp = reallocarray(ls->parts, ls->nparts_max + 32,
- sizeof(struct blkid_struct_partition));
+ sizeof(blkid_partition));
if (!tmp)
return NULL;
ls->parts = tmp;
ls->nparts_max += 32;
}
- par = &ls->parts[ls->nparts++];
- memset(par, 0, sizeof(struct blkid_struct_partition));
+ par = calloc(1, sizeof(struct blkid_struct_partition));
+ if (!par)
+ return NULL;
+ ls->parts[ls->nparts++] = par;
ref_parttable(tab);
par->tab = tab;
@@ -852,7 +860,7 @@ int blkid_probe_is_covered_by_pt(blkid_probe pr,
/* check if the partition table fits into the device */
for (i = 0; i < nparts; i++) {
- blkid_partition par = &ls->parts[i];
+ blkid_partition par = ls->parts[i];
if (par->start + par->size > (pr->size >> 9)) {
DBG(LOWPROBE, ul_debug("partition #%d overflows "
@@ -864,7 +872,7 @@ int blkid_probe_is_covered_by_pt(blkid_probe pr,
/* check if the requested area is covered by PT */
for (i = 0; i < nparts; i++) {
- blkid_partition par = &ls->parts[i];
+ blkid_partition par = ls->parts[i];
if (start >= par->start && end <= par->start + par->size) {
rc = 1;
@@ -963,7 +971,7 @@ blkid_partition blkid_partlist_get_partition(blkid_partlist ls, int n)
if (n < 0 || n >= ls->nparts)
return NULL;
- return &ls->parts[n];
+ return ls->parts[n];
}
blkid_partition blkid_partlist_get_partition_by_start(blkid_partlist ls, uint64_t start)
@@ -1075,7 +1083,7 @@ blkid_partition blkid_partlist_devno_to_partition(blkid_partlist ls, dev_t devno
* and an entry in partition table.
*/
for (i = 0; i < ls->nparts; i++) {
- blkid_partition par = &ls->parts[i];
+ blkid_partition par = ls->parts[i];
if (partno != blkid_partition_get_partno(par))
continue;
@@ -1091,7 +1099,7 @@ blkid_partition blkid_partlist_devno_to_partition(blkid_partlist ls, dev_t devno
DBG(LOWPROBE, ul_debug("searching by offset/size"));
for (i = 0; i < ls->nparts; i++) {
- blkid_partition par = &ls->parts[i];
+ blkid_partition par = ls->parts[i];
if ((uint64_t)blkid_partition_get_start(par) == start &&
(uint64_t)blkid_partition_get_size(par) == size)https://github.com/util-linux/util-linux/commit/c0186f14fbdb02f64c8e0ba701ce727ea764ff4c
https://github.com/util-linux/util-linux/commit/c0186f14fbdb02f64c8e0ba701ce727ea764ff4c
Dates from discovery through public reveal.
- 2026-03-20 Reported to tracker
- 2026-05-08 Sent to maintainer
- 2026-05-09 Maintainer acknowledged
- 2026-06-16 Patch released
- 2026-08-17 Publicly revealed
SHA-3-512 hash:
b322f519496ca8294ecf2a7fb53c3196ba0c9377d8c9ea3292509a123e5a32feecfbb9abdf3d4a533628cf09218b84e43bf768ae3dd331c5fbcb96e4aecf000b
Committed 2026-05-08 00:11 PT
Revealed 2026-08-17 10:47 PT
Verify (download preimage.json)
Show preimage JSON
{
"ant_id": "ANT-2026-ZRDQDR79",
"bug_class": "heap-use-after-free",
"claude_severity": "critical",
"commit_sha": null,
"created_at": "2026-03-20T19:13:36+00:00",
"description": "A heap-use-after-free (READ) was detected in util-linux's libblkid library through the OSS-Fuzz test-blkid-fuzz harness. libblkid handles probing of block device content types (filesystem superblocks, partition tables) and is invoked by blkid, udev, and automount infrastructure. An attacker who can present a crafted block device image to the system — via USB insertion, virtual disk attachment, or placing a disk image where automounting will scan it — can trigger the read of freed memory during probing. The READ-type UAF most likely yields information disclosure or denial of service, with code execution possible but harder given heap layout dependencies.",
"discovered_at": null,
"location": "blkid_partition_get_start() at libblkid/src/partitions/partitions.c:1447",
"poc_sha256": "f013a9bb91af93bb8e505dad1e48b271ddade3e924c1192cc8c6cb49dc7d93d9",
"preimage_version": 1,
"project": "util-linux",
"reproduction": [
"Craft a malicious filesystem/partition image that triggers the UAF code path in libblkid probing",
"Present the image to the target: insert USB storage, attach a virtual disk, or place the image where automount infrastructure scans it",
"libblkid (invoked by blkid/udev/udisks, typically as root) probes the device and reads freed heap memory",
"Result: crash (DoS), potential information disclosure, or — with favorable heap layout and chaining — possible escalation"
],
"technical_details": "ASAN reports a READ-type heap-use-after-free during libblkid's probing of a crafted input, indicating internal probing data structures are freed and then accessed again. No specific ASAN size/address line or stack frames were provided in the report; the root-cause function and exact freed object are not identified. ASAN READ heap-UAF detections are highly reliable with near-zero false-positive rates due to precise allocator instrumentation.",
"title": "Heap-use-after-free in blkid_partition_get_start at partitions.c:1447 via nested BSD disklabel in DOS partition table",
"vendor_severity": "high"
}