Module Name: src Committed By: christos Date: Sat Feb 17 20:19:36 UTC 2018
Modified Files: src/sys/kern: uipc_usrreq.c Log Message: fix LOCAL_PEEREID to not return the same info for both sides... XXX: pullup-{7,8} To generate a diff of this commit: cvs rdiff -u -r1.182 -r1.183 src/sys/kern/uipc_usrreq.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/kern/uipc_usrreq.c diff -u src/sys/kern/uipc_usrreq.c:1.182 src/sys/kern/uipc_usrreq.c:1.183 --- src/sys/kern/uipc_usrreq.c:1.182 Sat Dec 2 03:22:04 2017 +++ src/sys/kern/uipc_usrreq.c Sat Feb 17 15:19:36 2018 @@ -1,4 +1,4 @@ -/* $NetBSD: uipc_usrreq.c,v 1.182 2017/12/02 08:22:04 mrg Exp $ */ +/* $NetBSD: uipc_usrreq.c,v 1.183 2018/02/17 20:19:36 christos Exp $ */ /*- * Copyright (c) 1998, 2000, 2004, 2008, 2009 The NetBSD Foundation, Inc. @@ -96,7 +96,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: uipc_usrreq.c,v 1.182 2017/12/02 08:22:04 mrg Exp $"); +__KERNEL_RCSID(0, "$NetBSD: uipc_usrreq.c,v 1.183 2018/02/17 20:19:36 christos Exp $"); #ifdef _KERNEL_OPT #include "opt_compat_netbsd.h" @@ -214,6 +214,15 @@ uipc_init(void) panic("uipc_init %d", error); } +static void +unp_connid(struct lwp *l, struct unpcb *unp, int flags) +{ + unp->unp_connid.unp_pid = l->l_proc->p_pid; + unp->unp_connid.unp_euid = kauth_cred_geteuid(l->l_cred); + unp->unp_connid.unp_egid = kauth_cred_getegid(l->l_cred); + unp->unp_flags |= flags; +} + /* * A connection succeeded: disassociate both endpoints from the head's * lock, and make them share their own lock. There is a race here: for @@ -627,8 +636,8 @@ uipc_ctloutput(int op, struct socket *so switch (sopt->sopt_name) { case LOCAL_PEEREID: if (unp->unp_flags & UNP_EIDSVALID) { - error = sockopt_set(sopt, - &unp->unp_connid, sizeof(unp->unp_connid)); + error = sockopt_set(sopt, &unp->unp_connid, + sizeof(unp->unp_connid)); } else { error = EINVAL; } @@ -986,10 +995,6 @@ unp_bind(struct socket *so, struct socka unp->unp_vnode = vp; unp->unp_addrlen = addrlen; unp->unp_addr = sun; - unp->unp_connid.unp_pid = p->p_pid; - unp->unp_connid.unp_euid = kauth_cred_geteuid(l->l_cred); - unp->unp_connid.unp_egid = kauth_cred_getegid(l->l_cred); - unp->unp_flags |= UNP_EIDSBIND; VOP_UNLOCK(vp); vput(nd.ni_dvp); unp->unp_flags &= ~UNP_BUSY; @@ -1019,6 +1024,7 @@ unp_listen(struct socket *so, struct lwp if (unp->unp_vnode == NULL) return EINVAL; + unp_connid(l, unp, UNP_EIDSBIND); return 0; } @@ -1082,17 +1088,6 @@ unp_connect1(struct socket *so, struct s unp2 = sotounpcb(so2); unp->unp_conn = unp2; - if ((so->so_proto->pr_flags & PR_CONNREQUIRED) != 0) { - unp2->unp_connid.unp_pid = l->l_proc->p_pid; - unp2->unp_connid.unp_euid = kauth_cred_geteuid(l->l_cred); - unp2->unp_connid.unp_egid = kauth_cred_getegid(l->l_cred); - unp2->unp_flags |= UNP_EIDSVALID; - if (unp2->unp_flags & UNP_EIDSBIND) { - unp->unp_connid = unp2->unp_connid; - unp->unp_flags |= UNP_EIDSVALID; - } - } - switch (so->so_type) { case SOCK_DGRAM: @@ -1203,6 +1198,22 @@ unp_connect(struct socket *so, struct so } unp3->unp_flags = unp2->unp_flags; so2 = so3; + /* + * The connector's (client's) credentials are copied from its + * process structure at the time of connect() (which is now). + */ + unp_connid(l, unp3, UNP_EIDSVALID); + /* + * The receiver's (server's) credentials are copied from the + * unp_peercred member of socket on which the former called + * listen(); unp_listen() cached that process's credentials + * at that time so we can use them now. + */ + if (unp2->unp_flags & UNP_EIDSBIND) { + memcpy(&unp->unp_connid, &unp2->unp_connid, + sizeof(unp->unp_connid)); + unp->unp_flags |= UNP_EIDSVALID; + } } error = unp_connect1(so, so2, l); if (error) { @@ -1271,10 +1282,6 @@ unp_connect2(struct socket *so, struct s case SOCK_SEQPACKET: /* FALLTHROUGH */ case SOCK_STREAM: unp2->unp_conn = unp; - if ((so->so_proto->pr_flags & PR_CONNREQUIRED) != 0) { - unp->unp_connid = unp2->unp_connid; - unp->unp_flags |= UNP_EIDSVALID; - } soisconnected(so); soisconnected(so2); break;