У кого есть другой конец этого Unix socketpair?

Системные вызовы не обрабатываются как вызовы регулярной функции. Это берет специальный код для создания перехода от пространства пользователя до пространства ядра, в основном немного кода встроенного ассемблерного кода введенный в программу на сайте вызова. Код стороны ядра, который "ловит" системный вызов, является также материалом низкого уровня, который Вы, вероятно, не должны понимать глубоко по крайней мере сначала.

В include/linux/syscalls.h в соответствии с Вашим исходным каталогом ядра, Вы находите это:

asmlinkage long sys_mkdir(const char __user *pathname, int mode);

Затем в /usr/include/asm*/unistd.h, Вы находите это:

#define __NR_mkdir                              83
__SYSCALL(__NR_mkdir, sys_mkdir)

В этом коде говорится mkdir(2) системный вызов № 83. То есть системные вызовы называет число, не адресом как с нормальным вызовом функции в рамках Вашей собственной программы или к функции в библиотеке, связанной с Вашей программой. Связующее звено встроенного ассемблерного кода кодирует, я упомянул выше использования это для создания перехода от пользователя к пространству ядра, беря параметры наряду с ним.

Другой бит доказательства, что вещи являются немного странными здесь, - то, что существует не всегда строгий список параметров для системных вызовов: open(2), например, может взять или 2 или 3 параметра. Это означает open(2) перегружается, функция C++, не C, все же интерфейс syscall является C-compatible. (Это не то же самое как функция C varargs, которая позволяет единственной функции брать переменное количество аргументов.)

Для ответа на первый вопрос нет никакого единственного файла где mkdir() существует. Linux поддерживает много различных файловых систем, и у каждого есть его собственная реализация "mkdir" операции. Уровень абстракции, который позволяет ядру скрыть все, что позади вызова единой системы называют VFS. Так, Вы, вероятно, хотите начать закапывать fs/namei.c, с vfs_mkdir(). Фактическая реализация кода изменения файловой системы низкого уровня в другом месте. Например, ext4 реализацию называют ext4_mkdir(), определенный в fs/ext4/namei.c.

Что касается Вашего второго вопроса, да существуют шаблоны ко всему этому, но ни одно правило. То, в чем Вы на самом деле нуждаетесь, является довольно широким пониманием того, как ядро работает для выяснения, где необходимо искать какой-то конкретный системный вызов. Не все системные вызовы включают VFS, таким образом, их цепочки вызовов стороны ядра выполняют не, все запускают fs/namei.c. mmap(2), например, запускается в mm/mmap.c, потому что это - часть управления памятью ("мм") подсистема ядра.

Я рекомендую получить копию "Понимания Ядра Linux" Bovet и Cesati.

57
26.03.2015, 00:16
8 ответов

Начиная с ядра 3.3, это - возможное использование ss или lsof-4.89 или выше — см. ответ Stéphane Chazelas.

В более старых версиях, по словам автора lsof, было невозможно узнать это: ядро Linux не выставляет эту информацию. Источник: поток 2003 года на comp.unix.admin.

Число, показанное в /proc/$pid/fd/$fd inode число сокета в виртуальной файловой системе сокета. При создании канала или пары сокета каждый конец последовательно получает inode число. Числа приписываются последовательно, таким образом, существует высокая вероятность, что числа отличаются 1, но это не гарантируется (или потому что первый сокет был N, и N+1 уже использовался из-за обертывания, или потому что некоторый другой поток был запланирован между двумя inode выделениями, и тот поток создал некоторый inodes также).

Я проверил определение socketpair в ядре 2.6.39 и двух концах сокета не коррелируются кроме определенным для типа socketpair метод. Для сокетов Unix это unix_socketpair в net/unix/af_unix.c.

