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>