summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichal Čihař <nijel@debian.org>2012-03-23 11:21:21 +0100
committerClint Adams <clint@debian.org>2012-03-24 10:42:39 -0400
commit1115a95b3c404498a8dd26cc019c782894337fdb (patch)
tree2e5c57dea677d9b6c103433dbcd23e8c95cb92cd
parent1b1dfee67e9ddd9dfe9171ac347e5000f4deab8a (diff)
downloaddebianutils-1115a95b3c404498a8dd26cc019c782894337fdb.tar.gz
Properly handle situation inside vserver
vserver is sort of chroot, just with stricter enforcement, so let's make ischoot detect it.
-rw-r--r--ischroot.c21
1 files changed, 17 insertions, 4 deletions
diff --git a/ischroot.c b/ischroot.c
index 9af6ea2..bed67f9 100644
--- a/ischroot.c
+++ b/ischroot.c
@@ -51,19 +51,32 @@ int isfakechroot()
#if defined (__linux__)
-/* On Linux we can detect chroots by checking if the
- * devicenumber/inode pair of / are the same as that of
+/* On Linux we can detect chroots by checking if the
+ * devicenumber/inode pair of / are the same as that of
* /sbin/init's. This may fail if not running as root or if
* /proc is not mounted, in which case 2 is returned.
+ *
+ * If /proc/1/root exists but can not be stated as root,
+ * we're running in some limited environment (eg. vserver),
+ * which we consider as chroot here.
*/
static int ischroot()
{
struct stat st1, st2;
- if (stat("/", &st1) || stat("/proc/1/root", &st2))
+ if (stat("/", &st1))
return 2;
- else if ((st1.st_dev == st2.st_dev) && (st1.st_ino == st2.st_ino))
+ if (stat("/proc/1/root", &st2)) {
+ /* Does /proc/1/root exist at all? */
+ if (lstat("/proc/1/root" , &st2))
+ return 2;
+ /* Are we root? */
+ if (geteuid() != 0)
+ 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))
return 1;
else
return 0;