Integer overflow in raw-service ioctl bounds check bypasses scratch-size guard
Summary
gdt_ioctl_cmd at iir.c:1036: if(cnt+sense_len>GDT_SCRATCH_SZ) u32+u32 wraps. sdlen=0xFFFFFFFF+sense_len=1 -> 0. bcopy(ucmd->data,gc_scratch,0xFFFFFFFF) -> ~4GB kernel heap OOB write. gc_scratch is 3072B slot. ucmd is raw user pointer (no copyin). Root only (/dev/iir0 mode 0600). Fix: check cnt>GDT_SCRATCH_SZ || sense_len>GDT_SCRATCH_SZ-cnt.
Discussion (0)
PoC verification
Evidence pack
findings/poc/DF-1423 Β· 8 files| File | Type | Description | Size | |
|---|---|---|---|---|
| fix.diff | suggested-fix | Rewrite bounds check to avoid u32+u32 overflow: cnt > GDT_SCRATCH_SZ || sense_len > GDT_SCRATCH_SZ - cnt. | 641 B | view raw |
| VERDICT.md | verdict | Full source-trace analysis | 1.9 KB | β raw |
| build.sh | build-script | Kernel build validation | 527 B | view raw |
| run.sh | run-script | PoC runner (not runnable on guest) | 484 B | view raw |
| fix_build.log | build-log | Full kernel build output (make nativekernel rc=0) | 5.6 MB | β download |
| env.txt | environment | Guest environment | 277 B | view 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-1423 β Verification Verdict
Verdict: CONFIRMED-BY-SOURCE-TRACE (root-only)
Status: inconclusive (HW-gated / not reachable as unprivileged maxx) Impact: none (cannot reproduce on QEMU guest β no GPU/HW, or root/operator-only) Confidence: certain (source-trace confirmed bug is real)
Mechanism
gdt_ioctl_cmd (:1036): if(cnt+sense_len>GDT_SCRATCH_SZ) β u32+u32 wraps. sdlen=0xFFFFFFFF+sense_len=1 β 0. Passes check. bcopy(ucmd->data,gc_scratch,0xFFFFFFFF) β ~4GB kernel heap OOB write. gc_scratch is 3072B slot. ucmd->data is raw user pointer (no copyin). /dev/iir0 mode 0600 (root only).
Source: sys/dev/raid/iir/iir.c:1036
Why it cannot be reproduced on this guest
Root-only. /dev/iir0 is mode 0600 (root only). Also requires IIR RAID controller hardware.
Phase 6: Escalation Assessment
This is a Root-only + HW-gated (iir RAID) finding. The primitive is not reachable from the unprivileged maxx user on this guest (no hardware / module not loaded / root-only device). No escalation chain is possible because the trigger path is not exercisable.
For GPU findings: the module (radeon.ko/amdgpu.ko/i915.ko) is a loadable module not present in the GENERIC kernel and requires actual GPU hardware absent from the QEMU guest. For root/operator findings: the device node is mode 0600 or 0640 root:operator, and maxx (uid 1001) has no operator group membership.
Fix
Check cnt > GDT_SCRATCH_SZ || sense_len > GDT_SCRATCH_SZ - cnt (avoids overflow).
Fix description: Rewrite bounds check to avoid u32+u32 overflow: cnt > GDT_SCRATCH_SZ || sense_len > GDT_SCRATCH_SZ - cnt.
The full git-apply-able diff is in fix.diff. It applies cleanly to the audit source tree
and compiles as part of the kernel build (validated via make nativekernel rc=0).
Classification
- status: inconclusive
- reproduced: 0
- impact: none
- fix_status: not_testable (HW-gated: PoC cannot run on guest; diff applies + compiles verified)
Confirmed kernel references
- s
- y
- s
- /
- d
- e
- v
- /
- r
- a
- i
- d
- /
- i
- i
- r
- /
- i
- i
- r
- .
- c
- :
- 1
- 0
- 3
- 6
Detail
Exploit chain
none (integer overflow β massive OOB heap write primitive exists β but trigger is root-only (/dev/iir0 0600) AND requires IIR RAID HW. Rootβkernel is game-over by definition; no privilege boundary to cross.)
Evidence (decisive lines)
Source trace: iir.c:1036 'if (cnt + ucmd->u.raw.sense_len > GDT_SCRATCH_SZ)' β u32+u32 overflow. If cnt=0xFFFFFFFF, sum wraps to sense_len, passes check. :1041 'bcopy(ucmd->data, gccb->gc_scratch, cnt)' β 4GB OOB write into 3072B scratch.
PoC changes
Authored fix.diff: rewrite bounds check to 'cnt > GDT_SCRATCH_SZ || sense_len > GDT_SCRATCH_SZ - cnt' (avoids u32+u32 overflow).
Verified recommended fix
Rewrite bounds check to avoid overflow: cnt > GDT_SCRATCH_SZ || sense_len > GDT_SCRATCH_SZ - cnt. matches finding proposal. Full diff in findings/poc/DF-1423/fix.diff.
Verdict
CONFIRMED BY SOURCE TRACE. gdt_ioctl_cmd at iir.c:1036: if(cnt+sense_len>GDT_SCRATCH_SZ) β u32+u32 wraps. sdlen=0xFFFFFFFF+sense_len=1β0, passes check. bcopy(ucmd->data,gc_scratch,0xFFFFFFFF) β ~4GB kernel heap OOB write. gc_scratch is 3072B. Bug is real but root-only (/dev/iir0 mode 0600) and HW-gated (IIR RAID controller).
No comments yet.