diff options
author | Roger Leigh <rleigh@debian.org> | 2012-10-14 22:48:58 +0100 |
---|---|---|
committer | Roger Leigh <rleigh@debian.org> | 2012-10-14 22:48:58 +0100 |
commit | 78f473c548d1f4f724223be888b36a1a2cf667e2 (patch) | |
tree | 83025bf07686ef936e10d1a7fa219a74e48f86aa | |
parent | 32939573cb04c875b041454949c0138adccbb362 (diff) | |
download | schroot-78f473c548d1f4f724223be888b36a1a2cf667e2.tar.gz |
schroot-mount: Canonicalise symlinks to avoid host mounts
If a symlink inside the chroot is absolute, and this is used
as part of the path in a mountpoint in the fstab file, then
this currently gets mounted (incorrectly) on the host. Use
realpath(3) to canonicalise the path, and then add the chroot
path back to it if missing, to ensure that symlinks can't be
used to accidentally mount filesystems on the host.
-rw-r--r-- | bin/schroot-mount/schroot-mount-main.cc | 15 | ||||
-rw-r--r-- | bin/schroot-mount/schroot-mount-main.h | 3 |
2 files changed, 16 insertions, 2 deletions
diff --git a/bin/schroot-mount/schroot-mount-main.cc b/bin/schroot-mount/schroot-mount-main.cc index 5d8356d7..2c5e1aa7 100644 --- a/bin/schroot-mount/schroot-mount-main.cc +++ b/bin/schroot-mount/schroot-mount-main.cc @@ -59,7 +59,8 @@ namespace emap(main::CHILD_FORK, N_("Failed to fork child")), emap(main::CHILD_WAIT, N_("Wait for child failed")), // TRANSLATORS: %1% = command name - emap(main::EXEC, N_("Failed to execute “%1%”")) + emap(main::EXEC, N_("Failed to execute “%1%”")), + emap(main::REALPATH, N_("Failed to resolve path “%1%”")) }; } @@ -102,6 +103,18 @@ main::action_mount () d = std::string("/") + d; std::string directory(opts->mountpoint + entry.directory); + // Canonicalise path to remove any symlinks. + char *resolved_path = realpath(directory.c_str(), 0); + if (resolved_path == 0) + throw error(directory, EXEC, strerror(errno)); + directory = resolved_path; + std::free(resolved_path); + // If the link was absolute (i.e. points somewhere on the host, + // outside the chroot, make sure that this is modified to be + // inside. + if (directory.size() < opts->mountpoint.size() || + directory.substr(0,opts->mountpoint.size()) != opts->mountpoint) + directory = opts->mountpoint + directory; if (!boost::filesystem::exists(directory)) { diff --git a/bin/schroot-mount/schroot-mount-main.h b/bin/schroot-mount/schroot-mount-main.h index f8a66183..7fa389ba 100644 --- a/bin/schroot-mount/schroot-mount-main.h +++ b/bin/schroot-mount/schroot-mount-main.h @@ -42,7 +42,8 @@ namespace schroot_mount { CHILD_FORK, ///< Failed to fork child. CHILD_WAIT, ///< Wait for child failed. - EXEC ///< Failed to execute. + EXEC, ///< Failed to execute. + REALPATH ///< Failed to resolve path. }; /// Exception type. |