On Sat, Apr 07, 2018 at 09:29:30PM -0600, Theo de Raadt wrote: > Philip Guenther <pguent...@proofpoint.com> wrote: > > > On Sat, 7 Apr 2018, Sebastien Marie wrote: > > > While running testsuite on third-party program, I found some weird > > > behaviour on us side regarding socketpair(2) and getpeereid(3). > > > > > > I ported the unit test to C (it was Rust) to check more easily. > > > > > > It just creates an UNIX domain socket using socketpair(2), and next > > > check the euid/egid of the peer connected socket. The expected result is > > > that euid of the peer is the euid of the process. > > ... > > > Could I have confirmation if it is a bug or not ? I am unsure if > > > socketpair(2) should set the peer information or not. But at least, > > > ENOTCONN is wrong: socketpair(2) returns connected sockets. > > > > That's a bug, IMO: socketpair(2) should support use of getpeereid(3). > > Yes, support should be added.
Here a diff to add getpeerid(3) support inside socketpair(2). It fills unp_connid on the two sockets (there are connected each other). I think it is the more simple way to achieve it. Moving the related code from unp_connect() to unp_connect2() should be possible (only few direct callers of {so,unp_}connect2() ), but unp_connid will not be copied on the two sockets. -- Sebastien Marie Index: kern/uipc_syscalls.c =================================================================== RCS file: /cvs/src/sys/kern/uipc_syscalls.c,v retrieving revision 1.168 diff -u -p -r1.168 uipc_syscalls.c --- kern/uipc_syscalls.c 28 Mar 2018 09:54:00 -0000 1.168 +++ kern/uipc_syscalls.c 8 Apr 2018 04:57:14 -0000 @@ -448,6 +448,7 @@ sys_socketpair(struct proc *p, void *v, struct filedesc *fdp = p->p_fd; struct file *fp1, *fp2; struct socket *so1, *so2; + struct unpcb *unp1, *unp2; int type, cloexec, nonblock, fflag, error, sv[2]; type = SCARG(uap, type) & ~(SOCK_CLOEXEC | SOCK_NONBLOCK); @@ -461,6 +462,14 @@ sys_socketpair(struct proc *p, void *v, error = socreate(SCARG(uap, domain), &so2, type, SCARG(uap, protocol)); if (error) goto free1; + + unp1 = sotounpcb(so1); + unp2 = sotounpcb(so2); + unp1->unp_connid.uid = unp2->unp_connid.uid = p->p_ucred->cr_uid; + unp1->unp_connid.gid = unp2->unp_connid.gid = p->p_ucred->cr_gid; + unp1->unp_connid.pid = unp2->unp_connid.pid = p->p_p->ps_pid; + unp1->unp_flags |= UNP_FEIDS; + unp2->unp_flags |= UNP_FEIDS; error = soconnect2(so1, so2); if (error != 0)