DF-0847 / quota_unreachable.c
/* * DF-0847 โ default-kernel reachability probe. * * The finding cites an unlocked manipulation of the global UFS dquot hash * list and free list in ufs_dqget()/ufs_dqrele()/ufs_dqflush() (ufs_quota.c). * This probe demonstrates that on the stock X86_64_GENERIC kernel the entire * quota code path is DEAD: * * 1. ufs_quotactl() returns EOPNOTSUPP unless the kernel was built with * `options QUOTA` (sys/vfs/ufs/ufs_vfsops.c:77-78). X86_64_GENERIC * does NOT enable `options QUOTA` (0 occurrences in sys/config/). * 2. Every in-kernel caller of ufs_getinoquota()/ufs_chkdq()/ufs_chkiq()/ * ufs_dqrele() โ the only paths that reach ufs_dqget() โ is wrapped in * `#ifdef QUOTA` (ffs_alloc.c, ffs_inode.c, ufs_vnops.c, ufs_inode.c, * ffs_balloc.c). Compiled out on a non-QUOTA kernel. * * Consequence: ufs_dqget() exists in the binary (ufs_quota.c is * `optional ffs`, not `optional quota` โ confirmed via sys/conf/files:1994) * but has ZERO callers and is unreachable. The unlocked list manipulation * (lines 769-866 of ufs_quota.c) can never execute on the default kernel. * * This program calls quotactl(Q_QUOTAON) against a UFS mount and prints the * errno. On the default kernel it is EOPNOTSUPP (path dead). On a kernel * built with `options QUOTA` it succeeds (path live). * * Build: cc -o quota_unreachable quota_unreachable.c * Run: ./quota_unreachable /mnt/q (path of a UFS mount point) */ #include <stdio.h> #include <errno.h> #include <string.h> #include <unistd.h> #include <sys/syscall.h> /* ufs quota commands โ from vfs/ufs/quota.h */ #define Q_QUOTAON 0x0100 #define Q_QUOTAOFF 0x0200 #define USRQUOTA 0 #define SUBCMDMASK 0x00ff #define SUBCMDSHIFT 8 int main(int argc, char **argv) { const char *path = (argc > 1) ? argv[1] : "/mnt/q"; const char *qfile = (argc > 2) ? argv[2] : "/mnt/q/quota.user"; /* cmd is packed as (subcmd << 8) | type per ufs_quotactl() */ int cmd_on = (Q_QUOTAON << SUBCMDSHIFT) | USRQUOTA; int cmd_off = (Q_QUOTAOFF << SUBCMDSHIFT) | USRQUOTA; long rc; errno = 0; /* syscall(SYS_quotactl, path, cmd, uid, arg) โ uid=0 (root's quota) */ rc = syscall(SYS_quotactl, path, cmd_on, 0, (char *)qfile); printf("quotactl(Q_QUOTAON, \"%s\", uid=0, \"%s\") -> rc=%ld errno=%d (%s)\n", path, qfile, rc, errno, strerror(errno)); if (rc == 0) { printf("PATH LIVE: kernel has `options QUOTA`; the buggy code is reachable.\n"); printf(" (turning quotas off again to leave the mount clean.)\n"); syscall(SYS_quotactl, path, cmd_off, 0, NULL); return 0; } if (errno == EOPNOTSUPP) { printf("PATH DEAD: EOPNOTSUPP => ufs_quotactl() #ifndef-QUOTA early-return at\n"); printf(" sys/vfs/ufs/ufs_vfsops.c:77-78. `options QUOTA` is absent from\n"); printf(" X86_64_GENERIC, so every caller of ufs_dqget() is compiled out.\n"); printf(" => DF-0847 unreachable on this (default) kernel.\n"); return 0; } printf("Unexpected errno=%d (%s) โ see VERDICT.md.\n", errno, strerror(errno)); return 0; } |