untrusted comment: verify with openbsd-64-base.pub RWQq6XmS4eDAcV5mPUNxRO+zhPTE7T8Wn8qJiZ9fSvZxdDtY0LtBQm8BH5puNkyAZ4FTwuVZTj42xTgIMRRaqNS78HvMyGoWMQg= OpenBSD 6.4 errata 012, January 27, 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-64-base.pub -x 012_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.116 diff -u -p -r1.116 nfs_serv.c --- sys/nfs/nfs_serv.c 13 Jun 2018 14:57:24 -0000 1.116 +++ sys/nfs/nfs_serv.c 21 Jan 2019 22:25:43 -0000 @@ -1720,7 +1720,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) { @@ -2092,12 +2092,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) { @@ -2285,19 +2285,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) { @@ -2532,6 +2531,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.179 diff -u -p -r1.179 nfs_vnops.c --- sys/nfs/nfs_vnops.c 2 Jul 2018 20:56:22 -0000 1.179 +++ sys/nfs/nfs_vnops.c 21 Jan 2019 22:25:43 -0000 @@ -1248,7 +1248,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) { @@ -2523,7 +2523,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) { if (newvp == vp) Index: sys/nfs/nfsm_subs.h =================================================================== RCS file: /cvs/src/sys/nfs/nfsm_subs.h,v retrieving revision 1.46 diff -u -p -r1.46 nfsm_subs.h --- sys/nfs/nfsm_subs.h 9 Jul 2018 07:50:28 -0000 1.46 +++ sys/nfs/nfsm_subs.h 21 Jan 2019 22:25:43 -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; \