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)

Reply via email to