nfs: init real/saved uid/gid in server-side credentials
authorNicolas Thery <nthery@gmail.com>
Sun, 23 Aug 2009 19:04:21 +0000 (21:04 +0200)
committerNicolas Thery <nthery@gmail.com>
Sun, 23 Aug 2009 19:39:12 +0000 (21:39 +0200)
When unmarshalling a request, the server constructs a ucred
structure (nfsrv_descript.nd_cr) from the credential data in the
RPC.  It initializes only the effective uid and gid and leaves
the real and saved uid/gid unitialized.  This effectively sets
the real/effective ids to root because nd_cr is first
bzero()'ed.

As a consequence, now that accept(2) checks real uid/gid, all
accept calls to NFS files incorrectly succeed.

Fix this by initializing the real and saved uid/gid in nd_cr to
the same values as the real uid/gid (only the real uid/gid are
RPC'ed to the server).

NOTE: accept(2) and faccessat(2) to NFS files are still broken
in part because the client sends the effective uid/gid to the
server.  I'll fix this once I've groked the uid magic in the NFS
code.

sys/vfs/nfs/nfs_socket.c

index 54a31f8..184d86e 100644 (file)
@@ -2291,7 +2291,9 @@ nfs_getreq(struct nfsrv_descript *nd, struct nfsd *nfsd, int has_header)
                bzero((caddr_t)&nd->nd_cr, sizeof (struct ucred));
                nd->nd_cr.cr_ref = 1;
                nd->nd_cr.cr_uid = fxdr_unsigned(uid_t, *tl++);
+               nd->nd_cr.cr_ruid = nd->nd_cr.cr_svuid = nd->nd_cr.cr_uid;
                nd->nd_cr.cr_gid = fxdr_unsigned(gid_t, *tl++);
+               nd->nd_cr.cr_rgid = nd->nd_cr.cr_svgid = nd->nd_cr.cr_gid;
                len = fxdr_unsigned(int, *tl);
                if (len < 0 || len > RPCAUTH_UNIXGIDS) {
                        m_freem(info.mrep);