From: Craig Small Date: Fri, 18 Mar 2022 21:51:22 +0000 (+1100) Subject: fuser: Do not path check sockets X-Git-Tag: v23.5rc1~6 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=43df1ce70db019f1e0598d083a9f0a955c93174d;p=psmisc fuser: Do not path check sockets The referenced commit fixed issue #10 where NFS servers have the same ID and fuser could get confused. That fix was to do a path compare between the user requested path and the path of the mount. Block devices were skipped, because /dev/sda2 is not the same as /home string-wise, even if sda2 was mounted as /home The new issue is, sockets fail to match when using a mount point. That is because "socket:[1547]" is not the same as "/home/user/.gnupg/S.gpg-agent" string-wise, even if named socket 1547 uses that path. The fix is to skip the path checks when looking at sockets. I'm not sure if that means we will have confusion with named sockets that have a path on NFS shares or not but I'm not sure there is a fix for those. References: commit 5c979b38253d187a8ecb8e52a0878b8bb668894f psmisc/psmisc#35 --- diff --git a/ChangeLog b/ChangeLog index 5d90a87..9893085 100644 --- a/ChangeLog +++ b/ChangeLog @@ -2,6 +2,7 @@ Changes in NEXT =============== * killall: Check truncated names !28 * killall: Use openat and pidfd_send_signal #37 + * killall: Don't check paths of sockets #35 * pstree: Check for process with show_parents #38 * pstree: Don't disable compaction with show pgids #34 * pstree: Fix storage leak !29 diff --git a/Makefile.am b/Makefile.am index 8067689..3590afa 100644 --- a/Makefile.am +++ b/Makefile.am @@ -110,3 +110,11 @@ dist-hook: get-trans: rsync -Lrtvz translationproject.org::tp/latest/psmisc/ po rsync -Lrtvz translationproject.org::tp/latest/psmisc-man/ man-po + +# Programs required for testing only +check_PROGRAMS = \ + src/socket_test + +src_socket_test_SOURCES = src/socket_test.c + +check: $(check_PROGRAMS) diff --git a/src/.gitignore b/src/.gitignore index 6068ef7..a0653ce 100644 --- a/src/.gitignore +++ b/src/.gitignore @@ -7,3 +7,4 @@ prtstat pslog pstree signames.h +socket_test diff --git a/src/fuser.c b/src/fuser.c index 1e0d286..4d4363c 100644 --- a/src/fuser.c +++ b/src/fuser.c @@ -1681,8 +1681,9 @@ static void check_dir( if (thedev != dev_tmp->device) continue; - /* check the paths match if it is not a block device */ - if (! S_ISBLK(dev_tmp->name->st.st_mode)) + /* check the paths match if it is not a block device or socket */ + if (! S_ISBLK(dev_tmp->name->st.st_mode) + && !S_ISSOCK(st.st_mode)) { if (readlink(filepath, real_filepath, PATH_MAX-1) < 0) { diff --git a/src/socket_test.c b/src/socket_test.c new file mode 100644 index 0000000..ac6ebec --- /dev/null +++ b/src/socket_test.c @@ -0,0 +1,55 @@ +/* + * Creates named and anonymous sockets to test fuser + */ + +#include +#include +#include +#include +#include +#include + +int main(int argc, char *argv[]) +{ + int skt; + struct sockaddr_un name; + + if (argc < 2) + { + fprintf(stderr, "Usage:\n%s \n", argv[0]); + exit(EXIT_FAILURE); + } + + if ( (skt = socket(AF_UNIX, SOCK_SEQPACKET, 0)) < 0) + { + perror("socket"); + exit(EXIT_FAILURE); + } + + memset(&name, 0, sizeof(name)); + + name.sun_family = AF_UNIX; + strncpy(name.sun_path, argv[1], sizeof(name.sun_path) -1); + + if ( bind(skt, (const struct sockaddr *) &name, sizeof name) < 0) + { + perror("bind"); + exit(EXIT_FAILURE); + } + + if ( listen(skt, 5) < 0) + { + perror("listen"); + exit(EXIT_FAILURE); + } + + if ( accept(skt, NULL, NULL) < 0) + { + perror("accept"); + exit(EXIT_FAILURE); + } + +// sleep(100); + exit(EXIT_SUCCESS); +} + diff --git a/testsuite/config/unix.exp b/testsuite/config/unix.exp index 27e6382..cfa1777 100644 --- a/testsuite/config/unix.exp +++ b/testsuite/config/unix.exp @@ -30,3 +30,23 @@ proc expect_nothing { test } { eof { pass "$test" } } } + +proc kill_process pid { + set cmdline "kill $pid" + if { [catch { exec /bin/sh -c $cmdline } msg]} { + warning "Could not kill process: $msg\n" + } +} + +proc make_socketproc { sktpath } { + global topdir socketproc_pid socketproc_spawnid testsocket_path + + set testproc_realpath "${topdir}/src/socket_test" + set socketproc_pid [ spawn $testproc_realpath $sktpath ] +} + +proc kill_socketproc { } { + global socketproc_pid + kill_process $socketproc_pid +} + diff --git a/testsuite/fuser.test/fuser.exp b/testsuite/fuser.test/fuser.exp index 5c6a0c0..aac5947 100644 --- a/testsuite/fuser.test/fuser.exp +++ b/testsuite/fuser.test/fuser.exp @@ -39,4 +39,23 @@ set test "fuser -l" spawn $fuser -l expect_pass "$test" "^(\[A-Z12\]+\\s*)+$" +# Create test process to make named unix socket +# Needs a sleep otherwise the socket won't be +# available before the file exists comes along +set testsocket_path [ exec mktemp -u -p /tmp ] +make_socketproc ${testsocket_path} +sleep 1 + +if {[file exists ${testsocket_path} ]} { + set test "fuser find socket from path" + spawn sh -c "$fuser -v $testsocket_path" + expect_pass "$test" "$socketproc_pid F" + + set test "fuser find socket from mount" + spawn sh -c "$fuser -mv /tmp" + expect_pass "$test" "$socketproc_pid F" +} else { + unsupported "fuser tests using named sockets" +} +kill_socketproc