{"dataType":"CVE_RECORD","dataVersion":"5.2","cveMetadata":{"cveId":"CVE-2026-90234","assignerOrgId":"416baaa9-dc9f-4396-8d5f-8c081fb06d67","state":"PUBLISHED","assignerShortName":"Linux","dateReserved":"2026-09-11T19:38:34.794Z","datePublished":"2026-09-17T16:07:40.584Z","dateUpdated":"2026-09-18T17:54:00.394Z"},"containers":{"cna":{"providerMetadata":{"orgId":"416baaa9-dc9f-4396-8d5f-8c081fb06d67","shortName":"Linux","dateUpdated":"2026-09-18T17:54:00.394Z"},"descriptions":[{"lang":"en","value":"In the Linux kernel, the following vulnerability has been resolved:\n\nNFS: Return a delegation the client fails to record\n\nWhen an NFS server grants a delegation in an OPEN reply,\nnfs_inode_set_delegation() records it on the client. However, three\nof its error flows return without sending DELEGRETURN.\n\nA delegation can be relinquished only by DELEGRETURN (RFC 8881\nSection 20.2.4), so dropping one silently leaves the server believing\nthe client still holds it. If the server happens to recall that\ndelegation, the client answers CB_RECALL with NFS4ERR_BADHANDLE\nbecause it has no record of the stateid. The server revokes the\ndelegation and moves it onto its cl_revoked list, because the client\nnever sends the FREE_STATEID that would drain it. Every subsequent\nSEQUENCE reply then carries SEQ4_STATUS_RECALLABLE_STATE_REVOKED,\nand the client's state manager loops issuing TEST_STATEID across its\ndelegations without ever clearing the condition.\n\nThe window is easy to reach now that a server offers a write\ndelegation on any write OPEN: a delegation recalled for one opener\nraces a re-open that the server answers with a fresh write\ndelegation.\n\nInstead of dropping it, hand the delegation back during these error\nflows."}],"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 - nfs_inode_set_delegation() is reached from nfs4_process_delegation() after _nfs4_opendata_to_nfs4_state() consumes an NFSv4 OPEN reply; decode_rw_delegation() takes the WRITE open_delegation4 (stateid, want_recall) off that TCP ONC RPC reply, so the remote NFS server supplies the delegation the client then drops without DELEGRETURN.\nAC:L - When the inode's old delegation has NFS_DELEGATION_RETURNING set, a concurrent write OPEN whose reply carries a different write stateid hits test_and_set_bit(NFS_DELEGATION_RETURNING) or a failed nfs_detach_delegations_locked() and is freed without nfs_do_return_delegation(); nfs4_callback_recall() queues that return and the server can delay DELEGRETURN, so it times both RPCs.\nPR:N - nfs4_process_delegation() and nfs4_callback_recall() run on the established NFSv4 session with no capable() or local uid check; the attacker is the NFS server peer that authored the OPEN reply and CB_RECALL and needs no account or mount privilege on the client.\nUI:N - On an already-mounted NFSv4 share, ordinary open() through nfs4_atomic_open()/nfs4_file_open() drives the OPEN RPC; the server plants the unrecorded WRITE delegation in that reply and sends CB_RECALL, with no further victim action such as mounting a new image.\nS:U - The nfs4_state_manager() recovery loop and nfs4_begin_drain_session() of cl_session stay inside the NFS client kernel; this does not cross a VM, IOMMU, or sandbox boundary.\nC:N - The dropped object is a kmalloc'd nfs_delegation that was never published on nfsi->delegation; __nfs_free_delegation() frees it immediately, with no use-after-free, out-of-bounds read, or leftover pointer that could disclose kernel memory.\nI:N - The same unused nfs_delegation is only kfree_rcu'd; nfs_inode_set_delegation() does not write through a dangling pointer or overflow a buffer, so there is no arbitrary write or control-flow hijack.\nA:H - After CB_RECALL of the orphaned stateid, nfs_delegation_find_inode() misses it so nfs4_callback_recall() returns NFS4ERR_BADHANDLE; SEQ4_STATUS_RECALLABLE_STATE_REVOKED then makes nfs41_handle_recallable_state_revoked() reschedule nfs_test_expired_all_delegations() forever, and nfs4_begin_drain_session() hangs subsequent NFSv4 RPCs."}]}],"affected":[{"product":"Linux","vendor":"Linux","defaultStatus":"unaffected","repo":"https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git","programFiles":["fs/nfs/delegation.c"],"versions":[{"version":"ade04647dd56881e285983af3db702d56ee97e86","lessThan":"92533e49fe3c455088657b862cf3562260c0ce25","status":"affected","versionType":"git"},{"version":"ade04647dd56881e285983af3db702d56ee97e86","lessThan":"220af23d863995091f0edeb1e6aa0945b3db8b37","status":"affected","versionType":"git"}]},{"product":"Linux","vendor":"Linux","defaultStatus":"affected","repo":"https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git","programFiles":["fs/nfs/delegation.c"],"versions":[{"version":"4.0","status":"affected"},{"version":"0","lessThan":"4.0","status":"unaffected","versionType":"semver"},{"version":"7.2.6","lessThanOrEqual":"7.2.*","status":"unaffected","versionType":"semver"},{"version":"7.3-rc1","lessThanOrEqual":"*","status":"unaffected","versionType":"original_commit_for_fix"}]}],"cpeApplicability":[{"nodes":[{"operator":"OR","negate":false,"cpeMatch":[{"vulnerable":true,"criteria":"cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:*","versionStartIncluding":"4.0","versionEndExcluding":"7.2.6"},{"vulnerable":true,"criteria":"cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:*","versionStartIncluding":"4.0","versionEndExcluding":"7.3-rc1"}]}]}],"references":[{"url":"https://git.kernel.org/stable/c/92533e49fe3c455088657b862cf3562260c0ce25"},{"url":"https://git.kernel.org/stable/c/220af23d863995091f0edeb1e6aa0945b3db8b37"}],"title":"NFS: Return a delegation the client fails to record","x_generator":{"engine":"bippy-1.2.0"}}}}