Uninitialized kernel stack memory leaked via acl_get_file/acl_get_fd
Summary
vacl_get_acl declares struct acl inkernelacl on stack without zeroing(:92). VOP_GETACL writes acl_cnt entries. copyout(:99) copies ENTIRE struct including entries [acl_cnt..31] uninitialized. Latent: no in-tree FS implements VOP_GETACL (vfs_default.c:89 vop_eopnotsupp). Live immediately if ACL-capable FS added.
Discussion (0)
PoC verification
Evidence pack
findings/poc/DF-0185 Β· 9 files| File | Type | Description | Size | |
|---|---|---|---|---|
| acl_leak.c | trigger-source | syscall-based __acl_get_file probe | 2.1 KB | view raw |
| build.sh | build-script | cc -O2 -Wall | 155 B | view raw |
| run.sh | run-script | runs acl_leak | 49 B | view raw |
| VERDICT.md | verdict | latent-pattern narrative | 2.1 KB | β raw |
| fix.diff | suggested-fix | bzero(&inkernelacl, ...) before VOP_GETACL | 532 B | view raw |
| README.md | readme | human-facing summary | 850 B | β raw |
| env.txt | environment | guest uname, modules, HW-gate note | 190 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-0185 β uninitialized kernel stack leak via vacl_get_acl (LATENT)
Summary
vacl_get_acl (kern_acl.c:88) declares struct acl inkernelacl on the
stack without zeroing it; a future ACL-capable filesystem's VOP_GETACL
would leave entries [acl_cnt..31] uninitialized, and the copyout at
:99 leaks the whole struct to userspace.
Status
LATENT on master: no in-tree FS implements VOP_GETACL
(sys/kern/vfs_default.c:89 returns EOPNOTSUPP).
Build / Run
./build.sh && ./run.sh
Expected: __acl_get_file returns EOPNOTSUPP; leak path not reached.
Fix
fix.diff: bzero(&inkernelacl, sizeof(inkernelacl)) before VOP_GETACL.
Validated as defense-in-depth (no behavioral change).
Files
acl_leak.cβ__acl_get_filesyscall probe.fix.diffβ zero the struct.VERDICT.mdβ latent-pattern narrative.
DF-0185 β Uninitialized kernel stack leak via vacl_get_acl (LATENT)
Verdict: LATENT β bug confirmed by code inspection; copyout path
unreachable on this kernel because no in-tree FS implements VOP_GETACL. Fix VALIDATED as defense-in-depth.
Mechanism
vacl_get_acl (sys/kern/kern_acl.c:88-101) declares
struct acl inkernelacl; /* :92 -- NOT zeroed */
...
error = VOP_GETACL(vp, type, &inkernelacl, ucred);
if (error == 0)
error = copyout(&inkernelacl, aclp, sizeof(struct acl)); /* :99 */
struct acl contains an array acl_entry acl_entry[ACL_MAX_ENTRIES]
(32 entries). A correctly-implemented VOP_GETACL writes only the
first acl_cnt entries; entries [acl_cnt..31] remain uninitialized
kernel stack and are leaked to userspace by the full-struct copyout at
:99.
Latent on this kernel
No in-tree filesystem overrides VOP_GETACL:
$ grep -rn '\.vop_getacl\s*=' sys/vfs sys/kern sys/kern/vfs_default.c:89: .vop_getacl = (void *)vop_eopnotsupp,
The default returns EOPNOTSUPP, so the if (error == 0) copyout(...)
guard at kern_acl.c:98 is never taken. The bug becomes live the moment
an ACL-capable filesystem is added.
Reproduction (latent state demonstrated)
$ ./acl_leak
DF-0185: __acl_get_file(/etc/passwd, ACL_TYPE_ACCESS) = -1 errno=45 (Operation not supported)
DF-0185: __acl_get_file(/tmp, ACL_TYPE_DEFAULT) = -1 errno=45 (Operation not supported)
DF-0185: VOP_GETACL returned EOPNOTSUPP (vfs_default.c:89) --
copyout at kern_acl.c:99 NOT reached; leak is LATENT.
Fix is still warranted (zero `inkernelacl` before the call).
Fix (validated defense-in-depth)
fix.diff adds bzero(&inkernelacl, sizeof(inkernelacl)) before the
VOP_GETACL call, matching what every well-audited copyout-style
syscall should do. On the patched kernel (#1, sha256
bb88f4411402ab5bf93e4e4f51f98c54e7017c2f1b2c0c94a6b17ff697cfcb5a)
the behavior is unchanged (still EOPNOTSUPP) but the latent leak is
closed.
Note
This is the canonical "latent" pattern (cf. DF-0594, DF-0616, DF-0281): the bug exists in code, the trigger path is dead in master, the fix is trivial and warranted as defense-in-depth.
Fix verification
fixedvalidated
see evidence pack
Confirmed kernel references
β
Detail
Exploit chain
none
Evidence (decisive lines)
β
Verdict
Latent. vacl_get_acl uninitialized struct acl copyout path. No FS implements VOP_GETACL on master -> EOPNOTSUPP. Fix: bzero.
No comments yet.