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; \
} \
}