Subject: misc/3049: mount_union allows non-absolute paths to mount point
To: None <gnats-bugs@gnats.netbsd.org>
From: Eric Fischer <eric@fudge.uchicago.edu>
List: netbsd-bugs
Date: 12/19/1996 16:42:54
>Number:         3049
>Category:       misc
>Synopsis:       mount_union allows non-absolute paths to mount point
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    misc-bug-people (Misc Bug People)
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Thu Dec 19 15:05:00 1996
>Last-Modified:
>Originator:     Eric Fischer
>Organization:
University of Chicago Advanced Research Systems
>Release:        1.2
>Environment:
System: NetBSD fudge 1.2 NetBSD 1.2 (FUDGE) #43: Tue Dec 10 22:23:26 CST 1996 eric@fudge:/usr/src/sys/arch/sparc/compile/FUDGE sparc


>Description:

mount_union doesn't require that the mount point be an absolute
path, but umount does turn relative paths into absolute ones,
so you can't easily unmount a union-mounted directory if you
weren't careful when you mounted it.

>How-To-Repeat:

Mount a union directory on top of a directory but don't give the
full path to the mount point.  Then try to unmount it:

$ mkdir blah
$ mount_union /etc blah
$ df blah
Filesystem   1K-blocks     Used    Avail Capacity  Mounted on
<above>:/etc   1460760  1432977    25296    98%    blah
$ umount blah
umount: /usr/src/sbin/mount_union/blah: not currently mounted

>Fix:

Always give the mount point as an absolute path.  Or patch
mount_union to force the path to be absolute:

diff -rc ../mount_union.orig/mount_union.c ./mount_union.c
*** ../mount_union.orig/mount_union.c	Thu Dec 19 14:10:30 1996
--- ./mount_union.c	Thu Dec 19 14:23:03 1996
***************
*** 78,84 ****
  {
  	struct union_args args;
  	int ch, mntflags;
! 	char target[MAXPATHLEN];
  
  	mntflags = 0;
  	args.mntflags = UNMNT_ABOVE;
--- 78,84 ----
  {
  	struct union_args args;
  	int ch, mntflags;
! 	char target[MAXPATHLEN], mntpnt[MAXPATHLEN];
  
  	mntflags = 0;
  	args.mntflags = UNMNT_ABOVE;
***************
*** 109,121 ****
  	if (realpath(argv[0], target) == 0)
  		err(1, "%s", target);
  
! 	if (subdir(target, argv[1]) || subdir(argv[1], target))
! 		errx(1, "%s (%s) and %s are not distinct paths",
! 		    argv[0], target, argv[1]);
  
  	args.target = target;
  
! 	if (mount(MOUNT_UNION, argv[1], mntflags, &args))
  		err(1, NULL);
  	exit(0);
  }
--- 109,124 ----
  	if (realpath(argv[0], target) == 0)
  		err(1, "%s", target);
  
! 	if (realpath(argv[1], mntpnt) == 0)
! 		err(1, "%s", mntpnt);
! 
! 	if (subdir(target, mntpnt) || subdir(mntpnt, target))
! 		errx(1, "%s (%s) and %s (%s) are not distinct paths",
! 		    argv[0], target, argv[1], mntpnt);
  
  	args.target = target;
  
! 	if (mount(MOUNT_UNION, mntpnt, mntflags, &args))
  		err(1, NULL);
  	exit(0);
  }
>Audit-Trail:
>Unformatted: