CVE-2026-89671: nfsd: gate nfs3 setacl by argp->mask
In the Linux kernel, the following vulnerability has been resolved:
nfsd: gate nfs3 setacl by argp->mask
nfsd3procsetacl() calls setposixacl() unconditionally for both ACLTYPEACCESS and ACLTYPEDEFAULT, passing argp->aclaccess and argp->acldefault verbatim. The NFSv3 ACL decoder only populates those pointers when the corresponding mask bit is set:
nfs3svcdecodesetaclargs() if (args->mask & NFSACL) decode into aclaccess if (args->mask & NFSDFACL) decode into acldefault / otherwise the pointer stays NULL (pcargzero) /
nfsd3procsetacl() setposixacl(.., ACLTYPEACCESS, argp->aclaccess) setposixacl(.., ACLTYPEDEFAULT, argp->acldefault)
setposixacl(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=NFSACL silently drops the directory's default ACL; mask=0 drops both.
The sibling nfsd3procgetacl() already consults argp->mask before touching each arm; mirror that in setacl.
Fix by wrapping each setposixacl() call in the matching mask bit check and initializing error to 0 before inodelock so that a request with neither bit set leaves the on-disk ACLs untouched and returns nfsok. The outdroplock path and the unconditional posixaclrelease() at out: are preserved; both NULL-tolerate the skipped arms.
Affected Software
Remediation
Recommended actions to resolve this vulnerability, in priority order.
- Configuration
Modify NFSv3 setacl handling so setacl/decoder logic is gated by argp->mask: only call/populate set_posix_acl for ACL_TYPE_ACCESS when (args->mask & NFS_ACL) is set, and only call/populate set_posix_acl for ACL_TYPE_DEFAULT when (args->mask & NFS_DFACL) is set; when neither bit is set, leave on-disk ACLs untouched and return nfs_ok.
Linux kernel NFSv3 ACL decoder / nfsd3_proc_setacl (set_posix_acl calls) set_posix_acl mask gating for ACL_TYPE_ACCESS and ACL_TYPE_DEFAULT = if (args->mask & NFS_ACL) decode/set ACL_TYPE_ACCESS; if (args->mask & NFS_DFACL) decode/set ACL_TYPE_DEFAULT (otherwise pass NULL so on-disk ACLs are left untouched)
Event History
Frequently Asked Questions
Which systems are exposed to unintended ACL changes?
Systems serving NFSv3 ACL SETACL requests are affected when requests omit one or both ACL mask bits. Directories are particularly exposed because an access-ACL-only request can remove the directory default ACL.
What does an attacker or client need to do to trigger the issue?
They need to send an NFSv3 SETACL request with an ACL mask that omits an ACL arm. A request containing only NFS_ACL can remove the default ACL, while a request with mask=0 can remove both access and default ACLs.
How can administrators identify whether the issue may already have occurred?
Inspect ACLs on directories that received NFSv3 SETACL operations. Unexpectedly missing default ACLs after access ACL updates, or missing access and default ACLs after requests with an empty mask, are indicators of this behavior.