28
27.01.2020, 19:33
  • 1
    Спасибо @Gillles. Я действительно вспоминаю чтение чего-то о том некоторое время назад, но не могло найти его снова. Мне, вероятно, просто придется пойти, пишущий патч для/proc/net/unix. –  Jonathon Reinhart 10.07.2011, 01:09
  • 2
    И да, я сделал то наблюдение с увеличением inode числами, и в настоящее время это - то, с чем я работаю. Однако как Вы отметили, это не гарантируется. Процесс, на который я смотрю, имеет по крайней мере 40 открытых сокетов Unix, и я видел один экземпляр, где N+1 не сохранялся. Неприятность. –  Jonathon Reinhart 10.07.2011, 01:11
  • 3
    @JonathonReinhart я проверил определение socketpair, и два конца сокета не коррелируются кроме определенным для типа socketpair метод. Для сокетов Unix это unix_socketpair в 'net/unix/af_unix.c. Было бы хорошо иметь эту информацию для каналов, также. –  Gilles 'SO- stop being evil' 10.07.2011, 01:35

Erkki Seppala на самом деле имеет инструмент, который получает эту информацию от ядра Linux с gdb.. Это доступно здесь.

9
27.01.2020, 19:33
  • 1
    Очень полезная информация! Даже если инструмент не работал из поля на меня (это вызвало ядро ой), идея помогла мне определить другой конец. Я описал свое решение на Переполнении стека. –  MvG 15.08.2012, 23:33

ПРИМЕЧАНИЕ : Я сейчас поддерживаю обертку LSOF , который сочетает в себе оба подхода, описанные здесь, а также добавляет информацию для сверстников соединений TCP обратной связи в https://github.com/stephane-Chazelas/misc-scripts/blob/master/lsofc

Linux-3.3 и выше.

В Linux, поскольку ядра версии 3.3 (и предоставлена ​​функция Unix_diag , встроена в ядре), сверстник данного домена Unix (включает в себя сокет отправления) можно получить с помощью нового NetLink на основе API.

LSOF Поскольку версия 4.89 может воспользоваться этим API:

lsof +E -aUc Xorg

будет перечислять все розетки домена UNIX, которые имеют процесс, имя которого начинается с xorg при любом конце в формате, аналогичном :

Xorg       2777       root   56u  unix 0xffff8802419a7c00      0t0   34036 @/tmp/.X11-unix/X0 type=STREAM ->INO=33273 4120,xterm,3u

Если ваша версия LSOF слишком старая, есть еще несколько вариантов.

Утилита SS (из IPROUTE2 ) использует эту же API для извлечения и отображения информации в списке доменных сокетов Unix в системе, включая информацию о свертчике.

Розетки идентифицируются своим номером INODE . Обратите внимание, что это не связано с inode файловой системы файла сокета.

Например, в:

$ ss -x
[...]
u_str  ESTAB    0    0   @/tmp/.X11-unix/X0 3435997     * 3435996

написано, что разъем 3435997 (который был связан с абстрактным розеткой /tmp/.x11-unix/x0 )) подключен с разъемом 3435996. - P Опция может сказать вам, какой процесс (ES) открыт этот сокет. Это делает это, делая некоторые readLink / / proc / $ PID / FD / * , так что он может сделать это только в своих процессах (если только вы root ). Например, здесь:

$ sudo ss -xp
[...]
u_str  ESTAB  0  0  @/tmp/.X11-unix/X0 3435997 * 3435996 users:(("Xorg",pid=3080,fd=83))
[...]
$ sudo ls -l /proc/3080/fd/23
lrwx------ 1 root root 64 Mar 12 16:34 /proc/3080/fd/83 -> socket:[3435997]

Чтобы узнать, какой процесс (ES) имеет 3435996, вы можете посмотреть свой вход в вывод SS -xp :

$ ss -xp | awk '$6 == 3435996'
u_str  ESTAB  0  0  * 3435996  * 3435997 users:(("xterm",pid=29215,fd=3))

Вы также можете использовать этот скрипт как Обелочка вокруг LSOF , чтобы легко показать соответствующую информацию там:

#! /usr/bin/perl
# lsof wrapper to add peer information for unix domain socket.
# Needs Linux 3.3 or above and CONFIG_UNIX_DIAG enabled.

