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

ufs_quotactl Q_GETQUOTA self-authorization is quota-type-blind: uid==cr_ruid satisfies the check for GRPQUOTA too, letting any user read the group-quota record for gid numerically equal to their uid

Summary

The unprivileged path for Q_GETQUOTA compares only uid == cred->cr_ruid (:119-124) regardless of whether type is USRQUOTA or GRPQUOTA. A user may quotactl(QCMD(Q_GETQUOTA, GRPQUOTA), <own ruid>) and read the usage/limits of group <ruid> - on systems where per-user groups do not alias uid==gid this discloses another entity's quota record. Inherited 4.4BSD behavior; modern FreeBSD uses a proper priv_check for non-self targets. Marginal info disclosure; no write path (Q_SETQUOTA/Q_SETUSE correctly gated). Fix: USRQUOTA requires id==cr_ruid, GRPQUOTA requires groupmember(id, cred). [VERIFIED pass2: type-blind Q_GETQUOTA self-check confirmed; stock has QUOTA compiled out EOPNOTSUPP live; fixed semantics verified on the QUOTA kernel non-member EPERM member allowed]

Discussion (0)

No comments yet.

PoC verification

Evidence pack

findings/poc/DF-3243 Β· 8 files
FileTypeDescriptionSize
README.md β€” 235 B ↓ raw
df3243.c β€” 1.5 KB view raw
fix.diff β€” 565 B view raw
manifest.json β€” 439 B view raw
mntquota.c β€” 543 B view raw
qon.c β€” 629 B view raw
run.log β€” 1.5 KB view raw
verdict.json β€” 2.2 KB view raw

DF-3243 evidence pack

What

ufs_quotactl Q_GETQUOTA self-authorization is quota-type-blind

Verdict

status=not_reproduced impact=none confidence=certain

See VERDICT.md for the full narrative and fix.diff for the verified fix.

Fix verification

fixed

verified on the QUOTA-enabled F40FIX kernel: t2 (uid 4242, NOT a member of group 4242) -> EPERM for QCMD(Q_GETQUOTA,GRPQUOTA,4242); maxx (member of 1001) still reads his own group record. Type-aware self-check behaves exactly as designed. (Bug-side live demo impossible on the stock kernel: options QUOTA is compiled out there - EOPNOTSUPP confirmed live.)

↓ fix.diffper-fix-DF-3243

Confirmed kernel references

Detail

Evidence (decisive lines)

VERDICT.md with path:line citations; run.log where a live demo exists; fix.diff

PoC changes

probe extended with a root Q_SETQUOTA installer; mount_ufs has no userland quota option string so MNT_QUOTA was set via direct mount(2)

Verified recommended fix

USRQUOTA requires id==cr_ruid, GRPQUOTA requires groupmember(id, cred)

Verdict

Runtime reproduction impossible on the stock kernel - UFS quotas are compiled out (#ifndef QUOTA -> EOPNOTSUPP at ufs_vfsops.c:77; confirmed live: Q_QUOTAON returns EOPNOTSUPP as root on a mounted UFS image), and an unfixed-QUOTA comparison kernel was judged disproportionate for this Info-tier batch. Line-accurate confirmation: the unprivileged Q_GETQUOTA path compares only uid == cred->cr_ruid (ufs_vfsops.c:119-124) regardless of quota type, so any user can read the group-quota record for gid == their uid (group membership never consulted). The F40FIX kernel enables options QUOTA with the fix applied: live post-fix check shows user t2 (uid 4242, NOT a member of group 4242) gets EPERM for QCMD(Q_GETQUOTA,GRPQUOTA,4242) while maxx (member of 1001) reads his own group record. Fix = type-aware self-check with groupmember().