{"id":"CVE-2026-89695","state":"PUBLISHED","title":"nfsd: cap decoded POSIX ACL count to bound sort cost","description":"In the Linux kernel, the following vulnerability has been resolved:\n\nnfsd: cap decoded POSIX ACL count to bound sort cost\n\nnfsd4_decode_posixacl() reads a u32 entry count off the wire and passes\nit straight to posix_acl_alloc() and sort_pacl_range(). The latter is\nan O(n^2) bubble sort, so a client-chosen count drives unbounded CPU in\nthe server's compound processing path.\n\n    nfsd4_decode_posixacl()\n      xdr_stream_decode_u32(&count)       /* uncapped u32 */\n      posix_acl_alloc(count, GFP_KERNEL)\n      sort_pacl_range(*acl, 0, count - 1) /* O(n^2) bubble sort */\n\nThe encoder side in the same file already rejects ACLs whose a_count\nexceeds NFS_ACL_MAX_ENTRIES, but the decoder introduced in commit\n5fc51dfc2eb1 (\"NFSD: Add support for XDR decoding POSIX draft ACLs\")\nomitted the symmetric check.\n\nFix by rejecting a wire count greater than NFS_ACL_MAX_ENTRIES with\nnfserr_inval, before any allocation, so the sort is bounded by\nNFS_ACL_MAX_ENTRIES^2 comparisons.\n\nWhile we're in here, also fix the nfserr_resource return if\nposix_acl_alloc() fails. That's not a legal error code for v4.1+. Change\nit to return nfserr_jukebox as that's more appropriate for memory\nallocation failures.","publishedAt":"2026-09-11T19:46:14.258Z","updatedAt":"2026-10-19T08:51:08.488Z","severity":{"score":7.5,"label":"High","version":"3.1","vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H","source":"Linux"},"assigner":"Linux","products":["Linux Linux"],"affected":[{"vendor":"Linux","product":"Linux","defaultStatus":"unaffected","versions":[{"version":"5fc51dfc2eb160bd7ab3251ab1767cacf9c8bf05","status":"affected","lessThan":"ea14d71d6ecb925673761bcf79f781f7dc9042cc","versionType":"git"},{"version":"5fc51dfc2eb160bd7ab3251ab1767cacf9c8bf05","status":"affected","lessThan":"4bc1108e876153a2dd6d874052b99182c3603135","versionType":"git"}],"repo":"https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git","programFiles":["fs/nfsd/nfs4xdr.c"]},{"vendor":"Linux","product":"Linux","defaultStatus":"affected","versions":[{"version":"7.0","status":"affected"},{"version":"0","status":"unaffected","lessThan":"7.0","versionType":"semver"},{"version":"7.2.4","status":"unaffected","lessThanOrEqual":"7.2.*","versionType":"semver"},{"version":"7.3","status":"unaffected","lessThanOrEqual":"*","versionType":"original_commit_for_fix"}],"repo":"https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git","programFiles":["fs/nfsd/nfs4xdr.c"]}],"references":["https://git.kernel.org/stable/c/ea14d71d6ecb925673761bcf79f781f7dc9042cc","https://git.kernel.org/stable/c/4bc1108e876153a2dd6d874052b99182c3603135"],"weaknesses":[],"ingestedAt":"2026-10-29T20:13:26.108Z","source":{"repository":"CVEProject/cvelistV5","path":"cves/2026/89xxx/CVE-2026-89695.json","commit":"556c9d3a8cd17e218bb8e452ba7cd619a384ff47"},"raw":{"dataType":"CVE_RECORD","dataVersion":"5.2","cveMetadata":{"cveId":"CVE-2026-89695","state":"PUBLISHED","datePublished":"2026-09-11T19:46:14.258Z","dateUpdated":"2026-10-19T08:51:08.488Z","assignerShortName":"Linux","assignerOrgId":"416baaa9-dc9f-4396-8d5f-8c081fb06d67","dateReserved":"2026-09-11T19:38:34.750Z"},"containers":{"cna":{"title":"nfsd: cap decoded POSIX ACL count to bound sort cost","descriptions":[{"lang":"en","value":"In the Linux kernel, the following vulnerability has been resolved:\n\nnfsd: cap decoded POSIX ACL count to bound sort cost\n\nnfsd4_decode_posixacl() reads a u32 entry count off the wire and passes\nit straight to posix_acl_alloc() and sort_pacl_range(). The latter is\nan O(n^2) bubble sort, so a client-chosen count drives unbounded CPU in\nthe server's compound processing path.\n\n    nfsd4_decode_posixacl()\n      xdr_stream_decode_u32(&count)       /* uncapped u32 */\n      posix_acl_alloc(count, GFP_KERNEL)\n      sort_pacl_range(*acl, 0, count - 1) /* O(n^2) bubble sort */\n\nThe encoder side in the same file already rejects ACLs whose a_count\nexceeds NFS_ACL_MAX_ENTRIES, but the decoder introduced in commit\n5fc51dfc2eb1 (\"NFSD: Add support for XDR decoding POSIX draft ACLs\")\nomitted the symmetric check.\n\nFix by rejecting a wire count greater than NFS_ACL_MAX_ENTRIES with\nnfserr_inval, before any allocation, so the sort is bounded by\nNFS_ACL_MAX_ENTRIES^2 comparisons.\n\nWhile we're in here, also fix the nfserr_resource return if\nposix_acl_alloc() fails. That's not a legal error code for v4.1+. Change\nit to return nfserr_jukebox as that's more appropriate for memory\nallocation failures."}],"affected":[{"vendor":"Linux","product":"Linux","defaultStatus":"unaffected","versions":[{"version":"5fc51dfc2eb160bd7ab3251ab1767cacf9c8bf05","status":"affected","lessThan":"ea14d71d6ecb925673761bcf79f781f7dc9042cc","versionType":"git"},{"version":"5fc51dfc2eb160bd7ab3251ab1767cacf9c8bf05","status":"affected","lessThan":"4bc1108e876153a2dd6d874052b99182c3603135","versionType":"git"}],"repo":"https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git","programFiles":["fs/nfsd/nfs4xdr.c"]},{"vendor":"Linux","product":"Linux","defaultStatus":"affected","versions":[{"version":"7.0","status":"affected"},{"version":"0","status":"unaffected","lessThan":"7.0","versionType":"semver"},{"version":"7.2.4","status":"unaffected","lessThanOrEqual":"7.2.*","versionType":"semver"},{"version":"7.3","status":"unaffected","lessThanOrEqual":"*","versionType":"original_commit_for_fix"}],"repo":"https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git","programFiles":["fs/nfsd/nfs4xdr.c"]}],"references":[{"url":"https://git.kernel.org/stable/c/ea14d71d6ecb925673761bcf79f781f7dc9042cc"},{"url":"https://git.kernel.org/stable/c/4bc1108e876153a2dd6d874052b99182c3603135"}],"metrics":[{"cvssV3_1":{"version":"3.1","vectorString":"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H","baseScore":7.5,"baseSeverity":"HIGH"},"scenarios":[{"lang":"en","value":"AV:N - The flaw is in nfsd's NFSv4 XDR decoder (nfsd4_decode_posixacl in fs/nfsd/nfs4xdr.c), reached when a remote client sends COMPOUND SETATTR, CREATE, or OPEN with POSIX draft ACL fattrs over TCP/2049.\nAC:L - The attacker supplies the u32 ACL count and reverse-sorted ACE payload on the wire; decode then runs sort_pacl_range() deterministically with no race, victim state, or memory-layout dependency.\nPR:N - nfsd4_decode_posixacl() runs during COMPOUND XDR decode before SEQUENCE, filehandle, export, or setattr checks; under AUTH_SYS, the common NFS flavor, RPC credentials are attacker-asserted and no secret is verified.\nUI:N - nfsd worker threads decode and sort the attacker's COMPOUND automatically; no local user or administrator action is required.\nS:U - Impact stays inside the host kernel's nfsd thread pool; this is not a VM escape, IOMMU bypass, or other cross-authority boundary.\nC:N - The bug only burns CPU while sorting a temporary decoded POSIX ACL; it does not read kernel or file contents, and a failed posix_acl_alloc() returns an NFS error without leaking memory.\nI:N - sort_pacl_range() only reorders the attacker's own temporary ACL buffer, which is discarded on error; no kernel memory is corrupted and no on-disk ACL is applied without later authorization.\nA:H - A client-chosen ACE count, practically hundreds of thousands within the 4MiB RPC payload, drives an un-preempted O(n^2) bubble sort in an nfsd thread, stalling the finite nfsd pool so repeated requests fully deny NFS service."}]}],"providerMetadata":{"shortName":"Linux","orgId":"416baaa9-dc9f-4396-8d5f-8c081fb06d67","dateUpdated":"2026-10-19T08:51:08.488Z"},"cpeApplicability":[{"nodes":[{"operator":"OR","negate":false,"cpeMatch":[{"vulnerable":true,"criteria":"cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:*","versionStartIncluding":"7.0","versionEndExcluding":"7.2.4"},{"vulnerable":true,"criteria":"cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:*","versionStartIncluding":"7.0","versionEndExcluding":"7.3"}]}]}],"x_generator":{"engine":"bippy-1.2.0"}}}}}