CVE-2026-89671
largeLinux kernel nfsd NFSv3 SETACL flaw lets unauthenticated clients silently delete POSIX ACLs
The Linux kernel's NFS server (nfsd) mishandles NFSv3 SETACL requests: nfsd3_proc_setacl() calls set_posix_acl() unconditionally for both the access and default ACL types, but the request decoder leaves those pointer fields NULL when the client's mask bit for that arm is not set. Because a NULL pointer to set_posix_acl() means 'remove this ACL type', a client that only sent one ACL (or none) silently strips the other: mask=NFS_ACL drops the directory's default ACL, and mask=0 removes both. An unauthenticated remote NFSv3 client that can reach an affected server can therefore erase POSIX ACLs on exported filesystems, undermining intended access restrictions and potentially exposing restricted files (confidentiality and integrity impact, no availability impact per CVSS 9.1). Any host running nfsd with NFSv3 ACL support is affected; exploitation in the wild is not known and no public PoC exists. The fix gates each set_posix_acl() call on the matching mask bit, leaving on-disk ACLs untouched when neither bit is set.
What to do: Apply a kernel update containing the upstream fix that gates each set_posix_acl() call on the corresponding NFS_ACL / NFS_DFACL mask bit. Until patched, restrict NFSv3 exports to trusted clients via export lists and firewalling of ports 2049 and the mountd/statd RPC services, or disable NFSv3 ACL support where practical. Audit exported trees with getfacl for unexpectedly missing or emptied default and access ACLs, which would indicate the flaw has been triggered.
| Linux kernel (nfsd NFSv3 POSIX ACL support, nfsd3_proc_setacl) | Affected versions not enumerated in the data; all kernel releases carrying the unpatched nfsd3_proc_setacl code prior to the upstream fix commit |
Order-of-magnitude estimate by the model from install counts, market share and public scan data it knows; verify before quoting.
In the Linux kernel, the following vulnerability has been resolved: nfsd: gate nfs3 setacl by argp->mask nfsd3_proc_setacl() calls set_posix_acl() unconditionally for both ACL_TYPE_ACCESS and ACL_TYPE_DEFAULT, passing argp->acl_access and argp->acl_default verbatim. The NFSv3 ACL decoder only populates those pointers when the corresponding mask bit is set: nfs3svc_decode_setaclargs() if (args->mask & NFS_ACL) decode into acl_access if (args->mask & NFS_DFACL) decode into acl_default /* otherwise the pointer stays NULL (pc_argzero) */ nfsd3_proc_setacl() set_posix_acl(.., ACL_TYPE_ACCESS, argp->acl_access) set_posix_acl(.., ACL_TYPE_DEFAULT, argp->acl_default) set_posix_acl(idmap, dentry, type, NULL) is the VFS "remove this ACL type" operation. A NULL pointer that means "the client did not send this arm" is therefore indistinguishable from "the client asked to remove this ACL". A SETACL with mask=NFS_ACL silently drops the directory's default ACL; mask=0 drops both. The sibling nfsd3_proc_getacl() already consults argp->mask before touching each arm; mirror that in setacl. Fix by wrapping each set_posix_acl() call in the matching mask bit check and initializing error to 0 before inode_lock so that a request with neither bit set leaves the on-disk ACLs untouched and returns nfs_ok. The out_drop_lock path and the unconditional posix_acl_release() at out: are preserved; both NULL-tolerate the skipped arms.
- Vector
- CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:N
In the news0 stories
No ingested article mentions this CVE yet.