β¬’ DragonFlyBSD Kernel Audit
← triage Β· dashboard
DF-1434

CDRIOCSETBLOCKSIZE with arg=0 causes kernel divide-by-zero panic via rounddown()

Summary

acd_ioctl CDRIOCSETBLOCKSIZE at atapi-cd.c:723-726: cdp->block_size=*(int*)data, no validation. acd_set_ioparm :951: rounddown(iomax,block_size) = (iomax/block_size)*block_size. block_size=0 -> div-by-zero #DE panic. No caps_priv_check (unlike CDIOCRESET). /dev/acdN 0640 root:operator. Operator group. Fix: reject bs<=0.

Discussion (0)

No comments yet.

PoC verification

Evidence pack

findings/poc/DF-1434 Β· 8 files
FileTypeDescriptionSize
fix.diff suggested-fix Add `if (*(int*)ap->a_data <= 0) { error = EINVAL; break; }` guard in CDRIOCSETBLOCKSIZE. 349 B view raw
VERDICT.md verdict Full source-trace analysis 2.0 KB ↓ raw
build.sh build-script Kernel build validation 533 B view raw
run.sh run-script PoC runner (not runnable on guest) 538 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
VERDICT.md verdict Full source-trace analysis
↓ download raw

DF-1434 β€” Verification Verdict

Verdict: CONFIRMED-BY-SOURCE-TRACE (operator-only, maxx not in operator)

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

acd_ioctl CDRIOCSETBLOCKSIZE (:723-726): cdp->block_size=(int)data, no validation. acd_set_ioparm (:951): rounddown(iomax,block_size) = (iomax/block_size)*block_size. block_size=0 β†’ div-by-zero #DE panic. No caps_priv_check (unlike CDIOCRESET at :360 which has one). /dev/acdN is 0640 root:operator.

Source: sys/dev/disk/nata/atapi-cd.c:723-726, 951

Why it cannot be reproduced on this guest

Operator-group only. /dev/acd0 is 0640 root:operator. maxx (uid 1001) is NOT in operator group. Cannot open the device.

Phase 6: Escalation Assessment

This is a Operator-only (NATA ATAPI CD) 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

Reject block_size <= 0 in CDRIOCSETBLOCKSIZE handler with EINVAL.

Fix description: Add if (*(int*)ap->a_data <= 0) { error = EINVAL; break; } guard in CDRIOCSETBLOCKSIZE.

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

Detail

Exploit chain

none (div-by-zero DoS β€” no write primitive. Device is operator-group-only; maxx not in operator. Cannot even open /dev/acd0. The threat model is an operator-group member.)

Evidence (decisive lines)

Source trace: atapi-cd.c:724 'cdp->block_size = *(int *)ap->a_data' β€” no validation. :951 'rounddown(cdp->iomax, cdp->block_size)' β€” div-by-zero if block_size=0. Guest: ls -la /dev/acd0 β†’ 'crw-r----- root operator'. id maxx β†’ 'groups=1001(maxx)' β€” NOT in operator.

PoC changes

Authored fix.diff: reject block_size <= 0 in CDRIOCSETBLOCKSIZE handler with EINVAL.

Verified recommended fix

Add 'if ((int)ap->a_data <= 0) { error = EINVAL; break; }' guard in CDRIOCSETBLOCKSIZE. matches finding proposal. Full diff in findings/poc/DF-1434/fix.diff.

Verdict

CONFIRMED BY SOURCE TRACE. acd_ioctl CDRIOCSETBLOCKSIZE (:723-726): cdp->block_size=(int)data, no validation. acd_set_ioparm (:951): rounddown(iomax,block_size). block_size=0 β†’ div-by-zero #DE panic. No caps_priv_check (unlike CDIOCRESET :360). Bug is real. /dev/acd0 EXISTS on guest (natapicd in GENERIC) but is 0640 root:operator β€” maxx (uid 1001) is NOT in operator group. Cannot open device.