# retrieve peer and direction information from ss
my (%peer, %dir);
open SS, '-|', 'ss', '-nexa';
while (<SS>) {
  if (/\s(\d+)\s+\*\s+(\d+) ([<-]-[->])$/) {
    $peer{$1} = $2;
    $dir{$1} = $3;
  }
}
close SS;

# Now get info about processes tied to sockets using lsof
my (%fields, %proc);
open LSOF, '-|', 'lsof', '-nPUFpcfin';
while (<LSOF>) {
  if (/(.)(.*)/) {
    $fields{$1} = $2;
    if ($1 eq 'n') {
      $proc{$fields{i}}->{"$fields{c},$fields{p}" .
      ($fields{n} =~ m{^([@/].*?)( type=\w+)?$} ? ",$1" : "")} = "";
    }
  }
}
close LSOF;

# and finally process the lsof output
open LSOF, '-|', 'lsof', @ARGV;
while (<LSOF>) {
  chomp;
  if (/\sunix\s+\S+\s+\S+\s+(\d+)\s/) {
    my $peer = $peer{$1};
    if (defined($peer)) {
      $_ .= $peer ?
            " ${dir{$1}} $peer\[" . (join("|", keys%{$proc{$peer}})||"?") . "]" :
            "[LISTENING]";
    }
  }
  print "$_\n";
}
close LSOF or exit(1);

Например:

$ sudo that-lsof-wrapper -ad3 -p 29215
COMMAND   PID     USER   FD   TYPE             DEVICE SIZE/OFF    NODE NAME
xterm   29215 stephane    3u  unix 0xffff8800a07da4c0      0t0 3435996 type=STREAM <-> 3435997[Xorg,3080,@/tmp/.X11-unix/X0]

Перед Linux-3.3

Старый API Linux для получения информации о сокете Unix - через / proc / net / Unix Текстовый файл. Он перечисляет все сокеты домена UNIX (включая сокет отправления). Первое поле там (если не скрыто для не суперпроужиров с помощью Kernel.kptr_restrict Sysctl Parameter) AS , уже объяснено @TOTOR , содержит адрес ядра A Unix_sock Структура, которая содержит поля Peer , указывая на соответствующую Peer Unix_sock . Это также то, что выходы LSOF для столбца в столбце на разъеме Unix.

Теперь получение стоимости этого Peer поле означает возможность читать память ядра и знать смещение поля Peer в зависимости от адреса Unix_sock Отказ

Несколько GDB и и SystemTap решений уже даны, но они требуют GDB / SystemTap И символы отладки ядра Linux для установки беговой ядра, который, как правило, не имеет место в производственных системах.

Харкодирование смещения не совсем вариант, так как это варьируется в зависимости от версии ядра.

Теперь мы можем использовать эвристический подход при определении смещения: у нашего инструмента создать манекен Socketpair (тогда мы знаем адрес обоих сверстников),и поиск адреса Peer вокруг памяти на другом конце, чтобы определить смещение.

Вот подтверждающий концептуальный скрипт, который делает только что с использованием Perl (успешно протестировано с ядром 2.4.27 и 2.6.32 на I386 и 3.13 и 3.16 на AMD64). Как указано выше, он работает как обертка вокруг LSOF :

Например:

$ that-lsof-wrapper -aUc nm-applet
COMMAND    PID     USER   FD   TYPE             DEVICE SIZE/OFF  NODE NAME
nm-applet 4183 stephane    4u  unix 0xffff8800a055eb40      0t0 36888 type=STREAM -> 0xffff8800a055e7c0[dbus-daemon,4190,@/tmp/dbus-AiBCXOnuP6]
nm-applet 4183 stephane    7u  unix 0xffff8800a055e440      0t0 36890 type=STREAM -> 0xffff8800a055e0c0[Xorg,3080,@/tmp/.X11-unix/X0]
nm-applet 4183 stephane    8u  unix 0xffff8800a05c1040      0t0 36201 type=STREAM -> 0xffff8800a05c13c0[dbus-daemon,4118,@/tmp/dbus-yxxNr1NkYC]
nm-applet 4183 stephane   11u  unix 0xffff8800a055d080      0t0 36219 type=STREAM -> 0xffff8800a055d400[dbus-daemon,4118,@/tmp/dbus-yxxNr1NkYC]
nm-applet 4183 stephane   12u  unix 0xffff88022e0dfb80      0t0 36221 type=STREAM -> 0xffff88022e0df800[dbus-daemon,2268,/var/run/dbus/system_bus_socket]
nm-applet 4183 stephane   13u  unix 0xffff88022e0f80c0      0t0 37025 type=STREAM -> 0xffff88022e29ec00[dbus-daemon,2268,/var/run/dbus/system_bus_socket]

