Introduce a version field to `struct xucred' in place of one of the
spares (the size of the field was changed from u_short to u_int to reflect what it really ends up being). Accordingly, change users of xucred to set and check this field as appropriate. In the kernel, this is being done inside the new cru2x() routine which takes a `struct ucred' and fills out a `struct xucred' according to the former. This also has the pleasant sideaffect of removing some duplicate code. Reviewed by: rwatson
This commit is contained in:
parent
b7eeb587f6
commit
76183f3453
@ -118,7 +118,8 @@ have been called.
|
||||
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 ,
|
||||
|
@ -32,6 +32,7 @@ __FBSDID("$FreeBSD$");
|
||||
#include <sys/ucred.h>
|
||||
#include <sys/un.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
|
||||
int
|
||||
@ -45,6 +46,8 @@ getpeereid(int s, uid_t *euid, gid_t *egid)
|
||||
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);
|
||||
|
@ -211,7 +211,7 @@ struct mountlist *mlhead;
|
||||
struct grouplist *grphead;
|
||||
char exname[MAXPATHLEN];
|
||||
struct xucred def_anon = {
|
||||
0,
|
||||
XUCRED_VERSION,
|
||||
(uid_t)-2,
|
||||
1,
|
||||
{ (gid_t)-2 },
|
||||
@ -2050,6 +2050,7 @@ parsecred(namelist, cr)
|
||||
struct group *gr;
|
||||
int ngroups, groups[NGROUPS + 1];
|
||||
|
||||
cr->cr_version = XUCRED_VERSION;
|
||||
/*
|
||||
* Set up the unprivileged user.
|
||||
*/
|
||||
|
@ -1759,6 +1759,22 @@ crdup(cr)
|
||||
return (newcr);
|
||||
}
|
||||
|
||||
/*
|
||||
* 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));
|
||||
}
|
||||
|
||||
/*
|
||||
* small routine to swap a thread's current ucred for the correct one
|
||||
* taken from the process.
|
||||
|
@ -717,11 +717,7 @@ unp_connect(so, nam, td)
|
||||
* 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_ngroups;
|
||||
memcpy(unp3->unp_peercred.cr_groups, td->td_proc->p_ucred->cr_groups,
|
||||
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
|
||||
@ -1427,11 +1423,7 @@ unp_listen(unp, p)
|
||||
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);
|
||||
}
|
||||
|
@ -922,11 +922,7 @@ tcp_getcred(SYSCTL_HANDLER_ARGS)
|
||||
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);
|
||||
@ -978,11 +974,7 @@ tcp6_getcred(SYSCTL_HANDLER_ARGS)
|
||||
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);
|
||||
|
@ -922,11 +922,7 @@ tcp_getcred(SYSCTL_HANDLER_ARGS)
|
||||
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);
|
||||
@ -978,11 +974,7 @@ tcp6_getcred(SYSCTL_HANDLER_ARGS)
|
||||
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);
|
||||
|
@ -651,11 +651,7 @@ udp_getcred(SYSCTL_HANDLER_ARGS)
|
||||
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);
|
||||
|
@ -486,11 +486,7 @@ udp6_getcred(SYSCTL_HANDLER_ARGS)
|
||||
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);
|
||||
|
@ -265,11 +265,7 @@ lomac_local_connect(struct socket *so, struct sockaddr *nam, struct thread *td)
|
||||
* 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_ngroups;
|
||||
memcpy(unp3->unp_peercred.cr_groups, td->td_proc->p_ucred->cr_groups,
|
||||
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
|
||||
|
@ -73,12 +73,13 @@ struct ucred {
|
||||
* 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_int 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
|
||||
|
||||
@ -96,6 +97,7 @@ void crfree(struct ucred *cr);
|
||||
struct ucred *crget(void);
|
||||
struct ucred *crhold(struct ucred *cr);
|
||||
int crshared(struct ucred *cr);
|
||||
void cru2x(struct ucred *cr, struct xucred *xcr);
|
||||
int groupmember(gid_t gid, struct ucred *cred);
|
||||
#endif /* _KERNEL */
|
||||
|
||||
|
@ -569,7 +569,7 @@ ident_stream(s, sep) /* Ident service (AKA "auth") */
|
||||
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);
|
||||
|
@ -211,7 +211,7 @@ struct mountlist *mlhead;
|
||||
struct grouplist *grphead;
|
||||
char exname[MAXPATHLEN];
|
||||
struct xucred def_anon = {
|
||||
0,
|
||||
XUCRED_VERSION,
|
||||
(uid_t)-2,
|
||||
1,
|
||||
{ (gid_t)-2 },
|
||||
@ -2050,6 +2050,7 @@ parsecred(namelist, cr)
|
||||
struct group *gr;
|
||||
int ngroups, groups[NGROUPS + 1];
|
||||
|
||||
cr->cr_version = XUCRED_VERSION;
|
||||
/*
|
||||
* Set up the unprivileged user.
|
||||
*/
|
||||
|
Loading…
Reference in New Issue
Block a user