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

SESIOC_GETOBJMAP leaks 2 bytes of uninitialized kernel stack per object via ses_object struct padding

Summary

In SESIOC_GETOBJMAP handler sesioctl declares local ses_object obj and populates only three named fields (obj_id subencid object_type) before copyout(&obj uobj sizeof(ses_object)). ses_object has 4-byte alignment sizeof==8 leaving 2 bytes of tail padding (offsets 6-7) never written. copyout copies full 8 bytes leaking 2 indeterminate kernel-stack bytes to userspace per iteration. Same 2 stack bytes leaked ses_nobjects times per call. Already tracked as DF-1013 pattern variant - sesopen gates SYSCAP_RESTRICTEDROOT so attacker must be root-equivalent. Impact: small kernel-stack info leak KASLR bypass building block. [VERIFIED pass2: reproduced - GETOBJMAP returns ff ff tail padding for all 24 objects matching primer vs 00 00 unprimed; 2 uninit stack bytes per object to userland; bzero fix-validated]

Discussion (0)

No comments yet.

PoC verification

Evidence pack

findings/poc/DF-2280 Β· 2 files
FileTypeDescriptionSize
run_baseline_ses80.log run-log ff padding x24 objects x4 iters vs 00 control 2.7 KB view raw
fix.diff suggested-fix bzero obj before the copyout loop 548 B view raw

Fix verification

fixed
↓ fix.diffper-fix-DF-2280

Confirmed kernel references

Detail

Exploit chain

root ioctl SESIOC_GETOBJMAP on /dev/sesN -> copyout of 8-byte ses_object with 2 unwritten padding bytes -> stale kernel-stack bytes to userland xN objects

Evidence (decisive lines)

run_baseline_ses80.log: iter rows padding ffff... vs 0000 control with identical real fields

PoC changes

Authored fake-enclosure config page (SES config parser reversed: Nsubenc/Ntypes/VEnclen/type-header layout) so the REAL ses driver attaches; primer via same-thread CAMIOCOMMAND

Verified recommended fix

bzero the ses_object local before the GETOBJMAP copyout loop

Verdict

SESIOC_GETOBJMAP on the real compiled scsi_ses.c (fake SES enclosure with 24 objects attached as /dev/ses0) returned 2 tail-padding bytes per ses_object copied straight from the calling thread kernel stack: with a prior CAMIOCOMMAND on the same thread every object returned ff ff padding (4 iterations), while the unprimed control returned 00 00 and the six real fields stayed deterministic -- proving the padding is uninitianialized kernel-stack disclosure (48 bytes/call at 24 objects). Fix (bzero the local before the loop) validated: padding always zero. Root-equivalent gate (sesopen SYSCAP_RESTRICTEDROOT, /dev/ses0 0600 root:operator): KASLR building block, Low severity confirmed. A/B: Fixed kernel: padding bytes always 00 00 under every primer (baseline ff ff): stack disclosure eliminated.