Hello, I've noticed that getpeereid/LOCAL_PEERCRED doesn't work with sockets created through socketpair, but only through actual listen/connect calls.
I notice that in unp_connect, we stash the peercred of the thread, then call on to unp_connect2. In kern_socketpair, we call straight through to unp_connect2 (through pr_usrreqs->pru_connect2), so this makes sense from the code. I'd like to suggest we support peercred for socketpair-created sockets. Motivation: 1. All unix-domain STREAM sockets should be created equal. We can support it, so why shouldn't we? 2. getpeerucred on Solaris, SO_PEERCRED on Linux, and of most relevance MacOS's implementation of LOCAL_PEERCRED all work fine on socketpair sockets. (A point against is that AIX's getpeereid follows the BSD behaviour of requiring a connect/listen call.) Programmers are therefore more likely to expect it to work than not. Apart from AIX, we're the only people not providing this capability. 3. Real-world uses. I was actually trying to sandbox a daemon with capsicum when I ran into this, which requires a certain amount of mucking around with file descriptor passing. Being able to establish a channel with a socketpair, hand it to a secure daemon, and be able to check the peer's credentials in the daemon, is a reasonable use-case. 4. Compatibility. It's not going to break old applications to make the change. Patch: --- sys/kern/uipc_syscalls.c.RELEASE-9.1-243808 2013-02-21 13:37:31.778270145 +0000 +++ sys/kern/uipc_syscalls.c 2013-02-21 13:45:58.747896673 +0000 @@ -642,6 +642,19 @@ error = soconnect2(so2, so1); if (error) goto free4; + } else if (type == SOCK_STREAM) { + struct unpcb *unp, *unp2; + unp = sotounpcb(so1); + unp2 = sotounpcb(so2); + UNP_PCB_LOCK(unp); + UNP_PCB_LOCK(unp2); + cru2x(td->td_ucred, &unp->unp_peercred); + memcpy(&unp2->unp_peercred, &unp->unp_peercred, + sizeof(unp2->unp_peercred)); + unp->unp_flags |= UNP_HAVEPC; + unp2->unp_flags |= UNP_HAVEPC; + UNP_PCB_UNLOCK(unp); + UNP_PCB_UNLOCK(unp2); } finit(fp1, FREAD | FWRITE, DTYPE_SOCKET, fp1->f_data, &socketops); finit(fp2, FREAD | FWRITE, DTYPE_SOCKET, fp2->f_data, &socketops); I've not looked into the FreeBSD kernel before, so the patch may be useless! I think conceptually it's the right place to put it though. unix.4.man and getpeereid.3.man would have to be updated also. Best wishes, Nicholas ----- Nicholas Wilson: nicho...@nicholaswilson.me.uk Site and blog: www.nicholaswilson.me.uk 6 Tribune Court, CB4 2TU 07845 182898 _______________________________________________ freebsd-hackers@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-hackers To unsubscribe, send any mail to "freebsd-hackers-unsubscr...@freebsd.org"