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;

Reply via email to