nfscl: Fix a crash when a readdir entry has nul in it
Commit 026cdaa3b3 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
Reported by: asomers
Tested by: asomers
MFC after: 2 weeks
This commit is contained in:
@@ -3397,6 +3397,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,
|
||||
@@ -3622,6 +3623,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++;
|
||||
@@ -3701,6 +3703,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;
|
||||
@@ -3738,7 +3741,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;
|
||||
@@ -3875,7 +3878,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,
|
||||
@@ -4086,6 +4089,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++;
|
||||
@@ -4161,6 +4165,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;
|
||||
@@ -4217,7 +4222,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;
|
||||
|
||||
Reference in New Issue
Block a user