Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 23 Jul 1997 00:07:13 +1000
From:      Bruce Evans <bde@zeta.org.au>
To:        current@freebsd.org
Cc:        dfr@freebsd.org
Subject:   more WebNFS merge bugs, one serious
Message-ID:  <199707221407.AAA30817@godzilla.zeta.org.au>

next in thread | raw e-mail | index | archive | help
The WebNFS merge broke binary compatiblity of mount_msdos for the same
reason that it broke binary compatiblity of mount_cd9660.  The usual
symptom is bizarre modes for all files under the mount point.  This is
because for old mount binaries, the extra field in export_args is taken
from the uid arg, the uid arg is taken from the gid arg, the mode arg
is taken from stack garbage, and the corrupted args affect everything
under the mount point.

The WebNFS merge also broke nfs_namei() by deleting the `*retdirp = dp;'
line.  This usually causes nfserv_create() to panic and probably causes
vnode reference leaks in other callers.  nfserv_create() panics because
it is sloppy about checking `dirp == 0' and usually accesses the null
dirp's set by nfs_namei().  Other callers are apparently more careful.
ome callers have bogus initializations of dirp to 0.  nfs_namei() always
initializes it, and the initializations have style bugs.  I haven't fixed
bugs in the callers.

This diff was obtained by comparing the current, old and NetBSD versions.
It also fixes a memory leak for symlinks with ndp->ni_pathlen == 1,
and removes a superfluous initialization of cnp->cn_proc, and changes
the style to match NetBSD's.  I don't know if we still need the hash
calculations.

Bruce

diff -c2 nfs_subs.c~ nfs_subs.c
*** nfs_subs.c~	Thu Jul 17 18:46:34 1997
--- nfs_subs.c	Tue Jul 22 22:32:35 1997
***************
*** 1456,1460 ****
--- 1454,1461 ----
  	md = *mdp;
  	rem = mtod(md, caddr_t) + md->m_len - fromcp;
+ #ifdef __FreeBSD__
+ 	/* XXX why is this in FreeBSD but not in NetBSD? */
  	cnp->cn_hash = 0;
+ #endif
  	for (i = 0; i < len; i++) {
  		while (rem == 0) {
***************
*** 1471,1475 ****
--- 1472,1479 ----
  			goto out;
  		}
+ #ifdef __FreeBSD__
+ 	/* XXX why is this in FreeBSD but not in NetBSD? */
  		cnp->cn_hash += (unsigned char)*fromcp;
+ #endif
  		*tocp++ = *fromcp++;
  		rem--;
***************
*** 1482,1486 ****
  		if (rem >= len)
  			*dposp += len;
! 		else if (error = nfs_adv(mdp, dposp, len, rem))
  			goto out;
  	}
--- 1486,1490 ----
  		if (rem >= len)
  			*dposp += len;
! 		else if ((error = nfs_adv(mdp, dposp, len, rem)) != 0)
  			goto out;
  	}
***************
*** 1502,1505 ****
--- 1506,1511 ----
  		cnp->cn_flags |= RDONLY;
  
+ 	*retdirp = dp;
+ 
  	if (pubflag) {
  		/*
***************
*** 1561,1565 ****
  			dp = rootvnode;
  	} else {
!   		cnp->cn_flags |= NOCROSSMOUNT;
  	}
  
--- 1567,1571 ----
  			dp = rootvnode;
  	} else {
! 		cnp->cn_flags |= NOCROSSMOUNT;
  	}
  
***************
*** 1567,1571 ****
  	VREF(dp);
  
!       for (;;) {
  	cnp->cn_nameptr = cnp->cn_pnbuf;
  	ndp->ni_startdir = dp;
--- 1573,1577 ----
  	VREF(dp);
  
!     for (;;) {
  	cnp->cn_nameptr = cnp->cn_pnbuf;
  	ndp->ni_startdir = dp;
***************
*** 1573,1578 ****
  	 * And call lookup() to do the real work
  	 */
! 	cnp->cn_proc = p;
! 	if (error = lookup(ndp))
  		break;
  	/*
--- 1579,1584 ----
  	 * And call lookup() to do the real work
  	 */
! 	error = lookup(ndp);
! 	if (error)
  		break;
  	/*
***************
*** 1601,1605 ****
  			break;
  		}
! 		if (ndp->ni_pathlen > 0)
  			MALLOC(cp, char *, MAXPATHLEN, M_NAMEI, M_WAITOK);
  		else
--- 1607,1611 ----
  			break;
  		}
! 		if (ndp->ni_pathlen > 1)
  			MALLOC(cp, char *, MAXPATHLEN, M_NAMEI, M_WAITOK);
  		else
***************
*** 1648,1652 ****
  		}
  	}
!       }
  out:
  	FREE(cnp->cn_pnbuf, M_NAMEI);
--- 1654,1658 ----
  		}
  	}
!    }
  out:
  	FREE(cnp->cn_pnbuf, M_NAMEI);



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199707221407.AAA30817>