diff options
-rw-r--r-- | lib/libc/gen/getpeereid.3 | 3 | ||||
-rw-r--r-- | lib/libc/gen/getpeereid.c | 3 | ||||
-rw-r--r-- | sbin/mountd/mountd.c | 3 | ||||
-rw-r--r-- | sys/kern/kern_prot.c | 16 | ||||
-rw-r--r-- | sys/kern/uipc_usrreq.c | 12 | ||||
-rw-r--r-- | sys/netinet/tcp_subr.c | 12 | ||||
-rw-r--r-- | sys/netinet/tcp_timewait.c | 12 | ||||
-rw-r--r-- | sys/netinet/udp_usrreq.c | 6 | ||||
-rw-r--r-- | sys/netinet6/udp6_usrreq.c | 6 | ||||
-rw-r--r-- | sys/security/lomac/kernel_socket.c | 6 | ||||
-rw-r--r-- | sys/sys/ucred.h | 4 | ||||
-rw-r--r-- | usr.sbin/inetd/builtins.c | 2 | ||||
-rw-r--r-- | usr.sbin/mountd/mountd.c | 3 |
13 files changed, 38 insertions, 50 deletions
diff --git a/lib/libc/gen/getpeereid.3 b/lib/libc/gen/getpeereid.3 index 94ed61efd099..e124d0a9be9b 100644 --- a/lib/libc/gen/getpeereid.3 +++ b/lib/libc/gen/getpeereid.3 @@ -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 , diff --git a/lib/libc/gen/getpeereid.c b/lib/libc/gen/getpeereid.c index 7d0c5775e335..b64ff5497053 100644 --- a/lib/libc/gen/getpeereid.c +++ b/lib/libc/gen/getpeereid.c @@ -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); diff --git a/sbin/mountd/mountd.c b/sbin/mountd/mountd.c index b3f220eab506..862b61b4d25c 100644 --- a/sbin/mountd/mountd.c +++ b/sbin/mountd/mountd.c @@ -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. */ diff --git a/sys/kern/kern_prot.c b/sys/kern/kern_prot.c index 615709eb26c3..56f7895c8d4e 100644 --- a/sys/kern/kern_prot.c +++ b/sys/kern/kern_prot.c @@ -1760,6 +1760,22 @@ crdup(cr) } /* + * 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. */ diff --git a/sys/kern/uipc_usrreq.c b/sys/kern/uipc_usrreq.c index 6bc58f2bcbd3..a6522607af15 100644 --- a/sys/kern/uipc_usrreq.c +++ b/sys/kern/uipc_usrreq.c @@ -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); } diff --git a/sys/netinet/tcp_subr.c b/sys/netinet/tcp_subr.c index d79b816dea98..99b50a5799c0 100644 --- a/sys/netinet/tcp_subr.c +++ b/sys/netinet/tcp_subr.c @@ -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); diff --git a/sys/netinet/tcp_timewait.c b/sys/netinet/tcp_timewait.c index d79b816dea98..99b50a5799c0 100644 --- a/sys/netinet/tcp_timewait.c +++ b/sys/netinet/tcp_timewait.c @@ -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); diff --git a/sys/netinet/udp_usrreq.c b/sys/netinet/udp_usrreq.c index 6eeb3a1e00f6..047a5d4e7272 100644 --- a/sys/netinet/udp_usrreq.c +++ b/sys/netinet/udp_usrreq.c @@ -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); diff --git a/sys/netinet6/udp6_usrreq.c b/sys/netinet6/udp6_usrreq.c index 09fd89896ba4..2861f7f8afe6 100644 --- a/sys/netinet6/udp6_usrreq.c +++ b/sys/netinet6/udp6_usrreq.c @@ -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); diff --git a/sys/security/lomac/kernel_socket.c b/sys/security/lomac/kernel_socket.c index 541822b0aaf6..3ed2ee1b81e6 100644 --- a/sys/security/lomac/kernel_socket.c +++ b/sys/security/lomac/kernel_socket.c @@ -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 diff --git a/sys/sys/ucred.h b/sys/sys/ucred.h index 03d433706dc3..ed0d576c0dde 100644 --- a/sys/sys/ucred.h +++ b/sys/sys/ucred.h @@ -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 */ diff --git a/usr.sbin/inetd/builtins.c b/usr.sbin/inetd/builtins.c index 433c645aadc3..08c3c567bbea 100644 --- a/usr.sbin/inetd/builtins.c +++ b/usr.sbin/inetd/builtins.c @@ -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); diff --git a/usr.sbin/mountd/mountd.c b/usr.sbin/mountd/mountd.c index b3f220eab506..862b61b4d25c 100644 --- a/usr.sbin/mountd/mountd.c +++ b/usr.sbin/mountd/mountd.c @@ -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. */ |