Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Identify other end of a unix domain socket connection

I'm trying to figure out what process is holding the other end of a unix domain socket. In some strace output I've identified a given file descriptor which is involved in the problem I'm currently debugging, and I'd like to know which process is on the other end of that. As there are multiple connections to that socket, simply going by path name won't work.

lsof provides me with the following information:

dbus-daem  4175  mvg   10u  unix 0xffff8803e256d9c0      0t0  12828 @/tmp/dbus-LyGToFzlcG

So I know some address (“kernel address”?), I know some socket number, and I know the path. I can find that same information in other places:

$ netstat -n | grep 12828
unix  3      [ ]         STREAM     CONNECTED     12828    @/tmp/dbus-LyGToFzlcG
$ grep -E '12828|ffff8803e256d9c0' /proc/net/unix
ffff8803e256d9c0: 00000003 00000000 00000000 0001 03 12828 @/tmp/dbus-LyGToFzlcG
$ ls -l /proc/*/fd/* 2>/dev/null | grep 12828
lrwx------ 1 mvg users 64 10. Aug 09:08 /proc/4175/fd/10 -> socket:[12828]

However, none of this tells me what the other end of my socket connection is. How can I tell which process is holding the other end?

like image 943
MvG Avatar asked Aug 10 '12 08:08

MvG


2 Answers

Similar questions have been asked on Server Fault and Unix & Linux. The accepted answer is that this information is not reliably available to the user space on Linux.

A common suggestion is to look at adjacent socket numbers, but ls -l /proc/*/fd/* 2>/dev/null | grep 1282[79] gave no results here. Perhaps adjacent lines in the output from netstat can be used. It seems like there was a pattern of connections with and without an associated socket name. But I'd like some kind of certainty, not just guesswork.

One answer suggests a tool which appears to be able to address this by digging through kernel structures. Using that option requires debug information for the kernel, as generated by the CONFIG_DEBUG_INFO option and provided as a separate package by some distributions. Based on that answer, using the address provided by lsof, the following solution worked for me:

# gdb /usr/src/linux/vmlinux /proc/kcore
(gdb) p ((struct unix_sock*)0xffff8803e256d9c0)->peer

This will print the address of the other end of the connection. Grepping lsof -U for that number will provide details like the process id and the file descriptor number.

If debug information is not available, it might be possible to access the required information by knowing the offset of the peer member into the unix_sock structure. In my case, on Linux 3.5.0 for x86_64, the following code can be used to compute the same address without relying on debugging symbols:

(gdb) p ((void**)0xffff8803e256d9c0)[0x52]

I won't make any guarantees about how portable that solution is.

like image 89
MvG Avatar answered Sep 29 '22 17:09

MvG


Update: It's been possible to to do this using actual interfaces for a while now. Starting with Linux 3.3, the UNIX_DIAG feature provides a netlink-based API for this information, and lsof 4.89 and later support it. See https://unix.stackexchange.com/a/190606/1820 for more information.

like image 27
SamB Avatar answered Sep 29 '22 17:09

SamB