Вот сценарий:

#! /usr/bin/perl
# wrapper around lsof to add peer information for Unix
# domain sockets. needs lsof, and superuser privileges.
# Copyright Stephane Chazelas 2015, public domain.
# example: sudo this-lsof-wrapper -aUc Xorg
use Socket;

open K, "<", "/proc/kcore" or die "open kcore: $!";
read K, $h, 8192 # should be more than enough
 or die "read kcore: $!";

# parse ELF header
my ($t,$o,$n) = unpack("x4Cx[C19L!]L!x[L!C8]S", $h);
$t = $t == 1 ? "L3x4Lx12" : "Lx4QQx8Qx16"; # program header ELF32 or ELF64
my @headers = unpack("x$o($t)$n",$h);

# read data from kcore at given address (obtaining file offset from ELF
# @headers)
sub readaddr {
  my @h = @headers;
  my ($addr, $length) = @_;
  my $offset;
  while (my ($t, $o, $v, $s) = splice @h, 0, 4) {
    if ($addr >= $v && $addr < $v + $s) {
      $offset = $o + $addr - $v;
      if ($addr + $length - $v > $s) {
        $length = $s - ($addr - $v);
      }
      last;
    }
  }
  return undef unless defined($offset);
  seek K, $offset, 0 or die "seek kcore: $!";
  my $ret;
  read K, $ret, $length or die "read($length) kcore \@$offset: $!";
  return $ret;
}

# create a dummy socketpair to try find the offset in the
# kernel structure
socketpair(Rdr, Wtr, AF_UNIX, SOCK_STREAM, PF_UNSPEC)
 or die "socketpair: $!";
