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

