nfsd: size fh_verify server sockaddr slot by xpt_locallen
In the Linux kernel, the following vulnerability has been resolved:
nfsd: size fh_verify server sockaddr slot by xpt_locallen
The nfsd_fh_verify and nfsd_fh_verify_err tracepoints declare the
server sockaddr slot sized by xpt_remotelen but fill it from
xpt_local using xpt_locallen:
TP_STRUCT__entry(
...
__sockaddr(server, rqstp->rq_xprt->xpt_remotelen)
...
)
TP_fast_assign(
...
__assign_sockaddr(server, &rqstp->rq_xprt->xpt_local,
rqstp->rq_xprt->xpt_locallen);
...
)
When xpt_locallen exceeds xpt_remotelen, __assign_sockad
nfsd: validate symlink target length in NFSv4 CREATE
In the Linux kernel, the following vulnerability has been resolved:
nfsd: validate symlink target length in NFSv4 CREATE
nfsd4_decode_create() accepts an unbounded cr_datalen from the wire for
NF4LNK symlink targets, allowing a client to force a kmalloc of up to
the maximum RPC payload size (several MiB) per COMPOUND op that persists
until compound teardown. The VFS rejects oversized targets with
ENAMETOOLONG, but the allocation has already occurred.
Reject cr_datalen == 0 early with nfserr_inval and cr_datalen greater
than NFS4_MAXPATHLEN (PATH_MAX) with nfserr_nametoolong to bound the
allocation.
nfsd: add fh_want_write() for early-verified SETATTR in nfsd_proc_setattr()
In the Linux kernel, the following vulnerability has been resolved:
nfsd: add fh_want_write() for early-verified SETATTR in nfsd_proc_setattr()
The BOTH_TIME_SET branch calls fh_verify() early so setattr_prepare()
can inspect the dentry. This causes nfsd_setattr() to skip
fh_want_write(), so notify_change() runs without a mount write
reference.
Add the missing fh_want_write() call after the early fh_verify().
nfsd: block non-SAVEFH ops after FOREIGN PUTFH to prevent NULL deref
In the Linux kernel, the following vulnerability has been resolved:
nfsd: block non-SAVEFH ops after FOREIGN PUTFH to prevent NULL deref
When CONFIG_NFSD_V4_2_INTER_SSC is enabled, nfsd4_putfh() can return
success with fh_dentry and fh_export both NULL if fh_verify() returns
nfserr_stale and putfh->no_verify is true. The NFSD4_FH_FOREIGN flag
is set, but the compound dispatch loop only uses this flag to bypass
the nfserr_nofilehandle check -- it does not prevent subsequent ops
from running with a NULL fh_dentry.
A remote client can exploit this by crafting a COMPOUND that includes
an inter-SSC COPY (which causes check_if_stalefh_allowed()
nfsd: check client ownership when cancelling a copy-notify stateid
In the Linux kernel, the following vulnerability has been resolved:
nfsd: check client ownership when cancelling a copy-notify stateid
On the OFFLOAD_CANCEL path (clp != NULL), manage_cpntf_state() freed the
target cpntf state without checking ownership. The lookup key
st->si_opaque.so_id is allocated cyclically (guessable) and the embedded
clientid is the fixed per-net nn->s2s_cp_cl_id, so any authenticated
NFSv4.2 client could cancel and free another client's copy-notify
stateid.
Compare the creating clientid recorded in state->cp_p_clid against the
requesting client's cl_clientid and return nfserr_bad_stateid on a
mismatch instead of fr
nfsd: check nfsd4_acl_to_attr() return value in nfsd4_create()
In the Linux kernel, the following vulnerability has been resolved:
nfsd: check nfsd4_acl_to_attr() return value in nfsd4_create()
nfsd4_create() stores the return value of nfsd4_acl_to_attr() in
status, but the switch(create->cr_type) block unconditionally
overwrites it in every branch. ACL translation errors are silently
discarded, and the CREATE proceeds without the requested ACL.
Add an early exit check after nfsd4_acl_to_attr(), matching the
pattern already used in nfsd4_setattr().
[ cel: prefer NFS4ERR_BADTYPE over NFS4ERR_ATTRNOTSUPP ]
nfsd: fix BUG_ON in nfsd4_alloc_layout_stateid on racing delegation revoke
In the Linux kernel, the following vulnerability has been resolved:
nfsd: fix BUG_ON in nfsd4_alloc_layout_stateid on racing delegation revoke
nfsd4_alloc_layout_stateid reads fp->fi_deleg_file without holding
fi_lock when the parent stateid is a delegation. A concurrent delegation
revoke via the laundromat can clear fi_deleg_file under fi_lock, causing
nfsd_file_get() to return NULL and triggering the BUG_ON.
This race is client-reachable: two NFS clients can trigger it by having
one hold a delegation while another opens the same file to force a
recall. When the first client doesn't respond to the recall, the
laundromat revokes it. A conc
nfsd: fix clock domain mismatch in clients_still_reclaiming()
In the Linux kernel, the following vulnerability has been resolved:
nfsd: fix clock domain mismatch in clients_still_reclaiming()
clients_still_reclaiming() computes a deadline from nn->boot_time
(CLOCK_REALTIME, ~1.7 billion) but compares it against
ktime_get_boottime_seconds() (CLOCK_BOOTTIME, seconds since boot).
The comparison is always false — it would take ~54 years of uptime
for BOOTTIME to exceed the REALTIME-derived deadline.
This means any client can hold the server in grace indefinitely by
sending CLAIM_PREVIOUS OPEN requests, blocking all non-reclaim
operations for all other clients.
Add boot_time_bt (CLOCK_BOOTTIME) alongside
nfsd: fix cpntf publish race in nfs4_init_cp_state
In the Linux kernel, the following vulnerability has been resolved:
nfsd: fix cpntf publish race in nfs4_init_cp_state
nfs4_alloc_init_cpntf_state() published the new cpntf entry into the
s2s_cp_stateids IDR (with cs_type set) in one s2s_cp_lock section, then
took the lock again to list_add() it onto p_stid->sc_cp_list. In the gap
the entry is reachable by so_id but cp_list is still {NULL,NULL} from
kzalloc. A racing OFFLOAD_CANCEL (so_id is echoed to the client as
cnr_stateid, so any NFSv4.2 client can drive it) reaches
manage_cpntf_state() -> _free_cpntf_state_locked() and does list_del() on
the zeroed list_head, oopsing the server.
Fold
nfsd: fix fcache_disposal UAF by inlining dispose state into nfsd_net
In the Linux kernel, the following vulnerability has been resolved:
nfsd: fix fcache_disposal UAF by inlining dispose state into nfsd_net
nfsd_file_dispose_list_delayed() defers fput() to nfsd service threads
via a per-net freeme queue, preventing the shrinker and GC worker from
bearing the cost of closing files (see ffb402596147). However, the
queue lives in a separately-allocated struct nfsd_fcache_disposal that
is freed by nfsd_free_fcache_disposal_net() during per-net teardown.
The global shrinker, laundrette, and fsnotify callbacks can still be
inside nfsd_file_dispose_list_delayed() dereferencing that pointer,
causing a use-after-fre
nfsd: fix nfsd_file leak on inter-server COPY setup failure
In the Linux kernel, the following vulnerability has been resolved:
nfsd: fix nfsd_file leak on inter-server COPY setup failure
When nfsd4_setup_inter_ssc() fails, nfsd4_copy() returns
nfserr_offload_denied directly, bypassing the out: label where
release_copy_files() would drop the nf_dst reference taken by
nfs4_preprocess_stateid_op(). Each failed inter-server COPY
leaks one nfsd_file, pinning file/inode/dentry/vfsmount.
Fix by setting status and jumping to out: instead of returning
directly.
nfsd: fix stale s2s_cp_stateids IDR entry for async COPY
In the Linux kernel, the following vulnerability has been resolved:
nfsd: fix stale s2s_cp_stateids IDR entry for async COPY
For an async COPY, nfsd4_copy() called nfs4_init_copy_state() before
dup_copy_fields(), so the s2s_cp_stateids IDR was pointed at
&u->copy->cp_stateid -- memory in the per-rqstp COMPOUND buffer that is
reused by the next request. dup_copy_fields() copies only the value into
async_copy, so the IDR slot dangled at the transient buffer for the whole
background copy. Any IDR walker then dereferences reused request memory:
the laundromat reads cs_type from it and, if the bytes look like an
expired NFS4_COPYNOTIFY_STID, fol
In the Linux kernel, the following vulnerability has been resolved:
nfsd: fix UAF in async copy cancel and shutdown
An async copy could be freed or used after free while a teardown caller
(OFFLOAD_CANCEL, nfsd4_shutdown_copy, nfsd4_cancel_copy_by_sb) raced the
copy kthread:
- find_async_copy() bumped copy->refcount but left the copy on
clp->async_copies, so the reaper's cleanup_async_copy() could run
release_copy_files() concurrently with a cancel/shutdown caller. Both
put and NULL nf_src/nf_dst without a common lock, double-putting the
nfsd_file and freeing it early.
- nfsd4_do_async_copy() set NFSD4_COPY_F_STOPPED be
nfsd: fix XDR length calculation in nfsd4_ff_encode_layoutget
In the Linux kernel, the following vulnerability has been resolved:
nfsd: fix XDR length calculation in nfsd4_ff_encode_layoutget
The XDR buffer size calculation in nfsd4_ff_encode_layoutget() has
multiple errors that can result in either an out-of-bounds write or
leaking uninitialized kernel memory to the client:
- fh_len doesn't account for XDR padding on the file handle data
- uid and gid lengths use "8 + len" but xdr_encode_opaque() actually
writes "4 + xdr_align_size(len)" bytes
- ds_len omits the flags and stats_collect_hint fields (8 bytes),
while len's header constant overestimates by 8 bytes -- these
partially cancel b
In the Linux kernel, the following vulnerability has been resolved:
nfsd: gate nfs2 setacl by argp->mask
The NFSACL v2 SETACL path shares the decoder convention used by its
v3 sibling: nfsaclsvc_decode_setaclargs() fills in argp->acl_access
only when NFS_ACL is set in the request mask and argp->acl_default
only when NFS_DFACL is set, leaving the other pointer NULL because
the argument buffer is zeroed up to pc_argzero before decode.
nfsacld_proc_setacl() then hands both pointers to set_posix_acl()
unconditionally. set_posix_acl(idmap, dentry, type, NULL) is the VFS
"remove this ACL type" operation, so an omitted arm is
indistinguishable fr
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_acce
nfsd: initialize copy-notify stateid before publishing it
In the Linux kernel, the following vulnerability has been resolved:
nfsd: initialize copy-notify stateid before publishing it
nfsd4_copy_notify() finished initializing the cpntf state after
nfs4_alloc_init_cpntf_state() had already linked it into the
s2s_cp_stateids IDR and the parent's sc_cp_list, with cs_count == 1 (the
membership reference) and none held for the caller. A racing
OFFLOAD_CANCEL (crafted cl_id == nn->s2s_cp_cl_id plus the guessable
so_id) could reach manage_cpntf_state() and free the entry, turning the
caller's subsequent cpn_cnr_stateid read and cp_p_stateid/cp_p_clid
writes into use-after-free. The owning clientid was al
nfsd: reject out-of-range nseconds in NFSv3 SETATTR and create ops
In the Linux kernel, the following vulnerability has been resolved:
nfsd: reject out-of-range nseconds in NFSv3 SETATTR and create ops
A client can send an NFSv3 SETATTR, CREATE, MKDIR, SYMLINK or MKNOD
carrying an atime or mtime whose nseconds field is out of range. The
value is well-formed on the wire and decodes cleanly into a valid
uint32, but it is not a valid timespec64: tv_nsec must be less than
NSEC_PER_SEC.
Nothing in the setattr path clamps it. notify_change() runs the time
through timestamp_truncate(), which does not reduce tv_nsec below
NSEC_PER_SEC when the filesystem supports nanosecond granularity
(s_time_gran == 1), and the
nfsd: reject out-of-range useconds in NFSv2 SETATTR/CREATE
In the Linux kernel, the following vulnerability has been resolved:
nfsd: reject out-of-range useconds in NFSv2 SETATTR/CREATE
The NFSv2 sattr decoder converts the wire useconds to nanoseconds in
svcxdr_decode_sattr():
iap->ia_atime.tv_nsec = tmp2 * NSEC_PER_USEC;
tmp2 is a u32 and NSEC_PER_USEC is 1000, so the product is computed in
unsigned long. On ILP32 that is 32 bits, and an out-of-range useconds
value such as 4294968 wraps to tv_nsec == 704. The corruption therefore
happens during decode, before any proc function can inspect the value,
and a later range check on tv_nsec would see an in-range result and
accept it. Rejecting in the
nfsd: revoke copy-notify stateids before dropping their reference
In the Linux kernel, the following vulnerability has been resolved:
nfsd: revoke copy-notify stateids before dropping their reference
Copy-notify stateids live in the s2s_cp_stateids IDR and on their parent
stid's sc_cp_list, pinned by a single membership reference.
_free_cpntf_state_locked() only unlinks an entry once its refcount reaches
zero, so any revoke path that runs while a concurrent
find_cpntf_state()/manage_cpntf_state() holder has elevated cs_count drops
the reference without unlinking, leaving the entry discoverable with its
membership reference already consumed. A second revoke or a laundromat tick
then frees it while the read