I've noticed that getpeereid/LOCAL_PEERCRED doesn't work with sockets created through socketpair, but only through actual listen/connect calls. I'd like to suggest we support peercred for socketpair-created sockets. Motivation: 1. All unix-domain STREAM sockets should be created equal. 2. getpeerucred on Solaris and SO_PEERCRED on Linux work fine on socketpair sockets. More relevantly, the MacOS X implementation of LOCAL_PEERCRED works with 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, 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. Fix: 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). Patch attached hopefully fixes the problem in an acceptable way. It's the responsibility of the socketpair call to provide stamp the appropriate credentials when it makes a connection (unp_connect2 doesn't know enough about the calling context to take it on itself to do this). Patch attached. unix.4.man and getpeereid.3.man would have to be updated also. Patch attached with submission follows: How-To-Repeat: int main() { int fds[2]; if (socketpair(AF_UNIX, SOCK_STREAM, 0, fds) < 0) exit(1); uid_t uid; gid_t gid; return getpeereid(fds[0], &uid, &gid) < 0 ? 1 : 0; } Expected result: does not fail Actual result: fails
Responsible Changed From-To: freebsd-bugs->freebsd-net Over to maintainer(s).
I think I hit this recently as well. Man page contains wording: [ENOTCONN] The argument s does not refer to a socket on which connect(2) or listen(2) have been called. Which actually describes situation exactly, but it is bit non-obvious that it also means implicit exclusion of socktepair(). More over, as mentioned by nicholas, other system I tried (Linux) supports getting this information about socketpair() created sockets. I have not yet tried OS X. I wanted to use this to verify socket owner credentials (usually parent process), before consuming data from it, in scripted environment. Unfortunately, this feature can be used only when I go through fs namespace. I don't know how these "anonymous" sockets (created by socketpair()) are implemented internally but, I think creating socket files in my situation is kinda wasteful.
batch change: For bugs that match the following - Status Is In progress AND - Untouched since 2018-01-01. AND - Affects Base System OR Documentation DO: Reset to open status. Note: I did a quick pass but if you are getting this email it might be worthwhile to double check to see if this bug ought to be closed.
Code review in progress https://reviews.freebsd.org/D16350
A commit references this bug: Author: asomers Date: Fri Aug 3 01:37:01 UTC 2018 New revision: 337222 URL: https://svnweb.freebsd.org/changeset/base/337222 Log: Fix LOCAL_PEERCRED with socketpair(2) Enable the LOCAL_PEERCRED socket option for unix domain stream sockets created with socketpair(2). Previously, it only worked with unix domain stream sockets created with socket(2)/listen(2)/connect(2)/accept(2). PR: 176419 Reported by: Nicholas Wilson <nicholas@nicholaswilson.me.uk> MFC after: 2 weeks Differential Revision: https://reviews.freebsd.org/D16350 Changes: head/sys/kern/uipc_syscalls.c head/sys/kern/uipc_usrreq.c head/sys/sys/unpcb.h head/tests/sys/kern/Makefile head/tests/sys/kern/unix_socketpair_test.c
A commit references this bug: Author: asomers Date: Mon Oct 1 17:37:00 UTC 2018 New revision: 339067 URL: https://svnweb.freebsd.org/changeset/base/339067 Log: MFC r337222: Fix LOCAL_PEERCRED with socketpair(2) Enable the LOCAL_PEERCRED socket option for unix domain stream sockets created with socketpair(2). Previously, it only worked with unix domain stream sockets created with socket(2)/listen(2)/connect(2)/accept(2). PR: 176419 Reported by: Nicholas Wilson <nicholas@nicholaswilson.me.uk> Differential Revision: https://reviews.freebsd.org/D16350 Changes: _U stable/11/ stable/11/sys/kern/uipc_syscalls.c stable/11/sys/kern/uipc_usrreq.c stable/11/sys/sys/unpcb.h stable/11/tests/sys/kern/Makefile stable/11/tests/sys/kern/unix_socketpair_test.c
A commit references this bug: Author: asomers Date: Mon Oct 1 18:00:53 UTC 2018 New revision: 339068 URL: https://svnweb.freebsd.org/changeset/base/339068 Log: MFC r337222: Fix LOCAL_PEERCRED with socketpair(2) Enable the LOCAL_PEERCRED socket option for unix domain stream sockets created with socketpair(2). Previously, it only worked with unix domain stream sockets created with socket(2)/listen(2)/connect(2)/accept(2). PR: 176419 Reported by: Nicholas Wilson <nicholas@nicholaswilson.me.uk> Differential Revision: https://reviews.freebsd.org/D16350 Changes: _U stable/10/ stable/10/sys/kern/uipc_syscalls.c stable/10/sys/kern/uipc_usrreq.c stable/10/sys/sys/unpcb.h stable/10/tests/sys/kern/Makefile stable/10/tests/sys/kern/unix_socketpair_test.c