UBUNTU-CVE-2026-89664: High severity ubuntu/linux-hwe-edge vulnerability
In the Linux kernel, the following vulnerability has been resolved: nfsd: release OPEN-decoded posix ACLs via oprelease nfsd4decodecreatehow4() calls nfsd4decodefattr4(), which allocates refcounted struct posixacl objects via posixaclalloc() and stores them in open->oppacl and open->opdpacl. These pointers must be released once the OPEN compound finishes. When nfsd4decodeopenclaim4() returns a non-seqid-mutating error, the dispatcher short-circuits before opfunc runs: nfsd4proccompound() if (op->status && op->opnum == OPOPEN) op->status = nfsd4openomfg(...) if (!seqidmutatingerr(ntohl(op->status))) return op->status; / nfsd4open() never runs / ... opdesc->oprelease(&op->u) / must still release oppacl/opdpacl / Before this change OPOPEN had no .oprelease in nfsd4ops[], and the release pair lived inside nfsd4open() at its outerr: label. On the short-circuit path nfsd4open() is never invoked, so both posixacl refs leak on every malformed OPEN compound that carries valid POSIX ACL createhow4 attributes. Add nfsd4openrelease() and wire it as .oprelease for OPOPEN. posixaclrelease() is NULL-safe, so the single release site covers both the normal path and the nfsd4openomfg short-circuit. Remove the matching posixaclrelease() pair from nfsd4open()'s outerr: label to avoid double-releasing. The compound loop has two encoding branches: nfsd4encodeoperation() for normal ops, and nfsd4encodereplay() for v4.0 replayed ops. oprelease was only called from nfsd4encodeoperation(), so resources attached to op->u leak on the replay path. Move the oprelease() call out of nfsd4encodeoperation() and the replay branch, placing it after the if-else in nfsd4proccompound(). This gives a single call site in a fairly obviously-correct place, covering both the normal encoding and replay paths.
Affected Software
Remediation
Recommended actions to resolve this vulnerability, in priority order.
- Compensating control
Add nfsd4_open_release() and wire it as .op_release for OP_OPEN; move the op_release() call in nfsd4_proc_compound() to after the normal/replay if-else so both paths release op_pacl and op_dpacl, and remove the matching posix_acl_release() pair from nfsd4_open()'s out_err label to prevent double release.