$r = readlink("/proc/self/fd/" . fileno(Rdr)) or die "readlink Rdr: $!";
$r =~ /\[(\d+)/; $r = $1;
$w = readlink("/proc/self/fd/" . fileno(Wtr)) or die "readlink Wtr: $!";
$w =~ /\[(\d+)/; $w = $1;
# now $r and $w contain the socket inodes of both ends of the socketpair
die "Can't determine peer offset" unless $r && $w;

# get the inode->address mapping
open U, "<", "/proc/net/unix" or die "open unix: $!";
while (<U>) {
  if (/^([0-9a-f]+):(?:\s+\S+){5}\s+(\d+)/) {
    $addr{$2} = hex $1;
  }
}
close U;

die "Can't determine peer offset" unless $addr{$r} && $addr{$w};

# read 2048 bytes starting at the address of Rdr and hope to find
# the address of Wtr referenced somewhere in there.
$around = readaddr $addr{$r}, 2048;
my $offset = 0;
my $ptr_size = length(pack("L!",0));
my $found;
for (unpack("L!*", $around)) {
  if ($_ == $addr{$w}) {
    $found = 1;
    last;
  }
  $offset += $ptr_size;
}
die "Can't determine peer offset" unless $found;

my %peer;
# now retrieve peer for each socket
for my $inode (keys %addr) {
  $peer{$addr{$inode}} = unpack("L!", readaddr($addr{$inode}+$offset,$ptr_size));
}
close K;

# Now get info about processes tied to sockets using lsof
my (%fields, %proc);
open LSOF, '-|', 'lsof', '-nPUFpcfdn';
while (<LSOF>) {
  if (/(.)(.*)/) {
    $fields{$1} = $2;
    if ($1 eq 'n') {
      $proc{hex($fields{d})}->{"$fields{c},$fields{p}" .
      ($fields{n} =~ m{^([@/].*?)( type=\w+)?$} ? ",$1" : "")} = "";
    }
  }
}
close LSOF;

# and finally process the lsof output
open LSOF, '-|', 'lsof', @ARGV;
while (<LSOF>) {
  chomp;
  for my $addr (/0x[0-9a-f]+/g) {
    $addr = hex $addr;
    my $peer = $peer{$addr};
    if (defined($peer)) {
      $_ .= $peer ?
            sprintf(" -> 0x%x[", $peer) . join("|", keys%{$proc{$peer}}) . "]" :
            "[LISTENING]";
      last;
    }
  }
  print "$_\n";
}
close LSOF or exit(1);
38
27.01.2020, 19:33

Это решение, хотя и работает, но представляет ограниченный интерес, так как если у вас есть достаточно свежая системная запись, то, скорее всего, у вас будет достаточно свежее ядро, в котором вы можете использовать ss на основе подходов , а если вы используете более старое ядро, то это другое решение , хотя более hacky более вероятно будет работать и не требует дополнительного программного обеспечения.

По-прежнему полезно в качестве демонстрации того, как использовать systemtap для такого рода задач.

Если на недавней системе Linux с рабочей системной записью (1.8 или более новой), вы можете использовать скрипт ниже для постобработки вывода lsof:

Например:

$ lsof -aUc nm-applet | sudo that-script
COMMAND    PID     USER   FD   TYPE             DEVICE SIZE/OFF  NODE NAME
nm-applet 4183 stephane    4u  unix 0xffff8800a055eb40      0t0 36888 type=STREAM -> 0xffff8800a055e7c0[dbus-daemon,4190,@/tmp/dbus-AiBCXOnuP6]
nm-applet 4183 stephane    7u  unix 0xffff8800a055e440      0t0 36890 type=STREAM -> 0xffff8800a055e0c0[Xorg,3080,@/tmp/.X11-unix/X0]
nm-applet 4183 stephane    8u  unix 0xffff8800a05c1040      0t0 36201 type=STREAM -> 0xffff8800a05c13c0[dbus-daemon,4118,@/tmp/dbus-yxxNr1NkYC]
nm-applet 4183 stephane   11u  unix 0xffff8800a055d080      0t0 36219 type=STREAM -> 0xffff8800a055d400[dbus-daemon,4118,@/tmp/dbus-yxxNr1NkYC]
nm-applet 4183 stephane   12u  unix 0xffff88022e0dfb80      0t0 36221 type=STREAM -> 0xffff88022e0df800[dbus-daemon,2268,/var/run/dbus/system_bus_socket]
nm-applet 4183 stephane   13u  unix 0xffff88022e0f80c0      0t0 37025 type=STREAM -> 0xffff88022e29ec00[dbus-daemon,2268,/var/run/dbus/system_bus_socket]

(если вы видите 0x000000000000 выше вместо 0xffff.... то это потому, что в вашей системе установлен sysctl параметр kernel.kptr_restrict, что приводит к сокрытию указателей ядра от непривилегированных процессов, и в этом случае для получения значимого результата необходимо запустить lsof в качестве корня).

Этот скрипт не делает никаких попыток справиться с именами файлов сокетов с символами новой строки, но также lsoflsof не справляется с пробелами или двоеточиями). Здесь

systemtap используется для дампа адреса и однорангового адреса всех структур unix_sock в хэше unix_socket_table кернела.

Только в Linux 3.16 amd64 с systemtap 2.6 и 3.13 с 2.3.

#! /usr/bin/perl
# meant to process lsof output to try and find the peer of a given
# unix domain socket. Needs a working systemtap, lsof, and superuser
# privileges. Copyright Stephane Chazelas 2015, public domain.
# Example: lsof -aUc X | sudo this-script
open STAP, '-|', 'stap', '-e', q{
  probe begin {
    offset = &@cast(0, "struct sock")->__sk_common->skc_node;
    for (i = 0; i < 512; i++) 
      for (p = @var("unix_socket_table@net/unix/af_unix.c")[i]->first;
           p;
           p=@cast(p, "struct hlist_node")->next
          ) {
        sock = p - offset;
        printf("%p %p\n", sock, @cast(sock, "struct unix_sock")->peer);
    }
    exit()
  }
};  
my %peer;
while (<STAP>) {
  chomp;
  my ($a, $b) = split;
  $peer{$a} = $b;
}
close STAP;

my %f, %addr;
open LSOF, '-|', 'lsof', '-nPUFpcfdn';
while (<LSOF>) {
  if (/(.)(.*)/) {
    $f{$1} = $2;
    if ($1 eq 'n') {
      $addr{$f{d}}->{"$f{c},$f{p}" . ($f{n} =~ m{^([@/].*?)( type=\w+)?$} ? ",$1" : "")} = "";
    }
  }
}
close LSOF;

while (<>) {
  chomp;
  for my $addr (/0x[0-9a-f]+/g) {
    my $peer = $peer{$addr};
    if (defined($peer)) {
      $_ .= $peer eq '0x0' ?
            "[LISTENING]" :
            " -> $peer\[" . join("|", keys%{$addr{$peer}}) . "]";
      last;
    }
  }
  print "$_\n";
}
5
27.01.2020, 19:33

Начиная с ядра 3.3

Вы можете теперь получить эту информацию с помощью ss :

# ss -xp

Теперь вы можете увидеть в столбце Peer ID (номер inode), который соответствует другому ID в столбце Local . Соответствующие идентификаторы - это два конца сокета.

Примечание. В вашем ядре должна быть включена опция UNIX_DIAG .

До ядра 3.3

Linux не предоставлял эту информацию пользователю.

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

Примечание. В этом ответе используется gdb , однако, пожалуйста, см. Ответ @ StéphaneChazelas , который более подробно описан в этом отношении.

# lsof | grep whatever
mysqld 14450 (...) unix 0xffff8801011e8280 (...) /var/run/mysqld/mysqld.sock
mysqld 14450 (...) unix 0xffff8801011e9600 (...) /var/run/mysqld/mysqld.sock

Имеется 2 разных сокета, 1 прослушивающий и 1 установленный. Шестнадцатеричное число - это адрес соответствующей структуры ядра unix_sock , имеющей атрибут peer , являющийся адресом другого конца сокета (также экземпляр структуры unix_sock ).

Теперь мы можем использовать gdb , чтобы найти одноранговый узел в памяти ядра:

# gdb /usr/lib/debug/boot/vmlinux-3.2.0-4-amd64 /proc/kcore
(gdb) print ((struct unix_sock*)0xffff8801011e9600)->peer
$1 = (struct sock *) 0xffff880171f078c0

# lsof | grep 0xffff880171f078c0
mysql 14815 (...) unix 0xffff880171f078c0 (...) socket

Итак, другой конец сокета удерживается mysql ], PID 14815.

