Подтвердить что ты не робот

Идентифицировать другой конец соединения сокета домена unix

Я пытаюсь выяснить, какой процесс держит другой конец сокета домена unix. В некотором strace выводе я определил заданный файловый дескриптор, который участвует в проблеме, которую я сейчас отлаживаю, и я хотел бы знать, какой процесс находится на другом конце этого. Поскольку для этого сокета существует несколько соединений, просто переход по имени пути не будет работать.

lsof предоставляет мне следующую информацию:

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

Итак, я знаю какой-то адрес ( "адрес ядра"?), я знаю номер сокета, и я знаю путь. Я могу найти ту же информацию в других местах:

$ 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]

Однако, ничто из этого не говорит мне о том, каким другим концом моего соединения сокета. Как я могу определить, какой процесс поддерживает другой конец?

4b9b3361

Ответ 1

Обновление: теперь можно было сделать это с использованием реальных интерфейсов. Начиная с Linux 3.3, функция UNIX_DIAG предоставляет для этой информации API-интерфейс на основе netlink, а lsof 4.89 и более поздние версии поддерживают его. Подробнее см. https://unix.stackexchange.com/a/190606/1820.

Ответ 2

Аналогичные вопросы задавали Ошибка сервера и Unix и Linux. Принятый ответ заключается в том, что эта информация не надежно доступна для пользовательского пространства в Linux.

Общее предложение - посмотреть на соседние номера сокетов, но ls -l /proc/*/fd/* 2>/dev/null | grep 1282[79] не дал никаких результатов. Возможно, могут использоваться смежные строки на выходе из netstat. Похоже, что существует образец соединений с и без связанного имени сокета. Но мне нужна определенная определенность, а не просто догадки.

Один ответ предлагает инструмент, который, по-видимому, способен решить это, выкапывая структуры ядра. Для использования этого параметра требуется отладочная информация для ядра, генерируемая опцией CONFIG_DEBUG_INFO и предоставляемая отдельными пакетами некоторыми дистрибутивами. Исходя из этого ответа, используя адрес, предоставленный lsof, для меня работало следующее решение:

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

Это напечатает адрес другого конца соединения. Grepping lsof -U для этого номера предоставит детали, такие как идентификатор процесса и номер дескриптора файла.

Если отладочная информация недоступна, возможно, будет доступ к необходимой информации, зная смещение члена-партнера в структуру unix_sock. В моем случае, в Linux 3.5.0 для x86_64, следующий код может использоваться для вычисления одного и того же адреса без использования отладочных символов:

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

Я не буду давать никаких гарантий относительно того, насколько переносимо это решение.