git: 968abc191ea1 - stable/13 - nfscl: Fix a crash when a readdir entry has nul in it
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Fri, 24 Jan 2025 02:31:21 UTC
The branch stable/13 has been updated by rmacklem: URL: https://cgit.FreeBSD.org/src/commit/?id=968abc191ea145040f4c2105755d11b63ecb2427 commit 968abc191ea145040f4c2105755d11b63ecb2427 Author: Rick Macklem <rmacklem@FreeBSD.org> AuthorDate: 2025-01-10 03:54:41 +0000 Commit: Rick Macklem <rmacklem@FreeBSD.org> CommitDate: 2025-01-24 02:30:22 +0000 nfscl: Fix a crash when a readdir entry has nul in it Commit 026cdaa3b3a9 added a check for a nul or "/" in a file name in a readdir reply. Unfortunately, the minimal testing done on it did not detect a bug that can cause the client to crash. This patch fixes the code so that it does not crash. Note that a NFS server will not normally return a file name in a readdir reply that has a nul or "/" in it, so the crash is unlikely. PR: 283965 (cherry picked from commit f9f0a1d61c7b97c705246c747baec385e0592966) --- sys/fs/nfsclient/nfs_clrpcops.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/sys/fs/nfsclient/nfs_clrpcops.c b/sys/fs/nfsclient/nfs_clrpcops.c index b3062b5a5d88..f3ab2bda8f85 100644 --- a/sys/fs/nfsclient/nfs_clrpcops.c +++ b/sys/fs/nfsclient/nfs_clrpcops.c @@ -3079,6 +3079,7 @@ nfsrpc_readdir(vnode_t vp, struct uio *uiop, nfsuint64 *cookiep, nfsattrbit_t attrbits, dattrbits; u_int32_t rderr, *tl2 = NULL; size_t tresid; + bool validentry; KASSERT(uiop->uio_iovcnt == 1 && (uiop->uio_resid & (DIRBLKSIZ - 1)) == 0, @@ -3305,6 +3306,7 @@ nfsrpc_readdir(vnode_t vp, struct uio *uiop, nfsuint64 *cookiep, /* loop through the dir entries, doctoring them to 4bsd form */ while (more_dirs && bigenough) { + validentry = true; if (nd->nd_flag & ND_NFSV4) { NFSM_DISSECT(tl, u_int32_t *, 3*NFSX_UNSIGNED); ncookie.lval[0] = *tl++; @@ -3384,6 +3386,7 @@ nfsrpc_readdir(vnode_t vp, struct uio *uiop, nfsuint64 *cookiep, uiop->uio_offset = savoff; uiop->uio_resid = savresid; blksiz = savblksiz; + validentry = false; } else { cp = uiop->uio_iov->iov_base; tlen -= len; @@ -3421,7 +3424,7 @@ nfsrpc_readdir(vnode_t vp, struct uio *uiop, nfsuint64 *cookiep, ncookie.lval[0] = 0; ncookie.lval[1] = *tl++; } - if (bigenough) { + if (bigenough && validentry) { if (nd->nd_flag & ND_NFSV4) { if (rderr) { dp->d_fileno = 0; @@ -3560,7 +3563,7 @@ nfsrpc_readdirplus(vnode_t vp, struct uio *uiop, nfsuint64 *cookiep, size_t tresid; u_int32_t *tl2 = NULL, rderr; struct timespec dctime, ts; - bool attr_ok; + bool attr_ok, validentry; KASSERT(uiop->uio_iovcnt == 1 && (uiop->uio_resid & (DIRBLKSIZ - 1)) == 0, @@ -3771,6 +3774,7 @@ nfsrpc_readdirplus(vnode_t vp, struct uio *uiop, nfsuint64 *cookiep, /* loop through the dir entries, doctoring them to 4bsd form */ while (more_dirs && bigenough) { + validentry = true; NFSM_DISSECT(tl, u_int32_t *, 3 * NFSX_UNSIGNED); if (nd->nd_flag & ND_NFSV4) { ncookie.lval[0] = *tl++; @@ -3846,6 +3850,7 @@ nfsrpc_readdirplus(vnode_t vp, struct uio *uiop, nfsuint64 *cookiep, uiop->uio_offset = savoff; uiop->uio_resid = savresid; blksiz = savblksiz; + validentry = false; } else { cp = uiop->uio_iov->iov_base; tlen -= len; @@ -3902,7 +3907,7 @@ nfsrpc_readdirplus(vnode_t vp, struct uio *uiop, nfsuint64 *cookiep, goto nfsmout; } - if (bigenough) { + if (bigenough && validentry) { if (nd->nd_flag & ND_NFSV4) { if (rderr) { dp->d_fileno = 0;