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)
PoC verification
Evidence pack
findings/poc/DF-3243 Β· 8 files| File | Type | Description | Size | |
|---|---|---|---|---|
| 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
fixedverified 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.)
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().
No comments yet.