mirror of
https://github.com/google/sandboxed-api.git
synced 2024-03-22 13:11:30 +08:00
Use sandboxed libunwind also with sanitizers
PiperOrigin-RevId: 610710893 Change-Id: Iea2c103e88a848b40c5c5cbf3c9f6b9d7bf166db
This commit is contained in:
parent
2cacad6008
commit
2430bc8ae8
@ -66,6 +66,10 @@ namespace {
|
|||||||
namespace file = ::sapi::file;
|
namespace file = ::sapi::file;
|
||||||
namespace file_util = ::sapi::file_util;
|
namespace file_util = ::sapi::file_util;
|
||||||
|
|
||||||
|
// Use a fake pid so that /proc/{pid}/maps etc. also exist in the new pid
|
||||||
|
// namespace
|
||||||
|
constexpr int kFakePid = 1;
|
||||||
|
|
||||||
// Similar to GetStackTrace() but without using the sandbox to isolate
|
// Similar to GetStackTrace() but without using the sandbox to isolate
|
||||||
// libunwind.
|
// libunwind.
|
||||||
absl::StatusOr<std::vector<std::string>> UnsafeGetStackTrace(pid_t pid) {
|
absl::StatusOr<std::vector<std::string>> UnsafeGetStackTrace(pid_t pid) {
|
||||||
@ -92,9 +96,9 @@ bool IsSameFile(const std::string& path, const std::string& other) {
|
|||||||
class StackTracePeer {
|
class StackTracePeer {
|
||||||
public:
|
public:
|
||||||
static absl::StatusOr<std::unique_ptr<Policy>> GetPolicy(
|
static absl::StatusOr<std::unique_ptr<Policy>> GetPolicy(
|
||||||
pid_t target_pid, const std::string& maps_file,
|
const std::string& maps_file, const std::string& app_path,
|
||||||
const std::string& app_path, const std::string& exe_path,
|
const std::string& exe_path, const Namespace* ns,
|
||||||
const Namespace* ns, bool uses_custom_forkserver);
|
bool uses_custom_forkserver);
|
||||||
|
|
||||||
static absl::StatusOr<std::vector<std::string>> LaunchLibunwindSandbox(
|
static absl::StatusOr<std::vector<std::string>> LaunchLibunwindSandbox(
|
||||||
const Regs* regs, const Namespace* ns, bool uses_custom_forkserver,
|
const Regs* regs, const Namespace* ns, bool uses_custom_forkserver,
|
||||||
@ -102,7 +106,7 @@ class StackTracePeer {
|
|||||||
};
|
};
|
||||||
|
|
||||||
absl::StatusOr<std::unique_ptr<Policy>> StackTracePeer::GetPolicy(
|
absl::StatusOr<std::unique_ptr<Policy>> StackTracePeer::GetPolicy(
|
||||||
pid_t target_pid, const std::string& maps_file, const std::string& app_path,
|
const std::string& maps_file, const std::string& app_path,
|
||||||
const std::string& exe_path, const Namespace* ns,
|
const std::string& exe_path, const Namespace* ns,
|
||||||
bool uses_custom_forkserver) {
|
bool uses_custom_forkserver) {
|
||||||
PolicyBuilder builder;
|
PolicyBuilder builder;
|
||||||
@ -169,14 +173,15 @@ absl::StatusOr<std::unique_ptr<Policy>> StackTracePeer::GetPolicy(
|
|||||||
|
|
||||||
// Add proc maps.
|
// Add proc maps.
|
||||||
.AddFileAt(maps_file,
|
.AddFileAt(maps_file,
|
||||||
file::JoinPath("/proc", absl::StrCat(target_pid), "maps"))
|
file::JoinPath("/proc", absl::StrCat(kFakePid), "maps"))
|
||||||
.AddFileAt(maps_file,
|
.AddFileAt(maps_file,
|
||||||
file::JoinPath("/proc", absl::StrCat(target_pid), "task",
|
file::JoinPath("/proc", absl::StrCat(kFakePid), "task",
|
||||||
absl::StrCat(target_pid), "maps"))
|
absl::StrCat(kFakePid), "maps"))
|
||||||
|
|
||||||
// Add the binary itself.
|
// Add the binary itself.
|
||||||
.AddFileAt(exe_path, app_path)
|
.AddFileAt(exe_path, app_path)
|
||||||
.AllowLlvmCoverage();
|
.AllowLlvmCoverage()
|
||||||
|
.AllowLlvmSanitizers();
|
||||||
|
|
||||||
return builder.TryBuild();
|
return builder.TryBuild();
|
||||||
}
|
}
|
||||||
@ -261,8 +266,8 @@ absl::StatusOr<std::vector<std::string>> StackTracePeer::LaunchLibunwindSandbox(
|
|||||||
// forkserver).
|
// forkserver).
|
||||||
SAPI_ASSIGN_OR_RETURN(
|
SAPI_ASSIGN_OR_RETURN(
|
||||||
std::unique_ptr<Policy> policy,
|
std::unique_ptr<Policy> policy,
|
||||||
StackTracePeer::GetPolicy(pid, unwind_temp_maps_path, app_path, exe_path,
|
StackTracePeer::GetPolicy(unwind_temp_maps_path, app_path, exe_path, ns,
|
||||||
ns, uses_custom_forkserver));
|
uses_custom_forkserver));
|
||||||
|
|
||||||
VLOG(1) << "Running libunwind sandbox";
|
VLOG(1) << "Running libunwind sandbox";
|
||||||
auto sandbox =
|
auto sandbox =
|
||||||
@ -270,7 +275,7 @@ absl::StatusOr<std::vector<std::string>> StackTracePeer::LaunchLibunwindSandbox(
|
|||||||
Comms* comms = sandbox->comms();
|
Comms* comms = sandbox->comms();
|
||||||
|
|
||||||
UnwindSetup msg;
|
UnwindSetup msg;
|
||||||
msg.set_pid(pid);
|
msg.set_pid(kFakePid);
|
||||||
msg.set_regs(reinterpret_cast<const char*>(®s->user_regs_),
|
msg.set_regs(reinterpret_cast<const char*>(®s->user_regs_),
|
||||||
sizeof(regs->user_regs_));
|
sizeof(regs->user_regs_));
|
||||||
msg.set_default_max_frames(kDefaultMaxFrames);
|
msg.set_default_max_frames(kDefaultMaxFrames);
|
||||||
@ -330,13 +335,6 @@ absl::StatusOr<std::vector<std::string>> GetStackTrace(
|
|||||||
return UnsafeGetStackTrace(regs->pid());
|
return UnsafeGetStackTrace(regs->pid());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Show a warning if sandboxed libunwind is requested but we're running in
|
|
||||||
// a sanitizer build (= we can't use sandboxed libunwind).
|
|
||||||
if (sapi::sanitizers::IsAny()) {
|
|
||||||
LOG(WARNING) << "Sanitizer build, using non-sandboxed libunwind";
|
|
||||||
return UnsafeGetStackTrace(regs->pid());
|
|
||||||
}
|
|
||||||
|
|
||||||
return StackTracePeer::LaunchLibunwindSandbox(
|
return StackTracePeer::LaunchLibunwindSandbox(
|
||||||
regs, ns, uses_custom_forkserver, recursion_depth);
|
regs, ns, uses_custom_forkserver, recursion_depth);
|
||||||
}
|
}
|
||||||
|
@ -331,6 +331,13 @@ INSTANTIATE_TEST_SUITE_P(
|
|||||||
.final_status = Result::VIOLATION,
|
.final_status = Result::VIOLATION,
|
||||||
.function_name = "ViolatePolicy",
|
.function_name = "ViolatePolicy",
|
||||||
.full_function_description = "ViolatePolicy(int)",
|
.full_function_description = "ViolatePolicy(int)",
|
||||||
|
},
|
||||||
|
TestCase{
|
||||||
|
.testname = "ViolatePolicyForked",
|
||||||
|
.testno = 5,
|
||||||
|
.final_status = Result::VIOLATION,
|
||||||
|
.function_name = "ViolatePolicy",
|
||||||
|
.full_function_description = "ViolatePolicy(int)",
|
||||||
}),
|
}),
|
||||||
[](const ::testing::TestParamInfo<TestCase>& info) {
|
[](const ::testing::TestParamInfo<TestCase>& info) {
|
||||||
return info.param.testname;
|
return info.param.testname;
|
||||||
|
@ -80,6 +80,19 @@ void RunTest(int testno) {
|
|||||||
case 4:
|
case 4:
|
||||||
SleepForXSeconds(10);
|
SleepForXSeconds(10);
|
||||||
break;
|
break;
|
||||||
|
case 5: {
|
||||||
|
constexpr int kMaxForks = 16;
|
||||||
|
for (int i = 0; i < kMaxForks; ++i) {
|
||||||
|
if (fork() == 0) {
|
||||||
|
if (i == kMaxForks - 1) {
|
||||||
|
ViolatePolicy();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
SleepForXSeconds(10);
|
||||||
|
break;
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
SAPI_RAW_LOG(FATAL, "Unknown test case: %d", testno);
|
SAPI_RAW_LOG(FATAL, "Unknown test case: %d", testno);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user