[PATCH] nfsd: reject out-of-range nseconds in NFSv3 nfstime3 decode
robbieko <robbieko-UelDjCVBxVpWk0Htik3J/[email protected]>
| Newsgroups | gmane.linux.nfs |
|---|---|
| Message-ID | <[email protected]> |
From: Robbie Ko <robbieko-UelDjCVBxVpWk0Htik3J/[email protected]> The NFSv3 nfstime3 decoder svcxdr_decode_nfstime3() accepts the 32-bit nseconds field from the wire without validating its range. RFC 1813 does not constrain the value, but a tv_nsec >= NSEC_PER_SEC is not a valid timespec64. The NFSv4 decoder nfsd4_decode_nfstime4() already rejects such values with NFS4ERR_INVAL; NFSv3 had no equivalent check. A malicious or buggy client can therefore send a SETATTR carrying an out-of-range nseconds (up to 4294967295). The value flows through nfsd_setattr() -> notify_change() -> timestamp_truncate(), which does not clamp tv_nsec to < NSEC_PER_SEC when the filesystem supports nanosecond granularity (s_time_gran == 1). The inode atime/mtime setters store it verbatim (only ctime is normalized via inode_set_ctime_to_ts()). The un-normalized value then corrupts on-disk metadata: ext4's ext4_encode_extra_time() shifts tv_nsec left by EXT4_EPOCH_BITS, which overflows the 32-bit extra field and clobbers the seconds-epoch bits, so the stored seconds (year) are wrong on read-back. XFS with bigtime mis-stores the timestamp for the same reason. This is silent, with no WARN_ON anywhere in the path to catch it. Validate the decoded nseconds in svcxdr_decode_nfstime3() and fail the XDR decode if it is out of range, mirroring the NFSv4 behavior. Signed-off-by: Robbie Ko <robbieko-UelDjCVBxVpWk0Htik3J/[email protected]> --- fs/nfsd/nfs3xdr.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/fs/nfsd/nfs3xdr.c b/fs/nfsd/nfs3xdr.c index 2ff9a991a8fb..59e82ce03c20 100644 --- a/fs/nfsd/nfs3xdr.c +++ b/fs/nfsd/nfs3xdr.c @@ -64,6 +64,8 @@ svcxdr_decode_nfstime3(struct xdr_stream *xdr, struct timespec64 *timep) return false; timep->tv_sec = be32_to_cpup(p++); timep->tv_nsec = be32_to_cpup(p); + if (timep->tv_nsec >= (u32)1000000000) + return false; return true; } -- 2.43.0 Disclaimer: The contents of this e-mail message and any attachments are confidential and are intended solely for addressee. The information may also be legally privileged. This transmission is sent in trust, for the sole purpose of delivery to the intended recipient. If you have received this transmission in error, any use, reproduction or dissemination of this transmission is strictly prohibited. If you are not the intended recipient, please immediately notify the sender by reply e-mail or phone and delete this message and its attachments, if any.