diff --git a/sys/fs/nfsserver/nfs_nfsdserv.c.noalloc b/sys/fs/nfsserver/nfs_nfsdserv.c --- a/sys/fs/nfsserver/nfs_nfsdserv.c.noalloc +++ b/sys/fs/nfsserver/nfs_nfsdserv.c @@ -5346,12 +5346,15 @@ off = fxdr_hyper(tl); tl += 2; lop->lo_first = off; len = fxdr_hyper(tl); - lop->lo_end = off + len; + lop->lo_end = lop->lo_first + len; /* - * Paranoia, just in case it wraps around, which shouldn't - * ever happen anyhow. + * Sanity check the offset and length. + * off and len are off_t (signed int64_t) whereas + * lo_first and lo_end are uint64_t and, as such, + * if off >= 0 && len > 0, lo_end cannot overflow. */ - if (nd->nd_repstat == 0 && (lop->lo_end < lop->lo_first || len <= 0)) + if (nd->nd_repstat == 0 && (len <= 0 || off < 0 || lop->lo_end > + OFF_MAX)) nd->nd_repstat = NFSERR_INVAL; if (nd->nd_repstat == 0 && vnode_vtype(vp) != VREG)