From dwmalone@maths.tcd.ie  Sat Feb  1 16:19:24 1997
Received: from salmon.maths.tcd.ie (mmdf@salmon.maths.tcd.ie [134.226.81.11])
          by freefall.freebsd.org (8.8.5/8.8.5) with SMTP id QAA18596;
          Sat, 1 Feb 1997 16:19:22 -0800 (PST)
Received: from graves.maths.tcd.ie by salmon.maths.tcd.ie  with SMTP id aa22105;
          2 Feb 97 0:19 +0000
Message-Id: <9702020019.aa00900@graves.maths.tcd.ie>
Date: Sun, 2 Feb 97 0:19:13 +0000
From: dwmalone@maths.tcd.ie
Sender: dwmalone@maths.tcd.ie
Reply-To: dwmalone@maths.tcd.ie
To: FreeBSD-gnats-submit@freebsd.org
Cc: dwmalone@maths.tcd.ie, iedowse@maths.tcd.ie, mpp@freebsd.org
Subject: NFS cache and access permissions.
X-Send-Pr-Version: 3.2

>Number:         2635
>Category:       kern
>Synopsis:       NFS cache doesn't check execute permission on directories
>Confidential:   no
>Severity:       critical
>Priority:       high
>Responsible:    dfr
>State:          closed
>Quarter:
>Keywords:
>Date-Required:
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Sat Feb  1 16:20:01 PST 1997
>Closed-Date:    Fri May 9 06:14:08 PDT 1997
>Last-Modified:  Fri May  9 06:19:45 PDT 1997
>Originator:     David Malone
>Release:        FreeBSD 2.2-GAMMA i386
>Organization:
School of Maths, Trinity College, Dublin.
>Environment:

	FreeBSD-2.2-GAMMA and FreeBSD-stable NFS clients.
	Probably current too ( based on a quick look at nfs_vnops.c ).

>Description:

	This bug is similar, but NOT the same as kern/876.

	Suppose a user has permission to read the file /a/b/c, but
	should not be able to because the directory /a/b is not
	executable by them. If /a/b is in the NFS client cache it
	will allow them to read the file, as the cache code does't
	check for executability of the containing directory.

	This came to note because the web server was stating a file
	as root, and then serving it as nobody, when it should not
	have been able to. If you have NFS mounted home directories
	it means users stand a good chance of being able to view one
	anothers files.

	For some reason lstat'ing a file in the directory in question
	seems to invalidate the cache.


>How-To-Repeat:

[As nobody]

18:37:salmon 29% cat ~dwmalone/.mail/incoming_mail
cat: /u2/system/dwmalone/.mail/incoming_mail: Permission denied

[As dwmalone]

salmon 7% ls -ld incoming_mail .
-rw-r--r--   1 dwmalone  system  32888 Feb  1 17:56 incoming_mail
drws------  18 dwmalone  system   1024 Feb  1 16:11 .
salmon 8% cat incoming_mail  
blah blah blah

[As nobody]

19:38:salmon 33% cat ~dwmalone/.mail/incoming_mail
blah blah blah

[As dwmalone]

salmon 9% perl -e 'lstat("incoming_mail");'

[As nobody]

19:38:salmon 33% cat ~dwmalone/.mail/incoming_mail
cat: /u2/system/dwmalone/.mail/incoming_mail: Permission denied


>Fix:
	
In sys/nfs/nfs_vops.c we found that nfs_lookup does not check for
executability of a directory. Presumably this is OK if you are not
looking in the NFS attribute cache, as the NFS server should do the
check for you. We made the following patch, following
sys/ufs/ufs/ufs_lookup.c as a guideline. It seems to work ( fingers
crossed ), and only does the check if we are looking in the cache.
On the other hand, there may be locking or stuff to be done we don't
know about.


