DIOCGKERNELDUMP handled with no privilege check or FWRITE gate (diskioctl β disk_dumpconf β set_dumper)
| Field | Value |
|---|---|
| ID | DF-2743 |
| Status | new |
| Severity | Info |
| CVSS 3.1 | CVSS:3.1/AV:L/AC:L/PR:H/UI:N/S:U/C:N/I:N/A:N |
| CWE | CWE-862 Missing Authorization |
| File | sys/kern/subr_disk.c |
| Lines | 1186-1189 (β :914-939 β kern_shutdown.c:949-961) |
| Area | kern |
| Confidence | certain |
| Discovered | 2026-08-30 |
| Pass | 2 (GLM 5.3 second pass) |
| Bucket | base:kern |
| Reported | pending |
| Known CVE | none |
| CVE match | novel |
Summary
diskioctl() intercepts DIOCGKERNELDUMP and passes *(u_int*)a_data
straight to disk_dumpconf() β set_dumper(); none of the three contains
any privilege check or FWRITE requirement (FreeBSD enforces
PRIV_VFS_KERNELDUMP at the same spot). Exercised live: the full
crash-dumper register/clear machinery is driven by the ioctl alone.
Practically unreachable below root-class credentials because
diskopen() requires SYSCAP_RESTRICTEDROOT (verified live) β filed as
hardening: the kernel should not rely on the open gate alone (devfs
rulesets, future gate relaxation, jailed contexts; combined with
DF-2744's underflow, dumping outside partition bounds).
Recommended fix
In diskioctl()'s DIOCGKERNELDUMP branch: require FWRITE on the fd and a privilege check (equivalent to FreeBSD's PRIV_VFS_KERNELDUMP) before calling disk_dumpconf().
Timeline
- 2026-08-30 Discovered during pass-2 audit of subr_disk.c (GLM 5.3).
Discussion (0)
PoC verification
Evidence pack
findings/poc/DF-2743 Β· 7 files| File | Type | Description | Size | |
|---|---|---|---|---|
| poc2743.c | β | 1.8 KB | view raw | |
| p2743b.c | β | 709 B | view raw | |
| README.md | β | 1.4 KB | β raw | |
| VERDICT.md | β | 1.4 KB | β raw | |
| build.sh | β | 62 B | view raw | |
| run.log | β | 311 B | view raw | |
| env.txt | β | 392 B | view raw |
DF-2743 β DIOCGKERNELDUMP has no privilege check on the ioctl path
Impact
sys/kern/subr_disk.c:1186-1189 forwards DIOCGKERNELDUMP straight to
disk_dumpconf() -> set_dumper() (sys/kern/kern_shutdown.c:949-961).
Neither has a priv_check / caps_priv_check / FWRITE gate. Compare FreeBSD,
which requires PRIV_VFS_KERNELDUMP in its DIOCGKERNELDUMP handler.
Practical reachability today: opening any cooked disk node goes through
diskopen() which requires SYSCAP_RESTRICTEDROOT (subr_disk.c:1072), so
the ioctl is presently reachable only by root-class credentials (verified:
an operator-group user gets EPERM at open, before the ioctl). The missing
check is therefore defense-in-depth / hardening, plus a correctness gap if
the open gate is ever relaxed or devices exposed via devfs rulesets.
Reproduce (guest)
cc -O -o poc2743 poc2743.c
./poc2743 /dev/vn0 # as root: disable->OK enable->OK enable2->EBUSY
su -m op1 -c "/home/op1/poc2743 /dev/vn0" # op1 in group operator:
# open: Operation not permitted
# (diskopen SYSCAP_RESTRICTEDROOT gate)
Observed
root: disable -> 0; enable -> 0 (dumper registered on vn0); enable again -> EBUSY (set_dumper's dumper!=NULL path) β the whole register/clear machinery is driven with no privilege query anywhere past the open gate.
DF-2743 VERDICT β DIOCGKERNELDUMP without privilege check
Status: not_reproduced (as an unprivileged action). Impact: none on default config. Confidence: certain (about the missing check, by inspection + live exercise of the ungated path as root).
- The ioctl path is provably check-free:
diskioctl()intercepts DIOCGKERNELDUMP (sys/kern/subr_disk.c:1186-1189) and callsdisk_dumpconf()(subr_disk.c:914-939) βset_dumper()(sys/kern/kern_shutdown.c:949-961); none of the three contains a priv_check/caps_priv_check/FWRITE gate (contrast FreeBSD geom_disk, which enforces PRIV_VFS_KERNELDUMP). - Live: as root the full register/clear machinery was driven through the ioctl alone β disableβ0, enableβ0, enable againβEBUSY (run.log).
- However an operator-group user (gid 5) cannot even open a cooked disk
node:
diskopen()requires SYSCAP_RESTRICTEDROOT (sys/kern/subr_disk.c:1070-1073); op1 got EPERM at open. On a default system the missing check is therefore unreachable below root-class credentials β filed as hardening (Info), still worth fixing upstream (defense in depth; devfs rulesets / future gate changes).
Suggested fix
In diskioctl()'s DIOCGKERNELDUMP branch, require both FWRITE on the fd
and a privilege check, e.g.
if (!(ap->a_fflag & FWRITE)) return (EBADF);
error = priv_check(curthread, PRIV_VFS_KERNELDUMP); (or a suitable
caps_priv_check) before calling disk_dumpconf().
Fix verification
not_testableConfirmed kernel references
Detail
Evidence (decisive lines)
['run.log: root sequence disable/enable/enable2-EBUSY; operator user blocked at open with EPERM', 'VERDICT.md: static trace of the three ungated hops']
PoC changes
written from scratch; added root-side sequence binary p2743b.c
Verified recommended fix
Require FWRITE plus a privilege check (priv_check/caps_priv_check) in diskioctl()'s DIOCGKERNELDUMP branch before disk_dumpconf().
Verdict
The DIOCGKERNELDUMP path is provably check-free: diskioctl() (subr_disk.c:1186-1189) -> disk_dumpconf() (subr_disk.c:914-939) -> set_dumper() (kern_shutdown.c:949-961) contain no priv_check/caps_priv_check/FWRITE gate (FreeBSD enforces PRIV_VFS_KERNELDUMP at the same spot). Exercised live as root: disable->0, enable->0, enable again->EBUSY, i.e. the crash-dumper register/clear machinery is driven by the ioctl alone. However an operator-group user cannot reach the ioctl at all: diskopen() requires SYSCAP_RESTRICTEDROOT (subr_disk.c:1070-1073) and op1 got EPERM at open. On default configs the missing check is therefore unexploitable below root-class credentials -> filed as Info hardening (defense-in-depth; devfs rulesets/future gate relaxation).
No comments yet.