Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 18 Dec 2001 22:37:52 -0500 (EST)
From:      Robert Watson <rwatson@freebsd.org>
To:        Dima Dorfman <dima@trit.org>
Cc:        "Brian F. Feldman" <green@freebsd.org>, arch@freebsd.org
Subject:   Re: xucred versioning and filling (was: MFC'ing xucred definition)
Message-ID:  <Pine.NEB.3.96L.1011218223400.52778G-100000@fledge.watson.org>
In-Reply-To: <20011219005412.54A833E2F@bazooka.trit.org>

next in thread | previous in thread | raw e-mail | index | archive | help

Should crx2u() attempt to handle reference counting issues, as well as
uidinfo and friends?  I'm far more comfortable with a notion of u2crx than
vice versa, as the ucred structure has additional semantics, whereas the
xucred structure doesn't.  The vfs_export.c code that uses it may need
further inspection for the same reasons, actually...

Robert N M Watson             FreeBSD Core Team, TrustedBSD Project
robert@fledge.watson.org      NAI Labs, Safeport Network Services

On Wed, 19 Dec 2001, Dima Dorfman wrote:

> Does anybody have any comments on this?  I'd like to commit it
> soon-ish, but don't plan to MFC it before 4.5 (since it's a new
> interface, and I'd rather not set it in stone (-stable) yet).
> 
> Thanks.
> 
> I wrote:
> > Robert Watson <rwatson@freebsd.org> wrote:
> > > On Fri, 14 Dec 2001, Dima Dorfman wrote:
> > > > rwatson wrote:
> > > > > Actually, the one thing I'd like to see before we move forward
> > > > > is a standard routine that accepts a ucred, and a *xucred, and
> > > > > fills out the xucred using the ucred (preferably, in
> > > > > kern_prot.c).  Right now, xucred is filled out in various
> > > > > places manually (netinet, socket code, et al).  As we begin to
> > > > > broaden the scope of xucred (for example, I'd like to push in
> > > > > the ruid and rgid), it will make things a lot easier, and also
> > > > > prevent more code from knowing much about the innards of
> > > > > ucred.  That way, also, the version number can be kept in one
> > > > > place.
> > > > 
> > > > I had patches to add this routine (and vice versa, xucred->ucred) 
> > > > before you added the extra fields to ucred, at which point I dropped it
> > > > since it didn't make much sense: Which fields do you copy?  Effective,
> > > > real, or saved {u,g}ids?  It would again make sense if xucred had the
> > > > same set of fields as ucred, however. 
> > > 
> > > It's always been euid in ucred previously, so I assumed that for version 0
> > > of xucred, only euid and egid (plus additional groups) would be exported.
> > > Future versions of xucred (probably version 1, only in -CURRENT) would
> > > also be able to export ruid, svuid, rgid, and svgid.
> > 
> > Very well.  The attached patch adds two routines, cru2x() and crx2u()
> > which convert from a ucred to xucred and vice versa, respectively.
> > cru2x() sets the version number, and crx2u() checks it.  If the check
> > fails, it returns EINVAL.  I'm not sure if there's a better way to do
> > this error passing, since it seems that none of the other cr*()
> > routines return an error code.
> > 
> > The userland parts remain unchanged from my previous patches.
> > 
> > Index: lib/libc/gen/getpeereid.3
> > ===================================================================
> > RCS file: /ref/cvsf/src/lib/libc/gen/getpeereid.3,v
> > retrieving revision 1.3
> > diff -u -r1.3 getpeereid.3
> > --- lib/libc/gen/getpeereid.3	2001/12/02 23:50:40	1.3
> > +++ lib/libc/gen/getpeereid.3	2001/12/14 01:20:17
> > @@ -118,7 +118,8 @@
> >  The argument
> >  .Fa s
> >  does not refer to a socket of type
> > -.Dv SOCK_STREAM .
> > +.Dv SOCK_STREAM ,
> > +or the kernel returned invalid data.
> >  .El
> >  .Sh SEE ALSO
> >  .Xr connect 2 ,
> > Index: lib/libc/gen/getpeereid.c
> > ===================================================================
> > RCS file: /ref/cvsf/src/lib/libc/gen/getpeereid.c,v
> > retrieving revision 1.1
> > diff -u -r1.1 getpeereid.c
> > --- lib/libc/gen/getpeereid.c	2001/08/17 22:09:15	1.1
> > +++ lib/libc/gen/getpeereid.c	2001/12/14 01:20:17
> > @@ -34,6 +34,7 @@
> >  #include <sys/ucred.h>
> >  #include <sys/un.h>
> >  
> > +#include <errno.h>
> >  #include <unistd.h>
> >  
> >  int
> > @@ -47,6 +48,8 @@
> >  	error = getsockopt(s, LOCAL_PEERCRED, 1, &xuc, &xuclen);
> >  	if (error != 0)
> >  		return (error);
> > +	if (xuc.cr_version != XUCRED_VERSION)
> > +		return (EINVAL);
> >  	*euid = xuc.cr_uid;
> >  	*egid = xuc.cr_gid;
> >  	return (0);
> > Index: sbin/mountd/mountd.c
> > ===================================================================
> > RCS file: /ref/cvsf/src/sbin/mountd/mountd.c,v
> > retrieving revision 1.59
> > diff -u -r1.59 mountd.c
> > --- sbin/mountd/mountd.c	2001/09/20 02:15:17	1.59
> > +++ sbin/mountd/mountd.c	2001/12/14 01:20:17
> > @@ -211,7 +211,7 @@
> >  struct grouplist *grphead;
> >  char exname[MAXPATHLEN];
> >  struct xucred def_anon = {
> > -	0,
> > +	XUCRED_VERSION,
> >  	(uid_t)-2,
> >  	1,
> >  	{ (gid_t)-2 },
> > @@ -2050,6 +2050,7 @@
> >  	struct group *gr;
> >  	int ngroups, groups[NGROUPS + 1];
> >  
> > +	cr->cr_version = XUCRED_VERSION;
> >  	/*
> >  	 * Set up the unprivileged user.
> >  	 */
> > Index: sys/kern/kern_prot.c
> > ===================================================================
> > RCS file: /ref/cvsf/src/sys/kern/kern_prot.c,v
> > retrieving revision 1.131
> > diff -u -r1.131 kern_prot.c
> > --- sys/kern/kern_prot.c	2001/12/06 21:58:47	1.131
> > +++ sys/kern/kern_prot.c	2001/12/14 03:30:55
> > @@ -1670,6 +1670,41 @@
> >  }
> >  
> >  /*
> > + * Fill in a struct xucred based on a struct ucred.
> > + */
> > +void
> > +cru2x(cr, xcr)
> > +	struct ucred *cr;
> > +	struct xucred *xcr;
> > +{
> > +
> > +	bzero(xcr, sizeof(*xcr));
> > +	xcr->cr_version = XUCRED_VERSION;
> > +	xcr->cr_uid = cr->cr_uid;
> > +	xcr->cr_ngroups = cr->cr_ngroups;
> > +	bcopy(cr->cr_groups, xcr->cr_groups, sizeof(cr->cr_groups));
> > +}
> > +
> > +/*
> > + * Copy information out of a struct xucred into a struct ucred.  This
> > + * routine does *not* initialize (zero) the output structure (cr)
> > + * because that's the job of crget() or crdup().
> > + */
> > +int
> > +crx2u(xcr, cr)
> > +	struct xucred *xcr;
> > +	struct ucred *cr;
> > +{
> > +
> > +	if (xcr->cr_version != XUCRED_VERSION)
> > +		return (EINVAL);
> > +	cr->cr_uid = xcr->cr_uid;
> > +	cr->cr_ngroups = xcr->cr_ngroups;
> > +	bcopy(xcr->cr_groups, cr->cr_groups, sizeof(xcr->cr_groups));
> > +	return (0);
> > +}
> > +
> > +/*
> >   * Get login name, if available.
> >   */
> >  #ifndef _SYS_SYSPROTO_H_
> > Index: sys/kern/uipc_usrreq.c
> > ===================================================================
> > RCS file: /ref/cvsf/src/sys/kern/uipc_usrreq.c,v
> > retrieving revision 1.78
> > diff -u -r1.78 uipc_usrreq.c
> > --- sys/kern/uipc_usrreq.c	2001/12/13 22:09:37	1.78
> > +++ sys/kern/uipc_usrreq.c	2001/12/14 03:33:12
> > @@ -710,11 +710,7 @@
> >  		 * from its process structure at the time of connect()
> >  		 * (which is now).
> >  		 */
> -		memset(&unp3->unp_peercred, '\0', sizeof(unp3->unp_peercred));
> > -		unp3->unp_peercred.cr_uid = td->td_proc->p_ucred->cr_uid;
> > -		unp3->unp_peercred.cr_ngroups = td->td_proc->p_ucred->cr_ngroup
> > s;
> > -		memcpy(unp3->unp_peercred.cr_groups, td->td_proc->p_ucred->cr_g
> > roups,
> > -		    sizeof(unp3->unp_peercred.cr_groups));
> > +		cru2x(td->td_proc->p_ucred, &unp3->unp_peercred);
> >  		unp3->unp_flags |= UNP_HAVEPC;
> >  		/*
> >  		 * The receiver's (server's) credentials are copied
> > @@ -1396,11 +1392,7 @@
> >  	struct proc *p;
> >  {
> >  
> > -	bzero(&unp->unp_peercred, sizeof(unp->unp_peercred));
> > -	unp->unp_peercred.cr_uid = p->p_ucred->cr_uid;
> > -	unp->unp_peercred.cr_ngroups = p->p_ucred->cr_ngroups;
> > -	bcopy(p->p_ucred->cr_groups, unp->unp_peercred.cr_groups,
> > -	    sizeof(unp->unp_peercred.cr_groups));
> > +	cru2x(p->p_ucred, &unp->unp_peercred);
> >  	unp->unp_flags |= UNP_HAVEPCCACHED;
> >  	return (0);
> >  }
> > Index: sys/kern/vfs_export.c
> > ===================================================================
> > RCS file: /ref/cvsf/src/sys/kern/vfs_export.c,v
> > retrieving revision 1.312
> > diff -u -r1.312 vfs_export.c
> > --- sys/kern/vfs_export.c	2001/09/10 11:28:05	1.312
> > +++ sys/kern/vfs_export.c	2001/12/14 03:40:24
> > @@ -98,11 +98,9 @@
> >  			return (EPERM);
> >  		np = &nep->ne_defexported;
> >  		np->netc_exflags = argp->ex_flags;
> > -		bzero(&np->netc_anon, sizeof(np->netc_anon));
> > -		np->netc_anon.cr_uid = argp->ex_anon.cr_uid;
> > -		np->netc_anon.cr_ngroups = argp->ex_anon.cr_ngroups;
> > -		bcopy(argp->ex_anon.cr_groups, np->netc_anon.cr_groups,
> > -		    sizeof(np->netc_anon.cr_groups));
> > +		error = crx2u(&argp->ex_anon, &np->netc_anon);
> > +		if (error != 0)
> > +			return (error);
> >  		np->netc_anon.cr_ref = 1;
> >  		mp->mnt_flag |= MNT_DEFEXPORTED;
> >  		return (0);
> > @@ -150,11 +148,9 @@
> >  		goto out;
> >  	}
> >  	np->netc_exflags = argp->ex_flags;
> > -	bzero(&np->netc_anon, sizeof(np->netc_anon));
> > -	np->netc_anon.cr_uid = argp->ex_anon.cr_uid;
> > -	np->netc_anon.cr_ngroups = argp->ex_anon.cr_ngroups;
> > -	bcopy(argp->ex_anon.cr_groups, np->netc_anon.cr_groups,
> > -	    sizeof(np->netc_anon.cr_groups));
> > +	error = crx2u(&argp->ex_anon, &np->netc_anon);
> > +	if (error != 0)
> > +		goto out;
> >  	np->netc_anon.cr_ref = 1;
> >  	return (0);
> >  out:
> > Index: sys/netinet/tcp_subr.c
> > ===================================================================
> > RCS file: /ref/cvsf/src/sys/netinet/tcp_subr.c,v
> > retrieving revision 1.118
> > diff -u -r1.118 tcp_subr.c
> > --- sys/netinet/tcp_subr.c	2001/11/22 04:50:43	1.118
> > +++ sys/netinet/tcp_subr.c	2001/12/14 03:34:19
> > @@ -919,11 +919,7 @@
> >  	error = cr_cansee(req->td->td_proc->p_ucred, inp->inp_socket->so_cred);
> >  	if (error)
> >  		goto out;
> > -	bzero(&xuc, sizeof(xuc));
> > -	xuc.cr_uid = inp->inp_socket->so_cred->cr_uid;
> > -	xuc.cr_ngroups = inp->inp_socket->so_cred->cr_ngroups;
> > -	bcopy(inp->inp_socket->so_cred->cr_groups, xuc.cr_groups,
> > -	    sizeof(xuc.cr_groups));
> > +	cru2x(inp->inp_socket->so_cred, &xuc);
> >  	error = SYSCTL_OUT(req, &xuc, sizeof(struct xucred));
> >  out:
> >  	splx(s);
> > @@ -975,11 +971,7 @@
> >  	error = cr_cansee(req->td->td_proc->p_ucred, inp->inp_socket->so_cred);
> >  	if (error)
> >  		goto out;
> > -	bzero(&xuc, sizeof(xuc));
> > -	xuc.cr_uid = inp->inp_socket->so_cred->cr_uid;
> > -	xuc.cr_ngroups = inp->inp_socket->so_cred->cr_ngroups;
> > -	bcopy(inp->inp_socket->so_cred->cr_groups, xuc.cr_groups,
> > -	    sizeof(xuc.cr_groups));
> > +	cru2x(inp->inp_socket->so_cred, &xuc);
> >  	error = SYSCTL_OUT(req, &xuc, sizeof(struct xucred));
> >  out:
> >  	splx(s);
> > Index: sys/netinet/udp_usrreq.c
> > ===================================================================
> > RCS file: /ref/cvsf/src/sys/netinet/udp_usrreq.c,v
> > retrieving revision 1.100
> > diff -u -r1.100 udp_usrreq.c
> > --- sys/netinet/udp_usrreq.c	2001/11/08 02:13:17	1.100
> > +++ sys/netinet/udp_usrreq.c	2001/12/14 03:34:36
> > @@ -651,11 +651,7 @@
> >  	error = cr_cansee(req->td->td_proc->p_ucred, inp->inp_socket->so_cred);
> >  	if (error)
> >  		goto out;
> > -	bzero(&xuc, sizeof(xuc));
> > -	xuc.cr_uid = inp->inp_socket->so_cred->cr_uid;
> > -	xuc.cr_ngroups = inp->inp_socket->so_cred->cr_ngroups;
> > -	bcopy(inp->inp_socket->so_cred->cr_groups, xuc.cr_groups,
> > -	    sizeof(xuc.cr_groups));
> > +	cru2x(inp->inp_socket->so_cred, &xuc);
> >  	error = SYSCTL_OUT(req, &xuc, sizeof(struct xucred));
> >  out:
> >  	splx(s);
> > Index: sys/netinet6/udp6_usrreq.c
> > ===================================================================
> > RCS file: /ref/cvsf/src/sys/netinet6/udp6_usrreq.c,v
> > retrieving revision 1.19
> > diff -u -r1.19 udp6_usrreq.c
> > --- sys/netinet6/udp6_usrreq.c	2001/11/08 02:13:18	1.19
> > +++ sys/netinet6/udp6_usrreq.c	2001/12/14 03:35:00
> > @@ -484,11 +484,7 @@
> >  		error = ENOENT;
> >  		goto out;
> >  	}
> > -	bzero(&xuc, sizeof(xuc));
> > -	xuc.cr_uid = inp->inp_socket->so_cred->cr_uid;
> > -	xuc.cr_ngroups = inp->inp_socket->so_cred->cr_ngroups;
> > -	bcopy(inp->inp_socket->so_cred->cr_groups, xuc.cr_groups,
> > -	    sizeof(xuc.cr_groups));
> > +	cru2x(inp->inp_socket->so_cred, &xuc);
> >  	error = SYSCTL_OUT(req, &xuc, sizeof(struct xucred));
> >  out:
> >  	splx(s);
> > Index: sys/security/lomac/kernel_socket.c
> > ===================================================================
> > RCS file: /ref/cvsf/src/sys/security/lomac/kernel_socket.c,v
> > retrieving revision 1.2
> > diff -u -r1.2 kernel_socket.c
> > --- sys/security/lomac/kernel_socket.c	2001/12/03 00:21:18	1.2
> > +++ sys/security/lomac/kernel_socket.c	2001/12/14 03:35:23
> > @@ -265,11 +265,7 @@
> >  		 * from its process structure at the time of connect()
> >  		 * (which is now).
> >  		 */
> > -		memset(&unp3->unp_peercred, '\0', sizeof(unp3->unp_peercred));
> > -		unp3->unp_peercred.cr_uid = td->td_proc->p_ucred->cr_uid;
> > -		unp3->unp_peercred.cr_ngroups = td->td_proc->p_ucred->cr_ngroup
> > s;
> > -		memcpy(unp3->unp_peercred.cr_groups, td->td_proc->p_ucred->cr_g
> > roups,
> > -		    sizeof(unp3->unp_peercred.cr_groups));
> > +		cru2x(td->td_proc->p_ucred, &unp3->unp_peercred);
> >  		unp3->unp_flags |= UNP_HAVEPC;
> >  		/*
> >  		 * The receiver's (server's) credentials are copied
> > Index: sys/sys/ucred.h
> > ===================================================================
> > RCS file: /ref/cvsf/src/sys/sys/ucred.h,v
> > retrieving revision 1.26
> > diff -u -r1.26 ucred.h
> > --- sys/sys/ucred.h	2001/10/11 23:38:17	1.26
> > +++ sys/sys/ucred.h	2001/12/14 03:30:26
> > @@ -73,12 +73,13 @@
> >   * any need to change the size of this or layout of its used fields.
> >   */
> >  struct xucred {
> > -	u_short	_cr_unused0;		/* compatibility with old ucred */
> > +	u_short cr_version;		/* structure layout version */
> >  	uid_t	cr_uid;			/* effective user id */
> >  	short	cr_ngroups;		/* number of groups */
> >  	gid_t	cr_groups[NGROUPS];	/* groups */
> >  	void	*_cr_unused1;		/* compatibility with old ucred */
> >  };
> > +#define	XUCRED_VERSION	0
> >  
> >  #ifdef _KERNEL
> >  
> > @@ -95,6 +96,8 @@
> >  struct ucred	*crget __P((void));
> >  struct ucred	*crhold __P((struct ucred *cr));
> >  int		crshared __P((struct ucred *cr));
> > +void		cru2x __P((struct ucred *cr, struct xucred *xcr));
> > +int		crx2u __P((struct xucred *xcr, struct ucred *cr));
> >  int		groupmember __P((gid_t gid, struct ucred *cred));
> >  #endif /* _KERNEL */
> >  
> > Index: usr.sbin/inetd/builtins.c
> > ===================================================================
> > RCS file: /ref/cvsf/src/usr.sbin/inetd/builtins.c,v
> > retrieving revision 1.36
> > diff -u -r1.36 builtins.c
> > --- usr.sbin/inetd/builtins.c	2001/07/17 07:12:57	1.36
> > +++ usr.sbin/inetd/builtins.c	2001/12/14 01:20:18
> > @@ -569,7 +569,7 @@
> >  		getcredfail = EAFNOSUPPORT;
> >  		break;
> >  	}
> > -	if (getcredfail != 0) {
> > +	if (getcredfail != 0 || uc.cr_version != XUCRED_VERSION) {
> >  		if (*idbuf == '\0')
> >  			iderror(lport, fport, s,
> >  			    getcredfail == ENOENT ? ID_NOUSER : ID_UNKNOWN);
> 


To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-arch" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?Pine.NEB.3.96L.1011218223400.52778G-100000>