From owner-freebsd-hackers Sun Nov 26 10: 6:16 2000 Delivered-To: freebsd-hackers@freebsd.org Received: from mail.gmx.net (pop.gmx.net [194.221.183.20]) by hub.freebsd.org (Postfix) with SMTP id 13B9A37B479 for ; Sun, 26 Nov 2000 10:06:13 -0800 (PST) Received: (qmail 26945 invoked by uid 0); 26 Nov 2000 18:06:11 -0000 Received: from p3e9bc32c.dip.t-dialin.net (HELO forge.local) (62.155.195.44) by mail.gmx.net (mail10) with SMTP; 26 Nov 2000 18:06:11 -0000 Received: from thomas by forge.local with local (Exim 3.12 #1 (Debian)) id 1406AX-0000In-00 for ; Sun, 26 Nov 2000 19:04:53 +0100 Date: Sun, 26 Nov 2000 19:04:53 +0100 To: freebsd-hackers@freebsd.org Subject: [PATCH] Fix for panics in lookup() after forced unmount Message-ID: <20001126190453.A1157@crow.dom2ip.de> Mail-Followup-To: tmoestl@gmx.net, freebsd-hackers@freebsd.org Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline User-Agent: Mutt/1.2.5i From: Thomas Moestl Sender: owner-freebsd-hackers@FreeBSD.ORG Precedence: bulk X-Loop: FreeBSD.ORG Hi, I think I have a sufficient fix for PR kern/19572. Could somebody please Review/Comment this? To quote: > Description > Executing cd ../cdrom from /cdrom directory after cycle of mount-umount- > mount cycle causes trap 12 (page fault while in kernel mode) and hence > causes kernel panic. > How-To-Repeat > chdir to /cdrom (which) is default mount point for cdrom as per fstab. > mount /cdrom and do ls > now umount -f /cdrom (force as we will be /cdrom) > doing ls will give error( . not a directory) > do mount /cdrom to mount the cdrom once again (we are still in /cdrom dir) > now do ls will give error once again > now do cd ../ (tab in case of bash or esc in case of csh) to do file > completion. > This will result in trap 12 (page fault in kernel mode) and thus > results in kernel panic. Actually, the panic will occur after a simple forced unmount of the current working directory and subsequent try to access "..". This is because the vnode of the cwd was cleared and it's v_mount member was set to NULL. This member is however dereferenced in the handling for the ".." special case in lookup(), causing a panic. The fix is rather trivial, just check the member before using it and return an appropriate error. In the following patch, I use EBADF. Btw, after taking a look into the OpenBSD and NetBSD repos, I think they might have the same problem. Is there any standard channel to pass bug reports to them from FreeBSD, or should I just use the normal submit procedure? - Thomas The patch: ------------------------------------------------------------------------ *** old/kern/vfs_lookup.c Sat Nov 25 23:55:39 2000 --- new/kern/vfs_lookup.c Sun Nov 26 00:58:15 2000 *************** *** 403,408 **** --- 403,412 ---- if ((dp->v_flag & VROOT) == 0 || (cnp->cn_flags & NOCROSSMOUNT)) break; + if (dp->v_mount == NULL) { /* forced unmount */ + error = EBADF; + goto bad; + } tdp = dp; dp = dp->v_mount->mnt_vnodecovered; vput(tdp); *************** *** 424,430 **** printf("not found\n"); #endif if ((error == ENOENT) && ! (dp->v_flag & VROOT) && (dp->v_mount->mnt_flag & MNT_UNION)) { tdp = dp; dp = dp->v_mount->mnt_vnodecovered; --- 428,434 ---- printf("not found\n"); #endif if ((error == ENOENT) && ! (dp->v_flag & VROOT) && (dp->v_mount != NULL) && (dp->v_mount->mnt_flag & MNT_UNION)) { tdp = dp; dp = dp->v_mount->mnt_vnodecovered; *************** *** 502,507 **** --- 506,517 ---- ((cnp->cn_flags & FOLLOW) || trailing_slash || *ndp->ni_next == '/')) { cnp->cn_flags |= ISSYMLINK; + if (dp->v_mount == NULL) { + /* We can't know whether the directory was mounted with + * NOSYMFOLLOW, so we can't follow safely. */ + error = EBADF; + goto bad2; + } if (dp->v_mount->mnt_flag & MNT_NOSYMFOLLOW) { error = EACCES; goto bad2; To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-hackers" in the body of the message