Subject: debianutils: ischroot can no longer detect vservers

From: Andrew Ruthven <[email-masked]>
Date: Tue, 12 Mar 2013 23:12:28 +1300

Package: debianutils
Version: 4.3.4
Severity: important

[resubmitting as something seems to have gone wrong with creating the bug]
[third time's the charm?]

Dear Maintainer,

The ischroot code checks to see if it can access /proc/1/root to determine
if it is a running inside a chroot. Within vservers you can now read
/proc/1/root so it is no longer a sufficient test for vservers.

On newer vserver patches a better check is to look for a VxID line in
/proc/self/status.  If the line is present you're running a vserver
kernel.  If the value is 0, then you're on the physical host, anything
else means you're in a vserver.

Inside a vserver:

puck@build-sid-amd64:/$ grep VxID /proc/self/status
VxID: 12
puck@build-sid-amd64:/$ 

On the physical host:

build-servers:~$ grep VxID /proc/self/status
VxID: 0
puck@build-servers:~$ 

A patch that adds this behaviour is attached, please feel free to rewrite! Also,
method that I've supplied works for non-root users as well, but I haven't added
that support.

I've set this bug report to important as it is stopping initscripts from being
installable on a Wheezy vserver.

This is the case on Linux kernel 3.4 + 2.3.3.9 vserver patch.  The 3.2 kernel
set of patches is not affected by this change of behaviour.

Cheers!

-- System Information:
Debian Release: wheezy/sid
  APT prefers unstable
  APT policy: (500, 'unstable')
Architecture: amd64 (x86_64)

Kernel: Linux 2.6.32-28-vserver (SMP w/1 CPU core)
Locale: LANG=en_NZ.UTF-8, LC_CTYPE=POSIX (charmap=ANSI_X3.4-1968)
Shell: /bin/sh linked to /bin/dash

Versions of packages debianutils depends on:
ii  libc6           2.13-37
ii  sensible-utils  0.0.7

debianutils recommends no packages.

debianutils suggests no packages.

-- no debconf information

--- ischroot.c.orig	2013-03-12 22:00:36.235819225 +1300
+++ ischroot.c	2013-03-12 22:33:08.744874725 +1300
@@ -76,9 +76,31 @@
       return 2;
     /* Root can not read /proc/1/root, assume vserver or similar */
     return 0;
-  } else if ((st1.st_dev == st2.st_dev) && (st1.st_ino == st2.st_ino))
+  } else if ((st1.st_dev == st2.st_dev) && (st1.st_ino == st2.st_ino)) {
+    /* but look more closely for vserver, see if VxID != 0 */
+
+    FILE *status=fopen("/proc/self/status", "r");
+    size_t linesiz=0;
+    char* linebuf=0;
+    char* vxidline=0;
+    ssize_t linelen=0;
+    unsigned int vxid = 0;
+    while (linelen=getline(&linebuf, &linesiz, status)>0) {
+      vxidline = strstr(linebuf, "VxID:");
+      if (vxidline != NULL) {
+        sscanf(linebuf, "%*s %u", &vxid);
+
+        if (vxid == 0)
+          /* Host system */
+          return 1;
+        else
+          return 0;
+      }
+    }
+    free (linebuf);
+    fclose(status);
     return 1;
-  else
+  } else
     return 0;
 }