Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 26 Nov 2000 19:04:53 +0100
From:      Thomas Moestl <tmoestl@gmx.net>
To:        freebsd-hackers@freebsd.org
Subject:   [PATCH] Fix for panics in lookup() after forced unmount
Message-ID:  <20001126190453.A1157@crow.dom2ip.de>

next in thread | raw e-mail | index | archive | help
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




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