Package: lsof
Version: 4.86+dfsg-1
Followup-For: Bug #731780

last version of this patch made use of an unitilized variable (NoNS)

-- System Information:
Debian Release: jessie/sid
  APT prefers unstable
  APT policy: (500, 'unstable'), (1, 'experimental')
Architecture: amd64 (x86_64)
Foreign Architectures: i386
armhf

Kernel: Linux 3.13.0-rc2-00123-g70839b6 (SMP w/2 CPU cores; PREEMPT)
Locale: LANG=C.UTF-8, LC_CTYPE=C.UTF-8 (charmap=UTF-8)
Shell: /bin/sh linked to /bin/dash

Versions of packages lsof depends on:
ii  libc6                   2.17-97
ii  libperl4-corelibs-perl  0.003-1
ii  perl                    5.18.1-5

lsof recommends no packages.

lsof suggests no packages.

-- no debconf information
>From 6f33319b5631956ca11a09ea8aee6172786bfd3a Mon Sep 17 00:00:00 2001
From: Shawn Landden <[email protected]>
Date: Mon, 9 Dec 2013 10:42:32 -0800
Subject: [PATCH] linux: mount namespace support

If process we are inspecting is in a differn't mount namespace
than we are currently in switch to that namespace before stat()s.

Through openat() and fstatat() we are using the original /proc.

If mount namespace if differn't than the one lsof was ran in,
print the namespace.
---
 dialects/linux/dproc.c | 48 +++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 47 insertions(+), 1 deletion(-)

diff --git a/dialects/linux/dproc.c b/dialects/linux/dproc.c
index 7b54756..0f941bd 100644
--- a/dialects/linux/dproc.c
+++ b/dialects/linux/dproc.c
@@ -74,7 +74,9 @@ static short Cckreg;			/* conditional status of regular file
 static short Ckscko;			/* socket file only checking status:
 					 *     0 = none
 					 *     1 = check only socket files */
-
+static short NoNS = 0;			/* do not check/switch namespaces if 1*/
+#define NS_READLINK_SIZE 3 + 1 + 12 + 1
+static char lsofmntns[NS_READLINK_SIZE];
 
 /*
  * Local function prototypes
@@ -193,6 +195,8 @@ gather_proc_info()
 	    (void) snpf(pidpath, pidpathl, "%s/", PROCFS);
 	}
 
+	if (getlinksrcat(dirfd(ps), "self/ns/mnt", lsofmntns, sizeof(lsofmntns)) != 3 || strlen(&lsofmntns[4]) != 12)
+	    NoNS = 1;
 /*
  * Get lock information.
  */
@@ -942,6 +946,7 @@ process_id(idp, idpl, cmd, uid, pid, ppid, pgid, tid, ps)
 	FILE *ms;
 	static char *vbuf = (char *)NULL;
 	static size_t vsz = (size_t)0;
+	char nsbuf[NS_READLINK_SIZE];
 
 #if	defined(HASSELINUX)
 	cntxlist_t *cntxp;
@@ -984,6 +989,47 @@ process_id(idp, idpl, cmd, uid, pid, ppid, pgid, tid, ps)
 	}
 	ppath[i - 1] = '/';
 /*
+ * Check if PID is in differn't mnt namespace
+ */
+	if (!Ckscko && !NoNS) {
+	    alloc_lfile(" mns", -1);
+	    efs = 0;
+	    if ((getlinksrcat(dirfd(procp), "ns/mnt", pbuf, sizeof(pbuf)) != 3 || strlen(&pbuf[4]) != 12) ||
+		(getlinksrcat(dirfd(ps), "self/ns/mnt", nsbuf, sizeof(nsbuf)) != 3 || strlen(&nsbuf[4]) != 12))
+		pn = 0;
+	    else {
+		if (memcmp(pbuf, nsbuf, sizeof(nsbuf)) != 0) {
+		    int fd;
+		    fd = openat(dirfd(procp), "ns/mnt", O_RDONLY);
+		    if (fd >= 0) {
+			if (setns(fd, CLONE_NEWNS) < 0) {
+			    if (!Fwarn) {
+				(void) memset((void *)&sb, 0, sizeof(sb));
+				(void) snpf(nmabuf, sizeof(nmabuf), "(setns: %s)",
+						strerror(errno));
+				nmabuf[sizeof(nmabuf) - 1] = '\0';
+				(void) add_nma(nmabuf, strlen(nmabuf));
+			    }
+			}
+			ss = fstat(fd, &sb);
+			close(fd);
+		    }
+		}
+		if (memcmp(pbuf, lsofmntns, sizeof(nsbuf)) != 0)
+		    lnk = pn = 1;
+		else
+		    pn = 0;
+	    }
+	    if (pn) {
+		(void) process_proc_node(&pbuf[4],
+					&sb, ss,
+					(struct stat *)NULL, 0, ps);
+		if (Lf->sf)
+		    link_lfile();
+	    }
+	}
+
+/*
  * Process the ID's current working directory info.
  */
 	if (!Ckscko) {
-- 
1.8.5.1

Reply via email to