summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lib/libc/gen/getpeereid.33
-rw-r--r--lib/libc/gen/getpeereid.c3
-rw-r--r--sbin/mountd/mountd.c3
-rw-r--r--sys/kern/kern_prot.c16
-rw-r--r--sys/kern/uipc_usrreq.c12
-rw-r--r--sys/netinet/tcp_subr.c12
-rw-r--r--sys/netinet/tcp_timewait.c12
-rw-r--r--sys/netinet/udp_usrreq.c6
-rw-r--r--sys/netinet6/udp6_usrreq.c6
-rw-r--r--sys/security/lomac/kernel_socket.c6
-rw-r--r--sys/sys/ucred.h4
-rw-r--r--usr.sbin/inetd/builtins.c2
-rw-r--r--usr.sbin/mountd/mountd.c3
13 files changed, 38 insertions, 50 deletions
diff --git a/lib/libc/gen/getpeereid.3 b/lib/libc/gen/getpeereid.3
index 94ed61e..e124d0a 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 7d0c577..b64ff54 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 b3f220e..862b61b 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 615709e..56f7895 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 6bc58f2..a6522607 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 d79b816..99b50a5 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 d79b816..99b50a5 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 6eeb3a1..047a5d4 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 09fd898..2861f7f 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 541822b..3ed2ee1 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 03d4337..ed0d576 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 433c645..08c3c56 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 b3f220e..862b61b 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.
*/
OpenPOWER on IntegriCloud