*** /FreeBSD/FreeBSD-2.2/src/sys/nfs/nfs_vnops.c	Wed Jan  8 23:50:18 1997
--- ./nfs_vnops.c	Sat Feb  1 23:10:53 1997
***************
*** 840,845 ****
--- 840,849 ----
  	if ((error = cache_lookup(dvp, vpp, cnp)) && error != ENOENT) {
  		struct vattr vattr;
  		int vpid;
+ 		
+ 		if (error=VOP_ACCESS(dvp,VEXEC,cnp->cn_cred,cnp->cn_proc)) {
+ 			return (error);
+ 		}
  
  		newvp = *vpp;
  		vpid = newvp->v_id;

>Release-Note:
>Audit-Trail:

From: Bruce Evans <bde@zeta.org.au>
To: dwmalone@maths.tcd.ie, FreeBSD-gnats-submit@FreeBSD.ORG
Cc: iedowse@maths.tcd.ie, mpp@FreeBSD.ORG
Subject: Re: kern/2635: NFS cache and access permissions.
Date: Mon, 3 Feb 1997 01:38:39 +1100

 >	For some reason lstat'ing a file in the directory in question
 >	seems to invalidate the cache.
 
 I fixed this locally a year or two ago, but no one (except Terry :-)
 seemed interested in reviewing my patch or fixing it properly.  It was
 broken in 4.4Lite to support symlinks inheriting attributes from the
 parent directory.  I forget what the penalty for invalidating the
 cache is.
 
 Bruce
 
 diff -c2 vfs_lookup.c~ vfs_lookup.c
 *** vfs_lookup.c~	Wed Jan 15 05:06:10 1997
 --- vfs_lookup.c	Wed Jan 15 05:06:11 1997
 ***************
 *** 276,281 ****
   	wantparent = cnp->cn_flags & (LOCKPARENT | WANTPARENT);
   	docache = (cnp->cn_flags & NOCACHE) ^ NOCACHE;
   	if (cnp->cn_nameiop == DELETE ||
 ! 	    (wantparent && cnp->cn_nameiop != CREATE))
   		docache = 0;
   	rdonly = cnp->cn_flags & RDONLY;
 --- 273,290 ----
   	wantparent = cnp->cn_flags & (LOCKPARENT | WANTPARENT);
   	docache = (cnp->cn_flags & NOCACHE) ^ NOCACHE;
 + 	/*
 + 	 * XXX the following seems to be just to recover from not setting
 + 	 * NOCACHE for the DELETE cases (unlink, rmdir and the rename
 + 	 * source).  In BSD4.4lite[2], docache was also cleared for the
 + 	 * (wantparent && cnp->cn_nameiop == LOOKUP) case.  This case
 + 	 * seems to only occur for lstat and olstat, when it is wrong
 + 	 * to clear docache.  This case probably didn't occur before
 + 	 * BSD4.4lite.  LOCKPARENT was introduced for lstat to support
 + 	 * the new behaviour of symlinks (attributes inherited from the
 + 	 * parent.
 + 	 */
   	if (cnp->cn_nameiop == DELETE ||
 ! 	    (wantparent && cnp->cn_nameiop != CREATE &&
 ! 	     cnp->cn_nameiop != LOOKUP))
   		docache = 0;
   	rdonly = cnp->cn_flags & RDONLY;

From: David Malone <dwmalone@maths.tcd.ie>
To: Bruce Evans <bde@zeta.org.au>
Cc: dwmalone@maths.tcd.ie, FreeBSD-gnats-submit@freebsd.org,
        iedowse@maths.tcd.ie
Subject: Re: kern/2635: NFS cache and access permissions. 
Date: Thu, 06 Feb 1997 00:12:38 GMT

 > >	For some reason lstat'ing a file in the directory in question
 > >	seems to invalidate the cache.
 > 
 > I fixed this locally a year or two ago, but no one (except Terry :-)
 > seemed interested in reviewing my patch or fixing it properly.  It was
 > broken in 4.4Lite to support symlinks inheriting attributes from the
 > parent directory.  I forget what the penalty for invalidating the
 > cache is.
 
 I guess haveing a way to invalidate the cache is useful in some
 ways. Here we have maildrops in peoples home directories, and
 sometimes you get alerted you have newmail, type "inc" and inc
 says "no new mail".
 
 A quick ls -l of your home directory fixes this though ;-)
 
 Mind you - still leaves me with the problem that people can read
 files they shouldn't be able too.
 
 	David.

From: dwmalone@maths.tcd.ie
To: freebsd-gnats-submit@freebsd.org, dwmalone@maths.tcd.ie
Cc:  Subject: Re: kern/2635: NFS cache doesn't check execute permission on directori
Date: Sun, 4 May 97 19:46:25 +0100

 I've been using the patch which I submitted for 3 months
 now on both 2.1.7.1 and 2.2.1 machines with no problems
 that seem to be related to it. I checked the current
 source today, and it looks like the problem has not
 been fixed by the lite2 merge or any of the work that
 has gone on.
 
 I guess anyone that knows the vfs stuff well should be
 able to review the patch quite quickly.
 
 	David.
 
 >*** /FreeBSD/FreeBSD-2.2/src/sys/nfs/nfs_vnops.c        Wed Jan  8 23:50:18 199
 >7
 >--- ./nfs_vnops.c       Sat Feb  1 23:10:53 1997
 >***************
 >*** 840,845 ****
 >--- 840,849 ----
 >        if ((error = cache_lookup(dvp, vpp, cnp)) &amp;&amp; error != ENOENT) {
 >                struct vattr vattr;
 >                int vpid;
 >+
 >+               if (error=VOP_ACCESS(dvp,VEXEC,cnp-&gt;cn_cred,cnp-&gt;cn_proc)
 >) {
 >+                       return (error);
 >+               }
 >
 >                newvp = *vpp;
 
Responsible-Changed-From-To: freebsd-bugs->dfr 
Responsible-Changed-By: dfr 
Responsible-Changed-When: Tue May 6 03:12:23 PDT 1997 
Responsible-Changed-Why:  
Time to fix this one. 
State-Changed-From-To: open->closed 
State-Changed-By: dfr 
State-Changed-When: Fri May 9 06:14:08 PDT 1997 
State-Changed-Why:  
Fixed in rev 1.48 of nfs_vnops.c. 
>Unformatted:
