From 5166f36150a3d2e8618280660baf3254a871406e Mon Sep 17 00:00:00 2001 From: Wiktor Garbacz Date: Thu, 16 Jan 2025 04:07:06 -0800 Subject: [PATCH] Mounts: add better diagnostics on symlinks PiperOrigin-RevId: 716173428 Change-Id: I7a833d0920697d917a48f9f40c0b02397057e367 --- sandboxed_api/sandbox2/mounts.cc | 27 +++++++++++++++++++++++---- 1 file changed, 23 insertions(+), 4 deletions(-) diff --git a/sandboxed_api/sandbox2/mounts.cc b/sandboxed_api/sandbox2/mounts.cc index 16dbfb0c..8a96ac95 100644 --- a/sandboxed_api/sandbox2/mounts.cc +++ b/sandboxed_api/sandbox2/mounts.cc @@ -701,9 +701,17 @@ std::vector GetSortedEntries(const MountTree& tree) { return ordered; } +bool IsSymlink(const std::string& path) { + struct stat sb; + if (stat(path.c_str(), &sb) == -1) { + return false; + } + return S_ISLNK(sb.st_mode); +} + // Traverses the MountTree to create all required files and perform the mounts. -void CreateMounts(const MountTree& tree, const std::string& path, - bool create_backing_files) { +void CreateMounts(const MountTree& tree, const std::string& root_path, + const std::string& path, bool create_backing_files) { // First, create the backing files if needed. if (create_backing_files) { switch (tree.node().node_case()) { @@ -725,6 +733,17 @@ void CreateMounts(const MountTree& tree, const std::string& path, } } + if (IsSymlink(path)) { + std::string abs_path; + if (!file_util::fileops::ReadLinkAbsolute(path, &abs_path)) { + SAPI_RAW_LOG(WARNING, "could not resolve mount target path %s", + path.c_str()); + } else if (!absl::StartsWith(abs_path, absl::StrCat(root_path, "/"))) { + SAPI_RAW_LOG(ERROR, "Mount target not within chroot: %s resolved to %s", + path.c_str(), abs_path.c_str()); + } + } + // Perform the actual mounts based on the node type. switch (tree.node().node_case()) { case MountTree::Node::kDirNode: { @@ -764,14 +783,14 @@ void CreateMounts(const MountTree& tree, const std::string& path, // Traverse the subtrees. for (const auto& [key, value] : GetSortedEntries(tree)) { std::string new_path = sapi::file::JoinPath(path, key); - CreateMounts(*value, new_path, create_backing_files); + CreateMounts(*value, root_path, new_path, create_backing_files); } } } // namespace void Mounts::CreateMounts(const std::string& root_path) const { - sandbox2::CreateMounts(mount_tree_, root_path, true); + sandbox2::CreateMounts(mount_tree_, root_path, root_path, true); } namespace {