cvs commit: src/sys/nfsclient nfs_socket.c

John Baldwin jhb at freebsd.org
Fri Jan 11 08:55:09 PST 2008


On Thursday 10 January 2008 09:36:28 pm Alfred Perlstein wrote:
> * Peter Wemm <peter at wemm.org> [080110 17:39] wrote:
> > On Jan 10, 2008 5:00 PM, Alfred Perlstein <alfred at freebsd.org> wrote:
> > >
> > > * John Baldwin <jhb at FreeBSD.org> [080110 15:33] wrote:
> > > > jhb         2008-01-10 23:36:00 UTC
> > > >
> > > >   FreeBSD src repository
> > > >
> > > >   Modified files:
> > > >     sys/nfsclient        nfs_socket.c
> > > >   Log:
> > > >   Pass curthread to various socket routines (socreate(), sobind(), and
> > > >   soconnect()) instead of &thread0 when establishing a connection to the NFS
> > > >   server.  Otherwise inconsistent credentials may be used when setting up
> > > >   the NFS socket.
> > >
> > > I'm not sure, but I think this may be a regression, I seem to recall
> > > that a long time ago it was switched to &thread0 because otherwise
> > > certain operations can fail due to curthread not running as root.
> > 
> > That's my recollection too.  For example, when nfs is configured to
> > bind to a priviliged local port for making queries or connections, it
> > had to be done as root.  With tcp mounts, the connection can be
> > dropped and a reconnect required at any time.
> 
> This could be implemented by a handoff to a thread that does the
> appropriate setuid call beforehand, or perhaps the credential
> inconsistencies can be further expained or fixed.

The problem case I have is doing a mount inside of a jail.  The socket's
credential is jailed but thread0's credential is not, and you end up with
odd behavior where sobind() treats the socket as non-jailed (and thus only
binds the local port and not the local IP address) but soconnect() treats
the socket as jailed and fails with EINVAL when it sees a partially bound
socket.  (sobind() of a jailed socket sets both the port and IP.)  What I
can do as a workaround is to change curthread's ucred to be the NFS mount's
credential during nfs_connect() by fiddling with td_ucred.  It would be
safe as it wouldn't affect other threads even in the same process and the
current thread isn't going to be doing anything else until the function
returns with the restored credentials, just hackish.

-- 
John Baldwin


More information about the cvs-src mailing list