From owner-freebsd-fs@FreeBSD.ORG Mon Apr 2 14:31:47 2012 Return-Path: Delivered-To: freebsd-fs@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id E935B1065672; Mon, 2 Apr 2012 14:31:47 +0000 (UTC) (envelope-from jhb@freebsd.org) Received: from bigwig.baldwin.cx (bigknife-pt.tunnel.tserv9.chi1.ipv6.he.net [IPv6:2001:470:1f10:75::2]) by mx1.freebsd.org (Postfix) with ESMTP id 92F898FC14; Mon, 2 Apr 2012 14:31:47 +0000 (UTC) Received: from jhbbsd.localnet (unknown [209.249.190.124]) by bigwig.baldwin.cx (Postfix) with ESMTPSA id EE918B960; Mon, 2 Apr 2012 10:31:46 -0400 (EDT) From: John Baldwin To: freebsd-fs@freebsd.org Date: Mon, 2 Apr 2012 08:27:46 -0400 User-Agent: KMail/1.13.5 (FreeBSD/8.2-CBSD-20110714-p10; KDE/4.5.5; amd64; ; ) References: <1184428460.2076443.1333328057090.JavaMail.root@erie.cs.uoguelph.ca> In-Reply-To: <1184428460.2076443.1333328057090.JavaMail.root@erie.cs.uoguelph.ca> MIME-Version: 1.0 Content-Type: Text/Plain; charset="iso-8859-15" Content-Transfer-Encoding: 7bit Message-Id: <201204020827.46722.jhb@freebsd.org> X-Greylist: Sender succeeded SMTP AUTH, not delayed by milter-greylist-4.2.7 (bigwig.baldwin.cx); Mon, 02 Apr 2012 10:31:47 -0400 (EDT) Cc: alc@freebsd.org, Joel Ray Holveck , David Wolfskill Subject: Re: RFC: which patch is preferred for fix to PR#165923 X-BeenThere: freebsd-fs@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Filesystems List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 02 Apr 2012 14:31:48 -0000 On Sunday, April 01, 2012 8:54:17 pm Rick Macklem wrote: > First, a little background w.r.t. an offlist discussion of > PR# 165923. A critical part of the problem reported is the > credentials used to to the Write RPCs in the NFS client's > VOP_PUTPAGES(). Currently the code simply uses the credentials > of the thread that called VOP_PUTPAGES(), which is often incorrect, > especially when the caller is "root" and the NFS server is doing > "root squashing" (ie mapping root->nobody or similar). Can this in theory affect READ RPCs sent by VOP_GETPAGES() as well in the case of root squashing? Or are VOP_GETPAGES() synchronous with respect to faults such that in practice you always have a valid credential in curthread->td_ucred? > Although there is no correct answer w.r.t. what credentials should > be used, there seemed to be rough consensus that the credentials of > the process that did the mmap() call would be best. (If there are > multiple writers, you could use either the 1st or most recent mmap(), > but since all writers had write permissions at open(), I don't think > it matters much which you use, but others can comment on this.) The one problem I see with this approach is suppose someone changes the permissions on the file. Now a user that previously had write access might not have it any longer, but we might be sending RPCs as a different user so they will still work. However, I don't think we can solve that, and presumbly we already have that issue now. Hmm, there might be a variant of this though that is new. Suppose user A and user B both mmap the file. At the time, both users have write access to the file. The file is then chown'd or chmod'd such that only user B has write access to the file, but we are using user A's credential as the cached 'write' credential. Then subsequent writes via mmap() by user B will be lost because they will be sent to the server as user A. Previously you couldn't really get into this case if root squashing was off and all writes were sent as root. Not sure if this is easily solvable either. You could perhaps maintain a list of known-valid write credentials and if a write fails with a permission check, toss it that credential and try the next one in the list. > However, there seems to be some disagreement as to how a patch to > use the mmap() credentials should be done. > > putpages-a.patch - This one captures the credentials during the mmap() > call by using the property that only mmap() calls vnode_pager_alloc() > with "prot != 0" and references them in a new field in vm_object_t. > > putpages-b.patch - This one adds a new VOP_PUTPAGES_NOTIFY() call, which > is done by mmap(). For all file systems except NFS clients, it is a > null op. For the NFS clients, they reference the credentials in a > new field of the NFS specific part of the vnode. > > - I don't have a patch for the third one, but I believe Joel was proposing > something similar to putpages-a.patch, except that the credentials are > passed as an extra argument to VOP_PUTPAGES(), instead of the NFS client's > VOP_PUTPAGES() looking in the vnode's vm_object_t for the cred. I think what I would prefer for the longterm is option 3) (and possibly doing the same for VOP_GETPAGES(). Also, I would call the new field in vm_object something like 'writecred'. For MFC purposes you could use putpages-a.patch instead and only make the change to the VOPs in HEAD. However, I wonder if you can't manage this all at the vnode layer? If all you need is a credential that is allowed to write, can't you cache the credential used for a successful VOP_ACCESS() check with write support in the nfsnode and just use that for write RPCs? The same thing would work for reads, yes? I know for NFSv4 you already maintain a cache of credentials from open()'s that you use for other RPC's already, so this would seem to be similar to that case. This would also let you do the "list of credentials" idea if needed and even let you add new write-capable credentials to the list via VOP_ACCESS() calls after the file was mmap()'d or open()'d. > I've attached the first 2, in case anyone wants to look at them. > > Here's my take on the advantages/disadvantages of each patch: > Advantages Disadvantages > patch-a simple, doesn't require VOP > changes and, therefore, can > be MFC'd easily saves a largely NFS specific item > in vm_object_t > depends on the fact that only > mmap() calls vnode_pager_alloc() with > prot != 0 Only one more note here, this problem is not necessarily unique to NFS. It is probably just as relevant for any other networked file systems such as smbfs. Or just about any other filesystem with storage that requires authorization. -- John Baldwin