Find named sockets even on mounts

OBS-URL: https://build.opensuse.org/package/show/Base:System/psmisc?expand=0&rev=140
This commit is contained in:
Dr. Werner Fink 2022-11-25 11:52:03 +00:00 committed by Git OBS Bridge
parent 9d6e21a714
commit 14915a367d
3 changed files with 197 additions and 3 deletions

View File

@ -1,3 +1,12 @@
-------------------------------------------------------------------
Fri Nov 25 11:48:39 UTC 2022 - Dr. Werner Fink <werner@suse.de>
- Add patch socket-fix.patch
* Add test to check for named sockets as file as well as on mounts
* Fix code to find named sockets
- The former test requires nc at build aka netcat from openbsd to
create a named socket on the fly
-------------------------------------------------------------------
Wed Feb 23 13:04:06 UTC 2022 - Dr. Werner Fink <werner@suse.de>

View File

@ -26,6 +26,7 @@ BuildRequires: glibc-devel
BuildRequires: libselinux-devel
BuildRequires: linux-glibc-devel >= 4.12
BuildRequires: ncurses-devel
BuildRequires: netcat-openbsd
URL: https://gitlab.com/psmisc/psmisc/
Version: 23.4
Release: 0
@ -40,6 +41,7 @@ Patch2: %{name}-22.21-pstree.patch
# https://gitlab.com/bitstreamout/psmisc/tree/mountinfo
Patch3: 0001-Use-mountinfo-to-be-able-to-use-the-mount-identity.patch
Patch4: 0002-Use-new-statx-2-system-call-to-avoid-hangs-on-NFS.patch
Patch5: socket-fix.patch
%define have_peekfd %ix86 x86_64 ppc ppc64 ppc64le %arm mipsel m68k aarch64
@ -58,6 +60,7 @@ processes that are using specified files or filesystems.
%patch2 -p0 -b .pstree
%patch3 -p0 -b .mntinf
%patch4 -p0 -b .statx
%patch5 -p0 -b .sk
%patch0 -p0 -b .p0
%build
@ -74,9 +77,8 @@ CC=gcc
export CFLAGS CXXFLAGS LDFLAGS CC
%configure --disable-rpath \
--with-gnu-ld \
--enable-selinux \
--enable-mountinfo-list \
--enable-timeout-stat=static
--enable-apparmor \
--enable-selinux
make %{?_smp_mflags} CFLAGS="$CFLAGS" "CC=$CC"
%check

183
socket-fix.patch Normal file
View File

