vfs_unmount tears down quota accounting (VFS_ACDONE) before the filesystem unmount commits β failed unmounts leave a live mount with accounting already 'done'
| Field | Value |
|---|---|
| ID | DF-2954 |
| Status | new |
| Severity | Info |
| CVSS 3.1 | CVSS:3.1/AV:L/AC:H/PR:L/UI:N/S:U/C:N/I:N/A:N |
| CWE | CWE-459 / CWE-1264 (latent CWE-416) |
| File | sys/kern/vfs_vfsops.c |
| Lines | 131-134 |
| Area | kern/vfs |
| Confidence | certain |
| Discovered | 2026-09-02 |
| Pass | 2 (GLM 5.3 second pass) |
| Bucket | memcorrupt |
| Reported | pending |
| Known CVE | none |
| CVE match | novel |
Summary
vfs_unmount() dispatches VFS_ACDONE(mp) at :131 BEFORE calling mp->mnt_op->vfs_unmount (:133). dounmount() restores and keeps the mount alive whenever the filesystem's unmount op refuses (EBUSY etc.) β yet the accounting teardown has already executed on the surviving mount; retried unmounts re-run teardown each time. Impact is currently nil because the only registered acdone implementation calls vq_done() which is an explicit TODO no-op. It becomes a use-after-free family bug the moment that TODO is implemented (freeing the RB-tree nodes): mnt_op->vfs_account is never cleared (vfs_quota.c:133), so post-failure VFS_ACCOUNT calls keep dispatching vfs_stdaccount into freed/invalidated trees on a mount the admin believes healthy β and quota enforcement state is silently discarded on any failed unmount. Dormant on stock configs (vfs_quota_enabled defaults to 0). Fix: move VFS_ACDONE to the success path alongside vn_syncer_thr_stop (row diff).
Timeline
- 2026-09-02 Discovered during pass-2 audit of vfs_vfsops.c (GLM 5.3).
No comments yet.