From: Masatake YAMATO Date: Sun, 9 Mar 2025 03:48:34 +0000 (+0900) Subject: lsfd: add a dummy entry for UNIX socket having no peer to the IPC table X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=28e950b0da1b7f32d96fea132c743b0b5798d819;p=thirdparty%2Futil-linux.git lsfd: add a dummy entry for UNIX socket having no peer to the IPC table With recvfrom(2) and sendto(2), we can use a UNIX datagram socket at server side without assigning a peer address with connect(2). Here, I call such sockets one-way sockets. # ss -x -p Netid State Recv-Q Send-Q Local Address:Port Peer Address:Port Process ... u_dgr ESTAB 0 0 /run/systemd/notify 13465 * 0 users:(("systemd",pid=1,fd=227)) u_dgr ESTAB 0 0 * 35438 * 13465 users:(("systemd-journal",pid=1280,fd=15)) u_dgr ESTAB 0 0 * 74792 * 13465 users:(("bluetoothd",pid=13874,fd=4)) ... The socket, opened with systemd as fd 227, is an example of one-way socket (13465). It has 0 as "Peer Address:Port". From the side of systemd process, there is no communication peers. However, the sockets (35438 and 74792) opened with systemd-journal and bluetoothd have the one-way socket (13465) as their communication peers. We expect lsfd prints these connections if user specifies -o+ENDPOINTS. This change and subsequent changes remove limitations in this area. In the early stage of lsfd process, lsfd collects information about UNIX sockets on the system via unix-diag netlink. lsfd stores the information to the IPC table. lsfd looks up the IPC table when printing ENDPOINTS column. With the original code, lsfd could not fill the ENDPOINTS columns for sockets connecting to an one-way socket because lsfd did not store one-way sockets to the IPC table. # ./original-lsfd -Q 'INODE == 35438 || INODE == 74792' -oCOMMAND,PID,TYPE,INODE,NAME,ENDPOINTS COMMAND PID TYPE INODE NAME ENDPOINTS systemd-journal 1280 UNIX 35438 state=connected type=dgram bluetoothd 13874 UNIX 74792 state=connected type=dgram With this change, lsfd can fill the ENDPOINTS columns for sockets connecting to an one-way socket. The new code puts dummy entries for the one-way sockets to the IPC table. The dummy entries help lsfd to find the connections. # ./new-lsfd -Q 'INODE == 35438 || INODE == 74792' -oCOMMAND,PID,TYPE,INODE,NAME,ENDPOINTS COMMAND PID TYPE INODE NAME ENDPOINTS systemd-journal 1280 UNIX 35438 state=connected type=dgram 1,systemd,227rw bluetoothd 13874 UNIX 74792 state=connected type=dgram 1,systemd,227rw Signed-off-by: Masatake YAMATO --- diff --git a/lsfd-cmd/sock-xinfo.c b/lsfd-cmd/sock-xinfo.c index f6811213a..4d9dfb817 100644 --- a/lsfd-cmd/sock-xinfo.c +++ b/lsfd-cmd/sock-xinfo.c @@ -780,6 +780,8 @@ static bool handle_diag_unix(ino_t netns __attribute__((__unused__)), ino_t inode; struct sock_xinfo *xinfo; struct unix_xinfo *unix_xinfo; + bool peer_added = false; + bool maybe_oneway = false; if (diag->udiag_family != AF_UNIX) return false; @@ -819,6 +821,7 @@ static bool handle_diag_unix(ino_t netns __attribute__((__unused__)), switch (attr->rta_type) { case UNIX_DIAG_NAME: unix_refill_name(xinfo, RTA_DATA(attr), len); + maybe_oneway = true; break; case UNIX_DIAG_SHUTDOWN: @@ -837,9 +840,18 @@ static bool handle_diag_unix(ino_t netns __attribute__((__unused__)), unix_xinfo->unix_ipc->inode = inode; unix_xinfo->unix_ipc->ipeer = (ino_t)(*(uint32_t *)RTA_DATA(attr)); add_ipc(&unix_xinfo->unix_ipc->ipc, inode % UINT_MAX); + peer_added = true; break; } } + + if (!peer_added && maybe_oneway) { + assert(unix_xinfo->unix_ipc == NULL); + unix_xinfo->unix_ipc = (struct unix_ipc *)new_ipc(&unix_ipc_class); + unix_xinfo->unix_ipc->inode = inode; + unix_xinfo->unix_ipc->ipeer = 0; + add_ipc(&unix_xinfo->unix_ipc->ipc, inode % UINT_MAX); + }; return true; } diff --git a/tests/expected/lsfd/mkfds-unix-dgram-ENDPOINTS-column b/tests/expected/lsfd/mkfds-unix-dgram-ENDPOINTS-column new file mode 100644 index 000000000..71ba0525f --- /dev/null +++ b/tests/expected/lsfd/mkfds-unix-dgram-ENDPOINTS-column @@ -0,0 +1,2 @@ +endpoint_c: 0 +endpoint_c == PID,test_mkfs,3rw: 0 diff --git a/tests/ts/lsfd/mkfds-unix-dgram b/tests/ts/lsfd/mkfds-unix-dgram index c3b0711e4..c19e8ca29 100755 --- a/tests/ts/lsfd/mkfds-unix-dgram +++ b/tests/ts/lsfd/mkfds-unix-dgram @@ -73,4 +73,27 @@ ts_init_subtest "abstract" } > "$TS_OUTPUT" 2>&1 ts_finalize_subtest +ts_init_subtest "ENDPOINTS-column" +if ts_is_in_docker; then + ts_skip_subtest "unsupported in docker environment" +else + { + coproc MKFDS { "$TS_HELPER_MKFDS" unix-dgram $FDS $FDC \ + path=test_mkfds-unix-dgram \ + abstract=true ; } + + if read -r -u "${MKFDS[0]}" PID; then + endpoint_c=$(${TS_CMD_LSFD} -n -r -Q "PID == ${PID} && FD == $FDC" -o ENDPOINTS) + echo endpoint_c: $? + + test "$endpoint_c" = "${PID},test_mkfds,${FDS}rw" + echo "endpoint_c == PID,test_mkfs,${FDS}rw:" $? + + echo DONE >&"${MKFDS[1]}" + fi + wait "${MKFDS_PID}" + } > "$TS_OUTPUT" 2>&1 + ts_finalize_subtest +fi + ts_finalize