gptinit() accepts any CRC-self-consistent LBA1 block as a GPT header: hdr_sig ("EFI PART"), hdr_revision, and the partition-array CRC (hdr_crc_table) are never validated
| Field | Value |
|---|---|
| ID | DF-2964 |
| Status | new |
| Severity | Info |
| CVSS 3.1 | CVSS:3.1/AV:L/AC:H/PR:H/UI:N/S:U/C:N/I:N/A:N |
| CWE | CWE-345 |
| File | sys/kern/subr_diskgpt.c |
| Lines | 108-125, 131-144, 186-221 |
| Area | kern/disk |
| Confidence | certain |
| Discovered | 2026-09-02 |
| Pass | 2 (GLM 5.3 second pass) |
| Bucket | base:kern |
| Reported | pending |
| Known CVE | none |
| CVE match | novel |
Summary
The header sanity check validates only hdr_size bounds and the hdr_crc_self CRC. The spec-mandated signature ("EFI PART"), hdr_revision, hdr_lba_self==1, and hdr_crc_table (CRC32 over the partition-entry array) are never checked: hdr_crc_table is not read anywhere in the file, so the 16KB entry array consumed at :186-221 is taken with zero integrity verification. Any block whose first hdr_size bytes CRC to the stored value is parsed as a GPT. Under the crafted-media threat model the attacker controls the table bytes anyway, so CRC checks add no security boundary β spec-compliance/ robustness hardening gap; all consumed fields are independently bounds-checked, no privilege or memory-safety impact. Observed incidentally during DF-2963 verification (variant image with wrong hdr_crc_table/garbage hdr_sig still probes identically). Fix: require GPT_HDR_SIG + validate the table CRC (row diff).
Timeline
- 2026-09-02 Discovered during pass-2 audit of subr_diskgpt.c (GLM 5.3).
Discussion (0)
PoC verification
Evidence pack
findings/poc/DF-2964 Β· 10 files| File | Type | Description | Size | |
|---|---|---|---|---|
| README.md | β | 776 B | β raw | |
| VERDICT.md | β | 935 B | β raw | |
| build.sh | β | 79 B | view raw | |
| env.txt | β | 509 B | view raw | |
| fix.diff | β | 1017 B | view raw | |
| gen_gpt_corrupt.c | β | 4.6 KB | view raw | |
| manifest.json | β | 621 B | view raw | |
| run.log | β | 440 B | view raw | |
| run.sh | β | 158 B | view raw | |
| verdict.json | β | 2.2 KB | view raw |
DF-2964 β gptinit skips signature + table CRC (Info-tier hardening verification)
What
gptinit skips signature + table CRC
Build
cc -Wall -O2 -o gen_gpt_corrupt gen_gpt_corrupt.c
Run
./gen_gpt_corrupt && vnconfig -c vn0 /tmp/df2964.img; ls /dev/vn0*; dmesg | tail; vnconfig -u vn0
Expected
baseline (stock kernel): see verdict below fix kernel (all-41-fixes build): the bad behavior is gone
Files
README.md VERDICT.md build.sh env.txt fix.diff gen_gpt_corrupt.c manifest.json run.log run.sh verdict.json
Shared harness: h41.c (combined KLD, sysctl debug.h41.cmd=N driven).
Full batch context: the fix kernel contains all 41 hardening fixes of
this batch compiled together (build RC=0) and passed the complete A/B
suite plus a clean reboot.
DF-2964 β VERDICT
status: reproduced | reproduced: 1 | impact: none | confidence: certain
Mechanically reproduced as root on the stock guest: a GPT header with signature 'XXNOTGPT' (not 'EFI PART'), wrong hdr_crc_table (0xDEADBEEF) but a correct hdr_crc_self was fully parsed as GPT - /dev/vn0s0 was created from entry 0 and dmesg showed the kernel walking all 128 entries (subr_diskgpt.c validates only hdr_size bounds and hdr_crc_self at :112-125; hdr_sig/hdr_revision/hdr_crc_table are never read - rg confirms zero references). Under the crafted-media threat model the attacker controls the table bytes anyway, so this is spec-compliance/robustness hardening; all consumed fields are independently bounds-checked. On the fix kernel the same image is rejected: 'disk: Wrong GPT signature', no slice devices.
Baseline vs fix kernel
baseline: see verdict above / run log fix: behavior changed as designed (see verdict)
Fix verification
fixedA/B: baseline accepts garbage-signature header; fix kernel requires the EFI PART signature and validates the table CRC.
Confirmed kernel references
Detail
Evidence (decisive lines)
run.log baseline: slices created from garbage-signature GPT; fix kernel: disk: Wrong GPT signature + no vn0s0
PoC changes
gen_gpt_corrupt.c derived from the DF-2963 rig (same CRC helpers) with corrupted sig + table CRC
Verified recommended fix
Require the GPT_HDR_SIG signature and validate hdr_crc_table over the entry array
Verdict
Mechanically reproduced as root on the stock guest: a GPT header with signature XXNOTGPT (not EFI PART), wrong hdr_crc_table (0xDEADBEEF) but a correct hdr_crc_self was fully parsed as GPT - /dev/vn0s0 was created from entry 0 and dmesg showed the kernel walking all 128 entries (subr_diskgpt.c validates only hdr_size bounds and hdr_crc_self at :112-125; hdr_sig/hdr_revision/hdr_crc_table are never read - rg confirms zero references). Under the crafted-media threat model the attacker controls the table bytes anyway, so this is spec-compliance/robustness hardening; all consumed fields are independently bounds-checked. On the fix kernel the same image is rejected: disk: Wrong GPT signature, no slice devices.
No comments yet.