@ -0,0 +1,183 @@
---
src/fuser.c | 93 +++++++++++++++++++++++++++++++---------------
src/fuser.h | 1
testsuite/config/unix.exp | 19 +++++++++
3 files changed, 83 insertions(+), 30 deletions(-)
--- src/fuser.c
+++ src/fuser.c 2022-11-25 11:42:29.019144216 +0000
@@ -1741,8 +1741,9 @@ check_dir(const pid_t pid, const char *d
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) {
if (strncmp(dev_tmp->name->filename, filepath, strlen(dev_tmp->name->filename)) != 0)
continue;
@@ -1750,13 +1751,14 @@ check_dir(const pid_t pid, const char *d
if (strncmp(dev_tmp->name->filename, real_filepath, strlen(dev_tmp->name->filename)) != 0)
continue;
}
- }
- if (fdret != 0)
+ if (fdret != 0)
continue;
- if (fd.mnt_id != dev_tmp->mnt_id)
+ if (fd.mnt_id != dev_tmp->mnt_id)
continue;
+ }
+
if (access == ACCESS_FILE
&& (fd.flags & (O_WRONLY|O_RDWR))) {
add_matched_proc(dev_tmp->name,
@@ -2310,22 +2312,12 @@ get_fdinfo(const pid_t pid, const char *
char line[BUFSIZ];
FILE *fp;
# if defined(HAS_NAME_TO_HANDLE_AT)
- static ino_t mynamespace;
- struct stat st;
-
- if (!mynamespace) {
- if (statn("/proc/self/ns/mnt", STATX_INO, &st) != 0) {
- fprintf(stderr, _("Cannot stat %s: %s\n"),
- "/proc/self/ns/mnt", strerror(errno));
- exit(1);
- }
- mynamespace = st.st_ino;
- }
+ char *realname;
# endif
snprintf(pathname, sizeof(pathname)-1, "/proc/%d/fdinfo/%s", pid, fd);
if ((fp = fopen(pathname, "r")) == NULL)
goto out; /* forbidden namesspace, try our own namespace */
- while (fgets(line, BUFSIZ, fp) && ret < 2) {
+ while (fgets(line, BUFSIZ, fp) && ret < 1) {
char *xp, *vp, *ep;
unsigned long ul;
xp = strtok(&line[0], delimiters);
@@ -2338,24 +2330,18 @@ get_fdinfo(const pid_t pid, const char *
info->flags = (mode_t)ul;
flags++;
ret++;
- }
- if (strcmp(xp, "mnt_id") == 0 && (ul = strtoul(vp, &ep, 0)) != ULONG_MAX && ep && *ep == 0) {
- info->mnt_id = (int)ul;
- mnt_id++;
- ret++;
+ break;
}
}
fclose(fp);
out:
# if defined(HAS_NAME_TO_HANDLE_AT)
- if (mynamespace != ns) {
- char *realname;
- snprintf(pathname, sizeof(pathname)-1, "/proc/%d/fd/%s", pid, fd);
- realname = expandpath(pathname);
- if (realname) { /* Use our namespace for mount ID <sigh> */
- info->mnt_id = get_mountid(realname);
- mnt_id++;
- }
+ snprintf(pathname, sizeof(pathname)-1, "/proc/%d/fd/%s", pid, fd);
+ realname = expandpath(pathname);
+ if (realname) { /* Use our namespace for mount ID <sigh> */
+ info->mnt_id = get_mountid(realname);
+ mnt_id++;
+ ret++;
}
# endif
#endif
@@ -2625,6 +2611,53 @@ char *expandpath(const char *path)
}
lnkbuf[n] = '\0'; /* Don't be fooled by readlink(2) */
+ /*
+ * Expand to real path of named socket if any
+ */
+ if (lnkbuf[0] != '/' && strncmp("socket:[", lnkbuf, 8) == 0)
+ {
+ FILE *fp;
+ char *inode;
+ char line[BUFSIZ];
+ if ((inode = strchr(&lnkbuf[8], ']')))
+ {
+ *inode = '\0';
+ inode = &lnkbuf[8];
+ }
+
+ if (!inode || (fp = fopen(PROC_SOCKETS, "r")) == NULL)
+ {
+ /*fprintf(stderr, "Cannot open %s\n", PROC_SOCKETS); */
+ return (char *)0;
+ }
+ while (fgets(line, BUFSIZ, fp) != NULL)
+ {
+ char *named = NULL;
+ unsigned long snode;
+
+ if (*line == 'N')
+ continue;
+
+ if (sscanf(line, "%*x: %*x %*x %*x %*x %*x %lu %ms",
+ &snode, &named) == 2)
+ {
+ char *ep;
+ unsigned long oul = strtoul(inode, &ep, 0);
+ if (oul == snode) {
+ ep = named;
+ if (*ep == '@')
+ ep++;
+ n = strlen(ep);
+ memcpy(lnkbuf, ep, n);
+ lnkbuf[n] = '\0';
+ }
+ free (named);
+ }
+ }
+ fclose(fp);
+ }
+
+
len = strlen(end);
if ((n + len) > PATH_MAX) {
errno = ENAMETOOLONG;
--- src/fuser.h
+++ src/fuser.h 2022-11-25 11:26:23.523783208 +0000
@@ -124,5 +124,6 @@ typedef struct mntinfo_s {
#define KNFSD_EXPORTS "/proc/fs/nfs/exports"
#define PROC_MOUNTINFO "/proc/self/mountinfo"
+#define PROC_SOCKETS "/proc/self/net/unix"
#define PROC_MOUNTS "/proc/mounts"
#define PROC_SWAPS "/proc/swaps"
--- testsuite/config/unix.exp
+++ testsuite/config/unix.exp 2022-11-25 10:07:30.595008557 +0000
@@ -29,3 +29,22 @@ 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 "nc"
+ set socketproc_pid [ spawn $testproc_realpath -lU $sktpath ]
+}
+
+proc kill_socketproc { } {
+ global socketproc_pid
+ kill_process $socketproc_pid
+}