Ваше ядро ​​должно быть скомпилировано с KCORE_ELF , чтобы использовать / proc / kcore . Кроме того, вам понадобится версия образа ядра с отладочными символами. В Debian 7 этот файл предоставит apt-get install linux-image-3.2.0-4-amd64-dbg .

Нет необходимости в отлаживаемом образе ядра ...

Если у вас нет (или вы не хотите сохранять) образ ядра отладки в системе, вы можете дать gdb смещение памяти для «ручного» доступа к одноранговому узлу значение. Это значение смещения обычно отличается в зависимости от версии ядра или архитектуры.

Я знаю, что в моем ядре смещение составляет 680 байт, то есть в 85 раз больше по 64 бита. Итак, я могу сделать:

# gdb /boot/vmlinux-3.2.0-4-amd64 /proc/kcore
(gdb) print ((void**)0xffff8801011e9600)[85]
$1 = (void *) 0xffff880171f078c0

Voilà, тот же результат, что и выше.

Если у вас одно и то же ядро ​​работает на нескольких машинах, этот вариант проще использовать, потому что вам не нужен отладочный образ, а только значение смещения.

Чтобы (легко) обнаружить это значение смещения сначала, вам понадобится отладочный образ:

$ pahole -C unix_sock /usr/lib/debug/boot/vmlinux-3.2.0-4-amd64
struct unix_sock {
  (...)
  struct sock *              peer;                 /*   680     8 */
  (...)
}

