16

SO_PEERCRED is simple way to get pid/uid/gid of connected AF_UNIX stream socket, SCM_CREDENTIALS is more or less the same, but more complex (various ancillary messages). Links to example showing both ways.

  1. Why there are two ways to get more or less the same information?
  2. Why the more comfortable SO_PEERCRED is not listed in unix(7) manpage?
  3. Which is use more in real-life applicatins?

What should I use?

2 Answers 2

15
  1. If I understand correctly, there is a subtle difference between the two. SO_PEERCRED retrieves the credentials of the peer process, without requiring any interaction from the peer process. In contrast, SCM_CREDENTIALS is a mechanism to send / receive credentials of the peer process, which are then checked by the kernel. This subtle difference may matter when a process is running as UID 0. SCM_CREDENTIALS allows a process running as UID 0, to declare itself less privileged (e.g., UID 50), whereas this would not be possible with SO_PEERCRED.

  2. See above. I guess using SCM_CREDENTIALS is encouraged and SO_PEERCRED is only supported for compatibility.

  3. The dbus daemon seems to use SO_PEERCRED and getpeereid(). I think it is best to copy their code in order to portably get the credentials.

http://cgit.freedesktop.org/dbus/dbus/tree/dbus/dbus-sysdeps-unix.c?id=edaa6fe253782dda959d78396b43e9fd71ea77e3

3
  • 7
    There's another subtle difference. SO_PEERCRED gives you the credentials of the process that created the socket at the other end. The process that created the socket can later drop privileges, setuid, setgid, etc. and your SO_PEERCRED results will remain unchanged.
    – jtchitty
    Commented May 24, 2017 at 4:29
  • 2
    To further clarify @jtchitty's comment - created would mean the time peer called connect (and not socket).
    – domen
    Commented Mar 12, 2019 at 11:35
  • 1
    It's also worth noting that you'll only get valid data in SCM_CREDENTIALS after at least one end of the socket has turned on SO_PASSCRED. If you turn on SO_PASSCRED, and then try to receive a message that was sent before hand, you'll receive an SCM_CREDENTIALS control message with invalid values (pid = 0, uid/gid = -1). Commented Nov 28, 2023 at 13:49
6

SO_PEERCRED returns the socket peer's credentials. SCM_CREDENTIALS allows you to pass any credentials which you have privilege over. This is particularly valuable because the kernel will translate the ids, so a task in one pid namespace can send a pid to process in another namespace, and be assured that the received pid will refer to the same process it intended.

If you want the peer's credential then use SO_PEERCRED. SCM_CREDENTIAL is a credential which the caller specified (which it did have to have privilege over), not necessarily the peer's.

Not the answer you're looking for? Browse other questions tagged or ask your own question.