From tom@bozon.Stanford.EDU  Sun Oct 19 20:02:55 1997
Received: from bozon.Stanford.EDU (tom@tip-mp5-ncs-15.Stanford.EDU [36.173.0.110])
          by hub.freebsd.org (8.8.7/8.8.7) with ESMTP id UAA20823
          for <FreeBSD-gnats-submit@freebsd.org>; Sun, 19 Oct 1997 20:02:52 -0700 (PDT)
          (envelope-from tom@bozon.Stanford.EDU)
Received: (from tom@localhost)
          by bozon.Stanford.EDU (8.8.7/8.8.4)
	  id UAA01419; Sun, 19 Oct 1997 20:02:42 -0700 (PDT)
Message-Id: <199710200302.UAA01419@bozon.Stanford.EDU>
Date: Sun, 19 Oct 1997 20:02:42 -0700 (PDT)
From: pavel@slac.stanford.edu
Reply-To: pavel@slac.stanford.edu
To: FreeBSD-gnats-submit@freebsd.org
Subject: Access checks in msdosfs_mount()
X-Send-Pr-Version: 3.2

>Number:         4810
>Category:       kern
>Synopsis:       Access checks in msdosfs_mount()
>Confidential:   no
>Severity:       non-critical
>Priority:       medium
>Responsible:    freebsd-bugs
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Sun Oct 19 20:10:01 PDT 1997
>Closed-Date:    Wed Apr 15 11:05:04 PDT 1998
>Last-Modified:  Wed Apr 15 11:08:40 PDT 1998
>Originator:     Tom Pavel
>Release:        FreeBSD 2.2-STABLE i386
>Organization:
Stanford Linear Accelerator Center
>Environment:

	

>Description:

	I noticed this problem because I use a setuid wrapper to allow
non-privileged users to mount /def/fd0 as /floppy.  I have noticed that
this wrapper works fine for the cd9660 fs (/dev/wcd0c on /cdrom), but
fails for msdos fs unless the setuid wrapper is executed by root.

I have now traced to problem to the following code in msdosfs_vfsops.c:
------------------------------------------------------
	/*
	 * check to see that the user in owns the target directory.
	 * Note the very XXX trick to make sure we're checking as the
	 * real user -- were mount() executable by anyone, this wouldn't
	 * be a problem.
	 *
	 * XXX there should be one consistent error out.
	 */
	cred = crdup(p->p_ucred);			/* XXX */
	cred->cr_uid = p->p_cred->p_ruid;		/* XXX */
	error = VOP_GETATTR(mp->mnt_vnodecovered, &va, cred, p);
	if (error) {
		crfree(cred);				/* XXX */
		return error;
	}
	if (cred->cr_uid != 0) {
		if (va.va_uid != cred->cr_uid) {
			error = EACCES;
			crfree(cred);			/* XXX */
			return error;
		}

		/* a user mounted it; we'll verify permissions when unmounting */
		mp->mnt_flag |= MNT_USER;
	}
------------------------------------------------------

This code seems intent on checking only the real uid.  Perhaps that
semantics is required for some part of the msdosfs security model, but
I find it incovenient and I can't see the justification.  If the euid
of the process doing the mount is root, then I think the mount should
be allowed.

>How-To-Repeat:

	

>Fix:
	
	Not sure of the best fix.  Perhaps just change:

		if (cred->cr_uid != 0) {

	to:
		if (p->p_ucred->cr_uid != 0 && p->p_cred->p_ruid != 0) {



Tom Pavel

Stanford Linear Accelerator Center
pavel@slac.stanford.edu
>Release-Note:
>Audit-Trail:

From: Bruce Evans <bde@zeta.org.au>
To: FreeBSD-gnats-submit@FreeBSD.ORG, pavel@slac.stanford.edu
Cc:  Subject: Re: kern/4810: Access checks in msdosfs_mount()
Date: Tue, 21 Oct 1997 13:58:18 +1000

 >>Description:
 >
 >	I noticed this problem because I use a setuid wrapper to allow
 >non-privileged users to mount /def/fd0 as /floppy.  I have noticed that
 >this wrapper works fine for the cd9660 fs (/dev/wcd0c on /cdrom), but
 >fails for msdos fs unless the setuid wrapper is executed by root.
 >
 >I have now traced to problem to the following code in msdosfs_vfsops.c:
 >------------------------------------------------------
 >	/*
 >	 * check to see that the user in owns the target directory.
 >	 * Note the very XXX trick to make sure we're checking as the
 >	 * real user -- were mount() executable by anyone, this wouldn't
 >	 * be a problem.
 >...
 >This code seems intent on checking only the real uid.  Perhaps that
 >semantics is required for some part of the msdosfs security model, but
 >I find it incovenient and I can't see the justification.  If the euid
 >of the process doing the mount is root, then I think the mount should
 >be allowed.
 
 In -current, mount(2) _is_ executable by anyone, and anyone can mount
 anything (nosuid nodev) on any directory that they own.  Only the euid
 is checked (except in poorly maintained file systems like msdosfs).
 This is too insecure for a release (anyone can deny service by mounting
 any unmounted device) but it shows what msdosfs should do.
 
 This doesn't work in 2.2, because mount_msdos(8) is setuid root to
 get around the restriction on mount(2), so the euid is always root in
 msdosfs_mount().  The "very XXX trick" attempts to recover the previous
 euid by using the ruid.
 
 Fix for 2.2: remove the setuid bit from mount_msdos and change the ruid
 checking to euid checking.  Then add the desired insecurities using a
 wrapper.
 
 Fix for -current: remove the setuid bit from mount_msdos and remove all
 uid checking from msdosfs.  Somehow fix the insecurities (require at
 least read permission on the device being opened?).
 
 Bruce
State-Changed-From-To: open->closed 
State-Changed-By: dt 
State-Changed-When: Wed Apr 15 11:05:04 PDT 1998 
State-Changed-Why:  
The problem is fixed in -current. 
Nothing can be done in 2.2 
>Unformatted:
