mirror of
https://github.com/google/sandboxed-api.git
synced 2024-03-22 13:11:30 +08:00
Rework stacktrace mounttree logic
The previous one was not quite correct in cases where the outside binary path did not match the inside path. This should be fixed with this. PiperOrigin-RevId: 276075886 Change-Id: I1c7c4fa0191960437a2d2360b805c7098b1407c9
This commit is contained in:
parent
254abe04fe
commit
4da8f68aa8
|
@ -254,6 +254,28 @@ sapi::Status Mounts::AddDirectoryAt(absl::string_view outside,
|
||||||
return Insert(inside, node);
|
return Insert(inside, node);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const MountTree::Node* Mounts::GetNode(const std::string& path) const {
|
||||||
|
std::string fixed_path = file::CleanPath(path);
|
||||||
|
absl::string_view cur = fixed_path;
|
||||||
|
std::vector<std::string> parts;
|
||||||
|
|
||||||
|
while (cur != "/") {
|
||||||
|
auto split = file::SplitPath(cur);
|
||||||
|
cur = split.first;
|
||||||
|
parts.push_back(std::string(split.second));
|
||||||
|
}
|
||||||
|
|
||||||
|
const MountTree* curtree = &mount_tree_;
|
||||||
|
for (auto part = parts.rbegin(); part != parts.rend(); ++part) {
|
||||||
|
const auto& p = curtree->entries().find(*part);
|
||||||
|
if (p == curtree->entries().end()) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
curtree = &p->second;
|
||||||
|
}
|
||||||
|
return &curtree->node();
|
||||||
|
}
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
void LogContainer(const std::vector<std::string>& container) {
|
void LogContainer(const std::vector<std::string>& container) {
|
||||||
|
|
|
@ -57,6 +57,8 @@ class Mounts {
|
||||||
void RecursivelyListMounts(std::vector<std::string>* outside_entries,
|
void RecursivelyListMounts(std::vector<std::string>* outside_entries,
|
||||||
std::vector<std::string>* inside_entries);
|
std::vector<std::string>* inside_entries);
|
||||||
|
|
||||||
|
const MountTree::Node* GetNode(const std::string& path) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
friend class MountTreeTest;
|
friend class MountTreeTest;
|
||||||
sapi::Status Insert(absl::string_view path, const MountTree::Node& node);
|
sapi::Status Insert(absl::string_view path, const MountTree::Node& node);
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
#include <sys/capability.h>
|
#include <sys/capability.h>
|
||||||
#include <sys/resource.h>
|
#include <sys/resource.h>
|
||||||
#include <syscall.h>
|
#include <syscall.h>
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
@ -199,20 +200,28 @@ bool StackTracePeer::LaunchLibunwindSandbox(const Regs* regs,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get path to the binary.
|
// Get path to the binary.
|
||||||
// app_path contains the path like it is also in /proc/pid/maps. This is
|
// app_path contains the path like it is also in /proc/pid/maps. It is
|
||||||
// important when the file was removed, it will have a ' (deleted)' suffix.
|
// relative to the sandboxee's mount namespace. If it is not existing
|
||||||
|
// (anymore) it will have a ' (deleted)' suffix.
|
||||||
std::string app_path;
|
std::string app_path;
|
||||||
// The exe_path will have a mountable path of the application, even if it was
|
|
||||||
// removed.
|
|
||||||
std::string exe_path;
|
|
||||||
std::string proc_pid_exe = file::JoinPath("/proc", absl::StrCat(pid), "exe");
|
std::string proc_pid_exe = file::JoinPath("/proc", absl::StrCat(pid), "exe");
|
||||||
if (!file_util::fileops::ReadLinkAbsolute(proc_pid_exe, &app_path)) {
|
if (!file_util::fileops::ReadLinkAbsolute(proc_pid_exe, &app_path)) {
|
||||||
LOG(WARNING) << "Could not obtain absolute path to the binary";
|
LOG(WARNING) << "Could not obtain absolute path to the binary";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check whether the file still exists or not (SAPI).
|
// The exe_path will have a mountable path of the application, even if it was
|
||||||
if (access(app_path.c_str(), F_OK) == -1) {
|
// removed.
|
||||||
|
std::string exe_path;
|
||||||
|
|
||||||
|
// Resolve app_path backing file.
|
||||||
|
const auto* app_node = mounts.GetNode(app_path);
|
||||||
|
if (app_node) {
|
||||||
|
exe_path = app_node->file_node().outside();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (exe_path.empty()) {
|
||||||
|
// File was probably removed.
|
||||||
LOG(WARNING) << "File was removed, using /proc/pid/exe.";
|
LOG(WARNING) << "File was removed, using /proc/pid/exe.";
|
||||||
app_path = std::string(absl::StripSuffix(app_path, " (deleted)"));
|
app_path = std::string(absl::StripSuffix(app_path, " (deleted)"));
|
||||||
// Create a copy of /proc/pid/exe, mount that one.
|
// Create a copy of /proc/pid/exe, mount that one.
|
||||||
|
@ -221,8 +230,6 @@ bool StackTracePeer::LaunchLibunwindSandbox(const Regs* regs,
|
||||||
LOG(WARNING) << "Could not copy /proc/pid/exe";
|
LOG(WARNING) << "Could not copy /proc/pid/exe";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
exe_path = app_path;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
VLOG(1) << "Resolved binary: " << app_path << " / " << exe_path;
|
VLOG(1) << "Resolved binary: " << app_path << " / " << exe_path;
|
||||||
|
|
Loading…
Reference in New Issue
Block a user