summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPádraig Brady <P@draigBrady.com>2014-05-18 17:20:06 +0100
committerPádraig Brady <P@draigBrady.com>2014-05-21 11:18:27 +0100
commit0c4729516baa2fbefb0af66c38f434b1f7519078 (patch)
tree53401704e3202224cac326298cff134180d65f1e
parentaa1a72706bb9581fc08c63efc3bc03b908407124 (diff)
downloadcoreutils-0c4729516baa2fbefb0af66c38f434b1f7519078.tar.xz
chroot: make changing root check more robust
* src/chroot.c (is_root): A new helper function to determine if the passed argument is the root directory based on inode comparison. (main): Use the new helper rather than comparing strings. * tests/misc/chroot-fail.sh: Add cases for alternative root paths.
-rw-r--r--src/chroot.c19
-rwxr-xr-xtests/misc/chroot-fail.sh6
2 files changed, 22 insertions, 3 deletions
diff --git a/src/chroot.c b/src/chroot.c
index 0ded25dec..a623f883a 100644
--- a/src/chroot.c
+++ b/src/chroot.c
@@ -28,6 +28,7 @@
#include "ignore-value.h"
#include "mgetgroups.h"
#include "quote.h"
+#include "root-dev-ino.h"
#include "userspec.h"
#include "xstrtol.h"
@@ -158,6 +159,22 @@ parse_additional_groups (char const *groups, GETGROUPS_T **pgids,
return ret;
}
+static bool
+is_root (const char* dir)
+{
+ struct dev_ino root_ino;
+ if (! get_root_dev_ino (&root_ino))
+ error (EXIT_CANCELED, errno, _("failed to get attributes of %s"),
+ quote ("/"));
+
+ struct stat arg_st;
+ if (stat (dir, &arg_st) == -1)
+ error (EXIT_CANCELED, errno, _("failed to get attributes of %s"),
+ quote (dir));
+
+ return SAME_INODE (root_ino, arg_st);
+}
+
void
usage (int status)
{
@@ -253,7 +270,7 @@ main (int argc, char **argv)
/* Only do chroot specific actions if actually changing root.
The main difference here is that we don't change working dir. */
- if (! STREQ (argv[optind], "/"))
+ if (! is_root (argv[optind]))
{
/* We have to look up users and groups twice.
- First, outside the chroot to load potentially necessary passwd/group
diff --git a/tests/misc/chroot-fail.sh b/tests/misc/chroot-fail.sh
index 56be8e231..b171ec40c 100755
--- a/tests/misc/chroot-fail.sh
+++ b/tests/misc/chroot-fail.sh
@@ -39,7 +39,9 @@ test $? = 127 || fail=1
# Ensure we don't chdir("/") when not changing root
# to allow only changing user ids for a command.
-curdir=$(chroot / env pwd) || fail=1
-test "$curdir" = '/' && fail=1
+for dir in '/' '/.' '/../'; do
+ curdir=$(chroot "$dir" env pwd) || fail=1
+ test "$curdir" = '/' && fail=1
+done
Exit $fail