Date: Thu, 30 Nov 2000 05:30:53 -0800 (PST) From: tmoestl@gmx.net To: freebsd-gnats-submit@FreeBSD.org Subject: kern/23191: [PATCH] Fix for panics in lookup() after forced unmount Message-ID: <200011301330.eAUDUrs16435@freefall.freebsd.org>
next in thread | raw e-mail | index | archive | help
>Number: 23191 >Category: kern >Synopsis: [PATCH] Fix for panics in lookup() after forced unmount >Confidential: no >Severity: non-critical >Priority: medium >Responsible: freebsd-bugs >State: open >Quarter: >Keywords: >Date-Required: >Class: sw-bug >Submitter-Id: current-users >Arrival-Date: Thu Nov 30 05:40:00 PST 2000 >Closed-Date: >Last-Modified: >Originator: Thomas Moestl >Release: FreeBSD 4.2-STABLE >Organization: >Environment: FreeBSD crow.local 4.2-STABLE FreeBSD 4.2-STABLE #19: Sun Nov 26 01:04:14 CET 2000 root@crow.local:/usr/src/sys/compile/CROW i386 >Description: This is a fix for a problem described in PR kern/19572. It was recently discussed at -hackers. The problem is a null-pointer dereference that happens in kern/vfs_lookup.c when accessing ".." with a v_mount entry for the current directory vnode of NULL. This happens when a volume is forcibly unmounted, and the vnode for a working directory in the mounted volume is cleared. >How-To-Repeat: cd into a mountpoint, forcibly unmount the volume, and try to access "..": mount /cdrom cd /cdrom umount -f /cdrom ls .. >Fix: The following patch should fix the problem, as discussed on -hackers. It is against 4.2-STABLE, but it applies (with minor offsets) to -CURRENT, and there seems to not have changed anything that could make the patch break. If this gets mangled, the patch is also at http://home.t-online.de/home/Moestl/lookup-dotdot.diff *** 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; >Release-Note: >Audit-Trail: >Unformatted: To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-bugs" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200011301330.eAUDUrs16435>