Fix two bugs in nfs_readdirplus(). The first is that in some cases,

vnodes are locked and never unlocked, which leads to processes starting
to wedge up after doing a mount -o nfsv3,tcp,rdirplus foo:/fs /fs; ls /fs.
The second is that sometimes cnp is accessed without having been
properly initialized: cnp->cn_nameptr points to an earlier name while
"len" contains the length of a current name of different size. This
leads to an attempt to dereference *(cn->cn_nameptr + len) which will
sometimes cause a page fault and a panic.

With these two fixes, client side readdirplus works correctly with
FreeBSD, IRIX 6.5.4 and Solaris 2.5.1 and 2.6 servers.

Submitted by: Matthew Dillon <dillon@backplane.com>
This commit is contained in:
Bill Paul 1999-07-30 04:02:04 +00:00
parent ac02226555
commit f069164876
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=49237
2 changed files with 12 additions and 6 deletions

View File

@ -34,7 +34,7 @@
* SUCH DAMAGE.
*
* @(#)nfs_vnops.c 8.16 (Berkeley) 5/27/95
* $Id: nfs_vnops.c,v 1.134 1999/06/30 02:53:51 julian Exp $
* $Id: nfs_vnops.c,v 1.135 1999/07/01 13:32:54 peter Exp $
*/
@ -2343,7 +2343,7 @@ nfs_readdirplusrpc(vp, uiop, cred)
newvp = NFSTOV(np);
}
}
if (doit) {
if (doit && bigenough) {
dpossav2 = dpos;
dpos = dpossav1;
mdsav2 = md;
@ -2367,7 +2367,10 @@ nfs_readdirplusrpc(vp, uiop, cred)
nfsm_adv(nfsm_rndup(i));
}
if (newvp != NULLVP) {
vrele(newvp);
if (newvp == vp)
vrele(newvp);
else
vput(newvp);
newvp = NULLVP;
}
nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED);

View File

@ -34,7 +34,7 @@
* SUCH DAMAGE.
*
* @(#)nfs_vnops.c 8.16 (Berkeley) 5/27/95
* $Id: nfs_vnops.c,v 1.134 1999/06/30 02:53:51 julian Exp $
* $Id: nfs_vnops.c,v 1.135 1999/07/01 13:32:54 peter Exp $
*/
@ -2343,7 +2343,7 @@ nfs_readdirplusrpc(vp, uiop, cred)
newvp = NFSTOV(np);
}
}
if (doit) {
if (doit && bigenough) {
dpossav2 = dpos;
dpos = dpossav1;
mdsav2 = md;
@ -2367,7 +2367,10 @@ nfs_readdirplusrpc(vp, uiop, cred)
nfsm_adv(nfsm_rndup(i));
}
if (newvp != NULLVP) {
vrele(newvp);
if (newvp == vp)
vrele(newvp);
else
vput(newvp);
newvp = NULLVP;
}
nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED);