]> granicus.if.org Git - psmisc/commitdiff
fuser: Do not path check sockets
authorCraig Small <csmall@dropbear.xyz>
Fri, 18 Mar 2022 21:51:22 +0000 (08:51 +1100)
committerCraig Small <csmall@dropbear.xyz>
Fri, 18 Mar 2022 21:51:22 +0000 (08:51 +1100)
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

ChangeLog
Makefile.am
src/.gitignore
src/fuser.c
src/socket_test.c [new file with mode: 0644]
testsuite/config/unix.exp
testsuite/fuser.test/fuser.exp

index 5d90a8779cec1b31c35de229d9998e1f9e278f7f..9893085f23abf54cda0ebe6b84171328064ebe88 100644 (file)
--- 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
index 8067689d3604d28b12996f25609df071b56a090e..3590afa8dd826a0b248c33a032da1fad4587c781 100644 (file)
@@ -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)
index 6068ef75b1cea5d98782ed7765a987d81f40224f..a0653ce0f49eccb43de28a2ec8680c33c1559994 100644 (file)
@@ -7,3 +7,4 @@ prtstat
 pslog
 pstree
 signames.h
+socket_test
index 1e0d2860b946c42d204c87f97123281bde466654..4d4363c6237eb243cd340524b24f2375e17c4912 100644 (file)
@@ -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 (file)
index 0000000..ac6ebec
--- /dev/null
@@ -0,0 +1,55 @@
+/*
+ * Creates named and anonymous sockets to test fuser
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+
+int main(int argc, char *argv[])
+{
+    int skt;
+    struct sockaddr_un name;
+
+    if (argc < 2)
+    {
+        fprintf(stderr, "Usage:\n%s <socketpath>\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);
+}
+
index 27e63829e187af46130ba71f425461d165e22d20..cfa17779d994706a00151286ffa9a9eb8bd755c2 100644 (file)
@@ -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
+}
+
index 5c6a0c038b0d7515856a2fed9bbbefb2d9e9c90c..aac59476772a8c48156c3f0ced2d4d1733c727d8 100644 (file)
@@ -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