From owner-freebsd-current Tue Jul 22 07:11:34 1997 Return-Path: Received: (from root@localhost) by hub.freebsd.org (8.8.5/8.8.5) id HAA00373 for current-outgoing; Tue, 22 Jul 1997 07:11:34 -0700 (PDT) Received: from godzilla.zeta.org.au (godzilla.zeta.org.au [203.2.228.19]) by hub.freebsd.org (8.8.5/8.8.5) with ESMTP id HAA00364; Tue, 22 Jul 1997 07:11:25 -0700 (PDT) Received: (from bde@localhost) by godzilla.zeta.org.au (8.8.5/8.6.9) id AAA30817; Wed, 23 Jul 1997 00:07:13 +1000 Date: Wed, 23 Jul 1997 00:07:13 +1000 From: Bruce Evans Message-Id: <199707221407.AAA30817@godzilla.zeta.org.au> To: current@freebsd.org Subject: more WebNFS merge bugs, one serious Cc: dfr@freebsd.org Sender: owner-freebsd-current@freebsd.org X-Loop: FreeBSD.org Precedence: bulk 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);