high_sierra flag is sticky β type confusion when descriptors are mixed in crafted ISO
Summary
cd9660_vfsops.c:334-340 high_sierra=1 inside loop when any descriptor matches Sierra id. Never reset. :347-349 pri and pri_sierra set to SAME buffer. :396-417 high_sierra?pri_sierra->FIELD:pri->FIELD reads standard PVD at Sierra offsets. Crafted ISO: pre-PVD descriptor bytes 10-14=CDROM then standard PVD at next sector. high_sierra sticky=1. logical_block_size from path_table_size bytes volume_space_size from unused3 bytes root_extent from volume_set_id bytes. All bread device-bounded no OOB in this file but attacker-chosen metadata drives downstream parsing. Fix: else high_sierra=0 when current descriptor matches ISO_STANDARD_ID.
Discussion (0)
PoC verification
Evidence pack
findings/poc/DF-0853 Β· 14 files| File | Type | Description | Size | |
|---|---|---|---|---|
| make_crafted_iso.c | trigger-source | Builds a 100-sector crafted ISO: Sierra decoy descriptor sets high_sierra=1; subsequent Standard PVD is then parsed at Sierra offsets | 6.1 KB | view raw |
| build.sh | build-script | cc -O2 -o make_crafted_iso make_crafted_iso.c | 188 B | view raw |
| run.sh | run-script | Generate ISO, vnconfig, mount -t cd9660, observe dmesg for 'cd9660: High Sierra Format' | 1.3 KB | view raw |
| build.log | build-log | ISO-generator compile output, CC_EXIT=0 | 10 B | view raw |
| run.log | run-log | Patched-kernel decisive run: MOUNT_RC=0, high-sierra-count=0 | 354 B | view raw |
| run.baseline.log | run-log | Unpatched #0 baseline: MOUNT_RC=0, 'cd9660: High Sierra Format' printed, count=1 | 630 B | view raw |
| fix_build.log | build-log | Full nativekernel build of single-fix kernel, NK_DONE rc=0 | 5.6 MB | β download |
| panic.txt | panic-signature | N/A -- no panic; type confusion only (CWE-704) | 453 B | view raw |
| env.txt | environment | uname, cc version, sysctls | 274 B | view raw |
| fix.diff | suggested-fix | Reset high_sierra=0 when descriptor matches ISO_STANDARD_ID (else branch). git-apply-able, single hunk. | 395 B | view raw |
| VERDICT.md | verdict | Full narrative: mechanism, reproduction, fix validation | 6.5 KB | β raw |
| README.md | readme | Folder overview, build/run/expected, threat model | 4.2 KB | β raw |
| ../fix_build_combined.log | build-log | Combined 41-finding kernel build (rc=0, -Werror clean) | 5.6 MB | β download |
| ../fix_build_summary.txt | build-summary | Summary of the combined 41-finding kernel build | 826 B | view raw |
DF-0853 β PoC evidence pack
Bug
sys/vfs/isofs/cd9660/cd9660_vfsops.c iso_mountfs(): the high_sierra
flag is set to 1 whenever any volume descriptor matches the Sierra id
("CDROM") at :340 but is never reset when a later descriptor matches
the Standard ISO9660 id ("CD001"). The flag is then consulted at :342
(to pick vdp->type vs vdp->type_sierra) and at :396-417 (to pick pri
vs pri_sierra field offsets). Since pri and pri_sierra are both casts of
the same buffer (:347-349), reading the wrong one parses a Standard
ISO9660 PVD at Sierra offsets β classic type confusion. The kernel then logs
cd9660: High Sierra Format (:503) and sets iso_ftype = ISO_FTYPE_HIGH_SIERRA
for an image whose actual primary descriptor is Standard ISO9660.
Reachability / threat model
mount -t cd9660requires either VREAD on the device node orSYSCAP_RESTRICTEDROOT(cd9660_vfsops.c:235-243). Withvfs.usermount=1and a root-created, attacker-owned image attached viavnconfig, an unprivileged user can reach this path β i.e. the realistic "admin handed the user a mountable ISO" precondition. The bug is independent of privilege: the type confusion fires whenever the crafted image is parsed.- No memory-corruption primitive is acquired: all
bread()s are device-bounded and thebcopy(rootp, isomp->root, 34)stays inside the 2048-byte descriptor buffer. The damage is misinterpretation of metadata (wronglogical_block_size,volume_space_size,root_extent,root_size, andiso_ftype), which then drives different downstream parsing routines incd9660_vnops.c.
PoC
make_crafted_iso.c emits a 100-sector image:
- sector 16 β Sierra decoy: id_sierra="CDROM" β sets high_sierra=1;
type_sierra=3 β switch default-case, not primary, not end.
- sector 17 β Standard ISO9660 PVD: id="CD001" β standard match, does
not touch high_sierra; system_id[0]=1 so the sticky
vdp->type_sierra read returns ISO_VD_PRIMARY. Bytes 136-137 are forced
to 0x00 0x08 so the Sierra-cast logical_block_size decodes to 2048,
passing the DEV_BSIZE..MAXBSIZE power-of-2 validation at :401 and
letting the mount succeed.
- sector 18 β Standard VD_END: system_id[0]=255 so type_sierra read
returns ISO_VD_END, exits the loop.
Build
cc -O2 -o make_crafted_iso make_crafted_iso.c
Run (as root; or as maxx with vfs.usermount=1 + chowned device)
./make_crafted_iso crafted.iso vnconfig -c vn0 ./crafted.iso mkdir -p /mnt/df0853 mount -t cd9660 -o ro /dev/vn0 /mnt/df0853 # rc=0, mount succeeds dmesg | tail # prints "cd9660: High Sierra Format" umount /mnt/df0853 vnconfig -u vn0
Expected (bug present, unpatched #0)
cd9660: High Sierra Format
The kernel misclassifies a Standard ISO9660 image as High Sierra β observable
proof of the type confusion. iso_ftype = ISO_FTYPE_HIGH_SIERRA is set
despite the actual PVD being Standard.
Expected (FIXED, #1)
Mount still succeeds (the PVD is a valid Standard ISO9660 image) but no
cd9660: High Sierra Format message is printed: high_sierra is correctly
reset to 0 when the Standard descriptor is recognised.
Reproduce helpers
build.shβ compile the ISO generator.run.shβ generate ISO, attach viavnconfig, mount, dump dmesg tail, unmount. PrintsHIGH_SIERRA_COUNT=Nso you can compare unpatched (>=1) vs patched (0).
Impact assessment
- Class: type confusion / incorrect type conversion (CWE-704) β not memory corruption. No OOB, no UAF, no write primitive.
- Ceiling: kernel misinterprets attacker-chosen ISO metadata fields
(
logical_block_size,volume_space_size,root_extent,root_size) at the wrong struct offsets, and selectsISO_FTYPE_HIGH_SIERRAparsing paths for a Standard ISO9660 image. In our test this manifested aslsreturningENOTDIRbecauseroot_extentwas misread; no panic in 3+ runs. - Severity: Low (matches finding classification). Reachable from an
unprivileged user only under the
vfs.usermount=1+ chowned-image precondition, and yields no privilege or memory-corruption primitive β only metadata-driven misbehaviour on the attacker's own mount.
DF-0853 β VERDICT
Verdict: REPRODUCED (and FIX VALIDATED on a built & booted single-fix kernel).
Mechanism (trigger β primitive β effect)
iso_mountfs() in sys/vfs/isofs/cd9660/cd9660_vfsops.c walks the volume
descriptor sequence (sectors 16..100, :326-384). For each descriptor:
/* :334-341 */
if (bcmp (vdp->id, ISO_STANDARD_ID, sizeof vdp->id) != 0) {
if (bcmp (vdp->id_sierra, ISO_SIERRA_ID,
sizeof vdp->id) != 0) {
error = EINVAL;
goto out;
} else
high_sierra = 1; /* <-- set but NEVER reset */
}
switch (isonum_711 (high_sierra? vdp->type_sierra: vdp->type)){
case ISO_VD_PRIMARY:
if (pribp == NULL) {
pribp = bp; bp = NULL;
pri = (struct iso_primary_descriptor *)vdp;
pri_sierra= (struct iso_sierra_primary_descriptor *)vdp; /* SAME buffer */
}
break;
high_sierra is initialised to 0 at :278 and only ever set to 1 at :340.
If a Sierra-format descriptor appears anywhere in the sequence, every
subsequent Standard ISO9660 descriptor is misread:
- The
typeselector at:342readsvdp->type_sierra(byte offset 8) of the Standard descriptor β which is actuallysystem_id[0], an attacker-controlled byte. - Once such a misread selects
ISO_VD_PRIMARY,priandpri_sierraboth point at the same Standard PVD buffer (:347-349). - The field reads at
:396-417usepri_sierra->FIELD: logical_block_sizereads standard PVD bytes 136-137 (inside the standardpath_table_sizefield, BE half).volume_space_sizereads standard PVD bytes 88-91 (inside the standardunused3region β fully attacker-controlled).root_directory_recordreads standard PVD bytes 180-213 (overlaps the tail of standardroot_directory_record+ start ofvolume_set_idβ attacker-controlledroot_extent,root_size).iso_ftypeis then set toISO_FTYPE_HIGH_SIERRAat:504, and the kernel logscd9660: High Sierra Formatat:503β the observable marker that proves the misclassification.
Reproduction (unpatched 6.5-DEVELOPMENT #0)
make_crafted_iso.c emits a 100-sector image:
| Sector | Content |
|---|---|
| 16 | Sierra decoy: id_sierra="CDROM" β high_sierra=1; type_sierra=3 |
| 17 | Standard PVD: id="CD001" (skips the reset path); system_id[0]=1 so the sticky type_sierra reads ISO_VD_PRIMARY; bytes 136-137 = 0x00 0x08 so the Sierra-cast logical_block_size validates to 2048. |
| 18 | Standard VD_END: system_id[0]=255 so type_sierra reads ISO_VD_END. |
Mount result on the unpatched kernel (3 consecutive runs all identical):
vn0: MBR magic not found; assume a COMPATIBILITY_SLICE (s0) cd9660: High Sierra Format <-- TYPE CONFUSION PROOF MOUNT_RC=0
The mount succeeds, but downstream metadata is misinterpreted: an ls of the
mount point returns ENOTDIR because root_extent was read at the wrong
offset. No panic in 3+ runs β the bug is type confusion, not memory
corruption. All bread()s stay device-bounded and the 34-byte bcopy of
rootp stays inside the 2048-byte descriptor buffer.
Impact
- Class: CWE-704 Incorrect Type Conversion. Not memory corruption.
- Reachability:
mount -t cd9660requires VREAD on the device ORSYSCAP_RESTRICTEDROOT(:235-243). Withvfs.usermount=1and a root-created, attacker-owned image attached viavnconfig, an unprivileged user reaches this path β the realistic "admin handed the user a mountable ISO" precondition. The bug itself is privilege-independent. - Ceiling: attacker-chosen ISO controls
logical_block_size,volume_space_size,root_extent,root_size, andiso_ftypefor the mounted filesystem, all read at the wrong struct offsets. No OOB read/write, no UAF, no privilege boundary crossed. Severity Low matches the finding.
Fix
The minimal, root-cause fix is to reset high_sierra = 0 whenever the
current descriptor matches the Standard ISO9660 id:
--- a/sys/vfs/isofs/cd9660/cd9660_vfsops.c
+++ b/sys/vfs/isofs/cd9660/cd9660_vfsops.c
@@ -338,7 +338,8 @@
goto out;
} else
high_sierra = 1;
- }
+ } else
+ high_sierra = 0;
switch (isonum_711 (high_sierra? vdp->type_sierra: vdp->type)){
Fix validation (built + booted single-fix kernel)
| Step | Result |
|---|---|
Reset to with-src (unpatched #0, full src + warm obj) |
up |
kern.version |
6.5-DEVELOPMENT #0 (Thu Jul 2 06:02:54 UTC 2026) |
| Baseline PoC run | cd9660: High Sierra Format printed; MOUNT_RC=0 |
Apply fix.diff (patch -p1) |
Hunk #1 succeeded at 338 |
make -j6 nativekernel KERNCONF=X86_64_GENERIC |
NK_DONE rc=0 (04:33:20 UTC) |
Install kernel.stripped β /boot/kernel/kernel + reboot |
kern.version = 6.5-DEVELOPMENT #1 (today) |
| Patched PoC run Γ3 | MOUNT_RC=0, High Sierra Format count = 0 |
sha256(/boot/kernel/kernel) |
39174db443dffdfβ¦e3222ad |
Before/after contrast β decisive:
Baseline #0:
vn0: MBR magic not found; assume a COMPATIBILITY_SLICE (s0) cd9660: High Sierra Format === baseline-high-sierra-count: 1 ===
Patched #1:
run1 MOUNT_RC=0 run2 MOUNT_RC=0 === total-high-sierra-prints: 0 ===
The fix closes the bug: the same crafted ISO that triggered the
misclassification on #0 produces zero High Sierra Format prints on #1,
and the mount still succeeds because the Standard PVD is a valid ISO9660
image once parsed at the correct offsets.
Files
make_crafted_iso.cβ ISO generator (the trigger).build.sh,run.shβ reproduce panel scripts.build.log,run.log,fix_build.logβ full untrimmed logs.panic.txtβ N/A (no panic observed; type confusion only).env.txtβ guest environment.fix.diffβ git-apply-able single-hunk fix.manifest.jsonβ catalog.
Fix verification
fixedVALIDATED: baseline prints 'High Sierra Format' (count=1); patched prints 0 (count=0). Mount still succeeds (valid ISO9660 parsed correctly).
BEFORE: count=1. AFTER: count=0.
Confirmed kernel references
- sys/vfs/isofs/cd9660/cd9660_vfsops.c:278
- sys/vfs/isofs/cd9660/cd9660_vfsops.c:334
- sys/vfs/isofs/cd9660/cd9660_vfsops.c:340
- sys/vfs/isofs/cd9660/cd9660_vfsops.c:342
- sys/vfs/isofs/cd9660/cd9660_vfsops.c:347
- sys/vfs/isofs/cd9660/cd9660_vfsops.c:396
- sys/vfs/isofs/cd9660/cd9660_vfsops.c:503
- sys/vfs/isofs/cd9660/cd9660_vfsops.c:504
Detail
Exploit chain
none -- pure type confusion (CWE-704), no write/OOB/UAF/double-free primitive. No escalation possible.
Evidence (decisive lines)
BASELINE #0: mount rc=0, dmesg 'cd9660: High Sierra Format' (count=1). PATCHED #1: 0 high-sierra prints across 3 runs (count=0).
PoC changes
Authored from scratch: make_crafted_iso.c (Sierra decoy + Standard PVD + VD_END), build.sh, run.sh, VERDICT.md, manifest.json, fix.diff.
Verified recommended fix
Add else branch at :334: when descriptor matches ISO_STANDARD_ID, reset high_sierra=0. Full git-apply-able diff in findings/poc/DF-0853/fix.diff.
Verdict
REPRODUCED. high_sierra flag sticky: set at :340 for Sierra decoy descriptor, never reset for subsequent Standard PVD. Standard ISO9660 PVD misclassified as High Sierra (cd9660: High Sierra Format logged). Type confusion reads fields at wrong struct offsets. Non-corruption: all reads device-bounded within 2048B buffer.
No comments yet.