Вот, 680 байт, это 85 x 64 бита или 170 x 32 бита.

Большая заслуга в этом ответе принадлежит MvG .

8
27.01.2020, 19:33

4.89 lsof поддерживает отображение параметров конечной точки.

Цитата из lsof.8:

+|-E +E specifies that process intercommunication channels should be
     displayed with endpoint information and the channels
     of the endpoints should also be displayed.  Currently
     only pipe on Linux is implemented.

     Endpoint information is displayed in the NAME column
     in the form "PID,cmd,FDmode".  PID is the endpoint
     process ID; cmd is the endpoint process command; FD is
     the endpoint file's descriptor; and mode is the
     endpoint file's access mode.  Multiple occurrences of
     this information can appear in a file's NAME column.

     -E specfies that Linux pipe files should only be
     displayed with endpoint information.

Пример вывода:

mozStorag 21535 22254  yamato    6u     unix 0xf...       0t0     348924 type=STREAM pino=351122 4249,dbus-daem,55u
mozStorag 21535 22254  yamato   10u     unix 0xf...       0t0     356193 type=STREAM pino=356194 21535,gdbus,11u
mozStorag 21535 22254  yamato   11u     unix 0xf...       0t0     356194 type=STREAM pino=356193 21535,gdbus,10u
mozStorag 21535 22254  yamato   21u     unix 0xf...       0t0     355141 type=STREAM pino=357544 4249,dbus-daem,60u
mozStorag 21535 22254  yamato   26u     unix 0xf...       0t0     351134 type=STREAM pino=355142 5015,gdbus,17u
mozStorag 21535 22254  yamato   69u     unix 0xf...       0t0     469354 type=STREAM pino=468160 4545,alsa-sink,21u
mozStorag 21535 22254  yamato   82u     unix 0xf...       0t0     449383 type=STREAM pino=449384 12257,Chrome_Ch,3u
mozStorag 21535 22254  yamato   86u     unix 0xf...       0t0     355174 type=SEQPACKET pino=355175 21535,gdbus,95u
mozStorag 21535 22254  yamato   95u     unix 0xf...       0t0     355175 type=SEQPACKET pino=355174 21535,gdbus,86u 12257,Chrome_Ch,4u
mozStorag 21535 22254  yamato  100u     unix 0xf...       0t0     449389 type=STREAM pino=456453 3614,Xorg,38u
mozStorag 21535 22254  yamato  105u     unix 0xf...       0t0     582613 type=STREAM pino=586261
obexd     22163        yamato    1u     unix 0xf...       0t0     361859 type=STREAM pino=365931
obexd     22163        yamato    2u     unix 0xf...       0t0     361860 type=STREAM pino=365934
obexd     22163        yamato    3u     unix 0xf...       0t0     361241 type=DGRAM pino=10028
obexd     22163        yamato    6u     unix 0xf...       0t0     361242 type=STREAM pino=361864 4249,dbus-daem,70u
2
27.01.2020, 19:33

Начиная с ядра Linux 4.2 существует CONFIG_UNIX_DIAG, который предоставляет дополнительную информацию о сокетах домена UNIX, а именноVirtual File System(информацию VFS ), которая содержит до сих пор отсутствующую информацию для связи Inode с пути к процессу..Его уже можно запросить с помощью инструмента ssиз iproute2 , начиная с версии v4.19.0 ~55:

$ ss --processes --unix --all --extened
...
Netid  State   Recv-Q  Send-Q  Local Address:Port      Peer Address:Port
u_str  LISTEN  0       5         /tmp/socket 13381347             * 0     users:(("nc",pid=12550,fd=3)) <-> ino:1569897 dev:0/65025 peers:

Номер устройства и Inode пути, которые вы можете получить из

$ stat -c 'ino:%i dev:0/%d' /tmp/socket
ino:1569946 dev:0/65025

