untrusted comment: verify with openbsd-75-base.pub RWRGj1pRpprAfpfSCk7wg7g7MbzEL9hsCOm67Q8J+AqBr/J8XiLn7/2ncNp9nG0UoKVEohCADV7mReQ80i7ME5X6pWB2gz+C5wU= OpenBSD 7.5 errata 008, September 17, 2024: Avoid possible mbuf double free in NFS client and server implementation. Do not use uninitialized variable in error handling of NFS server. Apply by doing: signify -Vep /etc/signify/openbsd-75-base.pub -x 008_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_socket.c =================================================================== RCS file: /cvs/src/sys/nfs/nfs_socket.c,v diff -u -p -r1.145 nfs_socket.c --- sys/nfs/nfs_socket.c 5 Feb 2024 20:21:39 -0000 1.145 +++ sys/nfs/nfs_socket.c 14 Sep 2024 21:54:27 -0000 @@ -1005,6 +1005,7 @@ tryagain: if ((nmp->nm_flag & NFSMNT_NFSV3) && error == NFSERR_TRYLATER) { m_freem(info.nmi_mrep); + info.nmi_mrep = NULL; error = 0; tsleep_nsec(&nowake, PSOCK, "nfsretry", SEC_TO_NSEC(trylater_delay)); Index: sys/nfs/nfsm_subs.h =================================================================== RCS file: /cvs/src/sys/nfs/nfsm_subs.h,v diff -u -p -r1.47 nfsm_subs.h --- sys/nfs/nfsm_subs.h 18 Jan 2019 13:59:18 -0000 1.47 +++ sys/nfs/nfsm_subs.h 14 Sep 2024 21:54:27 -0000 @@ -65,6 +65,7 @@ struct nfsm_info { &cp2)) != 0) { \ error = t1; \ m_freem(info.nmi_mrep); \ + info.nmi_mrep = NULL; \ goto nfsmout; \ } else { \ (a) = (c)cp2; \ @@ -91,6 +92,7 @@ struct nfsm_info { &ttnp)) != 0) { \ error = t1; \ m_freem(info.nmi_mrep); \ + info.nmi_mrep = NULL; \ goto nfsmout; \ } \ (v) = NFSTOV(ttnp); \ @@ -112,6 +114,7 @@ struct nfsm_info { if (((s) = fxdr_unsigned(int, *tl)) <= 0 || \ (s) > NFSX_V3FHMAX) { \ m_freem(info.nmi_mrep); \ + info.nmi_mrep = NULL; \ error = EBADRPC; \ goto nfsmout; \ } \ @@ -126,6 +129,7 @@ struct nfsm_info { &info.nmi_dpos, (a))) != 0) { \ error = t1; \ m_freem(info.nmi_mrep); \ + info.nmi_mrep = NULL; \ goto nfsmout; \ } \ (v) = ttvp; \ @@ -140,6 +144,7 @@ struct nfsm_info { error = t1; \ (f) = 0; \ m_freem(info.nmi_mrep); \ + info.nmi_mrep = NULL; \ goto nfsmout; \ } \ (v) = ttvp; \ @@ -175,19 +180,30 @@ struct nfsm_info { nfsm_dissect(tl, u_int32_t *,NFSX_UNSIGNED); \ if (((s) = fxdr_unsigned(int32_t, *tl)) < 0 || (s) > (m)) { \ m_freem(info.nmi_mrep); \ + info.nmi_mrep = NULL; \ error = EBADRPC; \ goto nfsmout; \ } \ } +/* + * Note nfsm_reply at the end of this macro would return if v3 and an error + * different from EBADRPC. But it does not make sense to continue anyway if + * the error is NFSERR_NAMETOL. + */ #define nfsm_srvnamesiz(s) { \ nfsm_dissect(tl, u_int32_t *,NFSX_UNSIGNED); \ - if (((s) = fxdr_unsigned(int32_t, *tl)) > NFS_MAXNAMLEN) \ + if (((s) = fxdr_unsigned(int32_t, *tl)) > NFS_MAXNAMLEN) { \ error = NFSERR_NAMETOL; \ - if ((s) <= 0) \ + (s) = 0; \ + } else if ((s) <= 0) { \ error = EBADRPC; \ - if (error) \ + (s) = 0; \ + } \ + if (error) { \ nfsm_reply(0); \ + return(0); \ + } \ } #define nfsm_mtouio(p, s) \ @@ -196,6 +212,7 @@ struct nfsm_info { &info.nmi_dpos)) != 0) { \ error = t1; \ m_freem(info.nmi_mrep); \ + info.nmi_mrep = NULL; \ goto nfsmout; \ } @@ -204,6 +221,7 @@ struct nfsm_info { #define nfsm_strtom(a, s, m) \ if ((s) > (m)) { \ m_freem(info.nmi_mreq); \ + info.nmi_mreq = NULL; \ error = ENAMETOOLONG; \ goto nfsmout; \ } \ @@ -217,10 +235,8 @@ struct nfsm_info { else \ (void) nfs_rephead((s), nfsd, slp, error, \ &info.nmi_mreq, &info.nmi_mb); \ - if (info.nmi_mrep != NULL) { \ - m_freem(info.nmi_mrep); \ - info.nmi_mrep = NULL; \ - } \ + m_freem(info.nmi_mrep); \ + info.nmi_mrep = NULL; \ *mrq = info.nmi_mreq; \ if (error && (!(nfsd->nd_flag & ND_NFSV3) || error == EBADRPC)) \ return(0); \ @@ -235,6 +251,7 @@ struct nfsm_info { (s), t1)) != 0) { \ error = t1; \ m_freem(info.nmi_mrep); \ + info.nmi_mrep = NULL; \ goto nfsmout; \ } \ }