Bug 176419 - socketpair support for LOCAL_PEERCRED
Summary: socketpair support for LOCAL_PEERCRED
Status: Closed FIXED
Alias: None
Product: Base System
Classification: Unclassified
Component: kern (show other bugs)
Version: Unspecified
Hardware: Any Any
: Normal Affects Only Me
Assignee: Alan Somers
URL: https://reviews.freebsd.org/D16350
Keywords: needs-qa
Depends on:
Blocks:
 
Reported: 2013-02-25 13:00 UTC by Nicholas Wilson
Modified: 2018-10-01 18:01 UTC (History)
5 users (show)

See Also:
asomers: mfc-stable11+
asomers: mfc-stable10+


Attachments
file.txt (1.02 KB, text/plain)
2013-02-25 13:00 UTC, Nicholas Wilson
no flags Details

Note You need to log in before you can comment on or make changes to this bug.
Description Nicholas Wilson 2013-02-25 13:00:00 UTC
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
Comment 1 Mark Linimon freebsd_committer freebsd_triage 2013-02-27 00:19:05 UTC
Responsible Changed
From-To: freebsd-bugs->freebsd-net

Over to maintainer(s).
Comment 2 Martin eto Misuth 2016-05-04 17:08:47 UTC
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.
Comment 3 Eitan Adler freebsd_committer freebsd_triage 2018-05-28 19:45:44 UTC
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.
Comment 4 Alan Somers freebsd_committer freebsd_triage 2018-07-19 16:22:59 UTC
Code review in progress https://reviews.freebsd.org/D16350
Comment 5 commit-hook freebsd_committer freebsd_triage 2018-08-03 01:37:54 UTC
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
Comment 6 commit-hook freebsd_committer freebsd_triage 2018-10-01 17:37:49 UTC
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
Comment 7 commit-hook freebsd_committer freebsd_triage 2018-10-01 18:01:10 UTC
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