ssтакже поддерживает фильтрацию:

 ss --processes --unix --all --extended 'sport = /tmp/socket'

но имейте в виду, что здесь может быть указан не тот сокет, который вам нужен, так как злой процесс может переименовать исходный сокет и заменить его собственным злым:

mv /tmp/socket /tmp/socket.orig
nc -U -l /tmp/socket.evil &
mv /tmp/socket.evil /tmp/socket

lsof /tmp/socket, fuser /tmp/socketи ss --processes --unix --all --extended 'sport = /tmp/socket'будут перечислять исходный процесс, , а не замену злого. Вместо этого используйте что-то вроде этого:

id=$(stat -c 'ino:%i dev:0/%d' /tmp/socket)
ss --processes --unix --all --extended | grep -F "$id"

Или напишите свою маленькую программу на основе шаблона, содержащегося в man 7 sock _diag .

3
20.08.2021, 13:34

Я бы использовал px .

Отказ от ответственности :Я написал это, поэтому, конечно, я рекомендую это.

pxсообщит вам, с какими другими процессами общается ваш.

Пример вывода, прокрутите вниз для трассировки сокетов:

~ $ sudo px 49903
/Applications/Google Chrome.app/Contents/MacOS/Google Chrome
  --enable-audio-service-sandbox
  --origin-trial-disabled-features=MeasureMemory

kernel(0)                                     root
  launchd(1)                                  root
--> Google Chrome(49903)                      johan
      Google Chrome Helper(49922)             johan
      Google Chrome Helper(49958)             johan
      Google Chrome Helper (GPU)(49920)       johan
      Google Chrome Helper (Renderer)(49935)  johan
      Google Chrome Helper (Renderer)(49936)  johan
      Google Chrome Helper (Renderer)(49943)  johan
      Google Chrome Helper (Renderer)(49950)  johan
      Google Chrome Helper (Renderer)(49951)  johan
      Google Chrome Helper (Renderer)(49957)  johan
      Google Chrome Helper (Renderer)(64466)  johan
      Google Chrome Helper (Renderer)(75275)  johan
      Google Chrome Helper (Renderer)(76225)  johan
      Google Chrome Helper (Renderer)(76650)  johan
      Google Chrome Helper (Renderer)(76668)  johan
      Google Chrome Helper (Renderer)(76712)  johan

7d21h ago Google Chrome was started, at 2020-09-04T19:15:03+02:00.
0.3% has been its average CPU usage since then, or 32m25s/7d21h

Other processes started close to Google Chrome(49903):
  Google Chrome/chrome_crashpad_handler(49912) was started just after Google Chrome(49903)
  AlertNotificationService(49924) was started 1.0s after Google Chrome(49903)
  Google Chrome Helper(49922) was started 1.0s after Google Chrome(49903)
  Google Chrome Helper (GPU)(49920) was started 1.0s after Google Chrome(49903)
  Google Chrome Helper (Renderer)(49935) was started 1.0s after Google Chrome(49903)
  Google Chrome Helper (Renderer)(49936) was started 1.0s after Google Chrome(49903)
  VTDecoderXPCService(49934) was started 1.0s after Google Chrome(49903)

Users logged in when Google Chrome(49903) started:
  johan

2020-09-12T16:28:30.587930: Now invoking lsof, this can take over a minute on a big system...
2020-09-12T16:28:30.901834: lsof done, proceeding.

Others sharing this process' working directory (/)
  Working directory too common, never mind.

File descriptors:
  stdin : [CHR] /dev/null
  stdout: [CHR] /dev/null
  stderr: [CHR] /dev/null

Network connections:
  [IPv4] *:* (LISTEN)

Inter Process Communication:
  mDNSResponder(291): [unix] ->0x2b8028c5de1ab5b
  mDNSResponder(291): [unix] ->0x2b8028c5de1c5eb

For a list of all open files, do "sudo lsof -p 49903", or "sudo watch lsof -p 49903" for a live view.
~ $
0
20.08.2021, 13:34

Теги

Похожие вопросы