untrusted comment: verify with openbsd-63-base.pub RWRxzbLwAd76ZdDqZo6LADrtHmdrzlxmicibn0H6YtBtSD0PIdSpq296Vs3tG2I3Uv4hUVPgZwPKOiRQ/tEt+3BKs/Iw5XK7UAU= OpenBSD 6.3 errata 029, February 5, 2019: Incorrect length checks in the NFS server and client can lead to crashes and other errors. Apply by doing: signify -Vep /etc/signify/openbsd-63-base.pub -x 029_nfs.patch.sig \ -m - | (cd /usr/src && patch -p0) And then rebuild and install a new kernel: KK=`sysctl -n kern.osversion | cut -d# -f1` cd /usr/src/sys/arch/`machine`/compile/$KK make obj make config make make install Index: sys/nfs/nfs_serv.c =================================================================== RCS file: /cvs/src/sys/nfs/nfs_serv.c,v retrieving revision 1.112 diff -u -p -r1.112 nfs_serv.c --- sys/nfs/nfs_serv.c 30 Dec 2017 20:47:00 -0000 1.112 +++ sys/nfs/nfs_serv.c 21 Jan 2019 22:28:46 -0000 @@ -1715,7 +1715,7 @@ nfsrv_symlink(struct nfsrv_descript *nfs nfsm_mtouio(&io, len2); if (!info.nmi_v3) { nfsm_dissect(sp, struct nfsv2_sattr *, NFSX_V2SATTR); - va.va_mode = fxdr_unsigned(u_int16_t, sp->sa_mode); + va.va_mode = nfstov_mode(sp->sa_mode); } *(pathcp + len2) = '\0'; if (nd.ni_vp) { @@ -2080,12 +2080,12 @@ nfsrv_readdir(struct nfsrv_descript *nfs } off = toff; cnt = fxdr_unsigned(int, *tl); - siz = ((cnt + DIRBLKSIZ - 1) & ~(DIRBLKSIZ - 1)); xfer = NFS_SRVMAXDATA(nfsd); + if (cnt > xfer || cnt < 0) + cnt = xfer; + siz = ((cnt + DIRBLKSIZ - 1) & ~(DIRBLKSIZ - 1)); if (siz > xfer) siz = xfer; - if (cnt > xfer) - cnt = xfer; fullsiz = siz; error = nfsrv_fhtovp(fhp, 1, &vp, cred, slp, nam, &rdonly); if (error) { @@ -2273,19 +2273,18 @@ nfsrv_readdirplus(struct nfsrv_descript fhp = &nfh.fh_generic; nfsm_srvmtofh(fhp); nfsm_dissect(tl, u_int32_t *, 6 * NFSX_UNSIGNED); - toff = fxdr_hyper(tl); + off = toff = fxdr_hyper(tl); tl += 2; verf = fxdr_hyper(tl); tl += 2; siz = fxdr_unsigned(int, *tl++); cnt = fxdr_unsigned(int, *tl); - off = toff; - siz = ((siz + DIRBLKSIZ - 1) & ~(DIRBLKSIZ - 1)); xfer = NFS_SRVMAXDATA(nfsd); + if (cnt > xfer || cnt < 0) + cnt = xfer; + siz = ((siz + DIRBLKSIZ - 1) & ~(DIRBLKSIZ - 1)); if (siz > xfer) siz = xfer; - if (cnt > xfer) - cnt = xfer; fullsiz = siz; error = nfsrv_fhtovp(fhp, 1, &vp, cred, slp, nam, &rdonly); if (error) { @@ -2520,6 +2519,8 @@ nfsrv_commit(struct nfsrv_descript *nfsd off = fxdr_hyper(tl); tl += 2; cnt = fxdr_unsigned(int, *tl); + if (cnt < 0) + cnt = 0; error = nfsrv_fhtovp(fhp, 1, &vp, cred, slp, nam, &rdonly); if (error) { nfsm_reply(2 * NFSX_UNSIGNED); Index: sys/nfs/nfs_vnops.c =================================================================== RCS file: /cvs/src/sys/nfs/nfs_vnops.c,v retrieving revision 1.171 diff -u -p -r1.171 nfs_vnops.c --- sys/nfs/nfs_vnops.c 22 Feb 2017 11:42:46 -0000 1.171 +++ sys/nfs/nfs_vnops.c 21 Jan 2019 22:28:46 -0000 @@ -1206,7 +1206,7 @@ nfs_writerpc(struct vnode *vp, struct ui nfsm_dissect(tl, u_int32_t *, 2 * NFSX_UNSIGNED + NFSX_V3WRITEVERF); rlen = fxdr_unsigned(int, *tl++); - if (rlen == 0) { + if (rlen <= 0) { error = NFSERR_IO; break; } else if (rlen < len) { @@ -2489,7 +2489,8 @@ nfs_readdirplusrpc(struct vnode *vp, str /* Just skip over the file handle */ nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED); i = fxdr_unsigned(int, *tl); - nfsm_adv(nfsm_rndup(i)); + if (i > 0) + nfsm_adv(nfsm_rndup(i)); } if (newvp != NULLVP) { vrele(newvp); Index: sys/nfs/nfsm_subs.h =================================================================== RCS file: /cvs/src/sys/nfs/nfsm_subs.h,v retrieving revision 1.45 diff -u -p -r1.45 nfsm_subs.h --- sys/nfs/nfsm_subs.h 29 Aug 2015 23:07:51 -0000 1.45 +++ sys/nfs/nfsm_subs.h 21 Jan 2019 22:28:46 -0000 @@ -173,7 +173,7 @@ struct nfsm_info { #define nfsm_strsiz(s, m) { \ nfsm_dissect(tl, u_int32_t *,NFSX_UNSIGNED); \ - if (((s) = fxdr_unsigned(int32_t, *tl)) > (m)) { \ + if (((s) = fxdr_unsigned(int32_t, *tl)) < 0 || (s) > (m)) { \ m_freem(info.nmi_mrep); \ error = EBADRPC; \ goto nfsmout; \