mirror of
https://github.com/google/sandboxed-api.git
synced 2024-03-22 13:11:30 +08:00
Add option to block the ptrace system call instead of denying it.
PiperOrigin-RevId: 451347905 Change-Id: Iaed0f6f116bca3be4e6e7009dddd4dd6267823bb
This commit is contained in:
parent
65487bca39
commit
5513e560eb
|
@ -106,10 +106,16 @@ std::vector<sock_filter> Policy::GetDefaultPolicy() const {
|
|||
SANDBOX2_TRACE,
|
||||
LABEL(&l, past_execveat_l),
|
||||
|
||||
// Forbid ptrace because it's unsafe or too risky.
|
||||
LOAD_SYSCALL_NR,
|
||||
JEQ32(__NR_ptrace, DENY),
|
||||
};
|
||||
|
||||
// Forbid ptrace because it's unsafe or too risky. The user policy can only
|
||||
// block (i.e. return an error instead of killing the process) but not allow
|
||||
// ptrace. This uses LOAD_SYSCALL_NR from above.
|
||||
if (!user_policy_handles_ptrace_) {
|
||||
policy.insert(policy.end(), {JEQ32(__NR_ptrace, DENY)});
|
||||
}
|
||||
|
||||
// If user policy doesn't mention it, then forbid bpf because it's unsafe or
|
||||
// too risky. This uses LOAD_SYSCALL_NR from above.
|
||||
if (!user_policy_handles_bpf_) {
|
||||
|
|
|
@ -107,6 +107,7 @@ class Policy final {
|
|||
// The policy set by the user.
|
||||
std::vector<sock_filter> user_policy_;
|
||||
bool user_policy_handles_bpf_ = false;
|
||||
bool user_policy_handles_ptrace_ = false;
|
||||
|
||||
// Contains a list of hosts the sandboxee is allowed to connect to.
|
||||
absl::optional<AllowedHosts> allowed_hosts_;
|
||||
|
|
|
@ -114,6 +114,21 @@ TEST(PolicyTest, PtraceDisallowed) {
|
|||
EXPECT_THAT(result.reason_code(), Eq(__NR_ptrace));
|
||||
}
|
||||
|
||||
TEST(PolicyTest, PtraceBlocked) {
|
||||
SKIP_SANITIZERS_AND_COVERAGE;
|
||||
const std::string path = GetTestSourcePath("sandbox2/testcases/policy");
|
||||
std::vector<std::string> args = {path, "8"};
|
||||
|
||||
Sandbox2 s2(std::make_unique<Executor>(path, args),
|
||||
CreatePolicyTestPolicyBuilder()
|
||||
.BlockSyscallWithErrno(__NR_ptrace, EPERM)
|
||||
.BuildOrDie());
|
||||
auto result = s2.Run();
|
||||
|
||||
// The policy binary fails with an error if the system call is *not* blocked.
|
||||
ASSERT_THAT(result.final_status(), Eq(Result::OK));
|
||||
}
|
||||
|
||||
// Test that clone(2) with flag CLONE_UNTRACED is disallowed.
|
||||
TEST(PolicyTest, CloneUntracedDisallowed) {
|
||||
SKIP_SANITIZERS_AND_COVERAGE;
|
||||
|
|
|
@ -113,6 +113,9 @@ PolicyBuilder& PolicyBuilder::BlockSyscallWithErrno(uint32_t num, int error) {
|
|||
if (num == __NR_bpf) {
|
||||
user_policy_handles_bpf_ = true;
|
||||
}
|
||||
if (num == __NR_ptrace) {
|
||||
user_policy_handles_ptrace_ = true;
|
||||
}
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
@ -929,6 +932,7 @@ absl::StatusOr<std::unique_ptr<Policy>> PolicyBuilder::TryBuild() {
|
|||
overridable_policy_.begin(),
|
||||
overridable_policy_.end());
|
||||
output->user_policy_handles_bpf_ = user_policy_handles_bpf_;
|
||||
output->user_policy_handles_ptrace_ = user_policy_handles_ptrace_;
|
||||
|
||||
auto pb_description = absl::make_unique<PolicyBuilderDescription>();
|
||||
|
||||
|
|
|
@ -639,6 +639,7 @@ class PolicyBuilder final {
|
|||
std::vector<sock_filter> user_policy_;
|
||||
std::vector<sock_filter> overridable_policy_;
|
||||
bool user_policy_handles_bpf_ = false;
|
||||
bool user_policy_handles_ptrace_ = false;
|
||||
absl::flat_hash_set<uint32_t> handled_syscalls_;
|
||||
|
||||
// Error handling
|
||||
|
|
|
@ -58,13 +58,22 @@ void TestAMD64SyscallMismatchFs() {
|
|||
}
|
||||
#endif
|
||||
|
||||
void TestPtrace() {
|
||||
void TestPtraceDenied() {
|
||||
ptrace(PTRACE_SEIZE, getppid(), 0, 0);
|
||||
|
||||
printf("Syscall violation should have been discovered by now\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
void TestPtraceBlocked() {
|
||||
int result = ptrace(PTRACE_SEIZE, getppid(), 0, 0);
|
||||
|
||||
if (result != -1 || errno != EPERM) {
|
||||
printf("System call should have been blocked\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
void TestCloneUntraced() {
|
||||
syscall(__NR_clone, static_cast<uintptr_t>(CLONE_UNTRACED), nullptr, nullptr,
|
||||
nullptr, static_cast<uintptr_t>(0));
|
||||
|
@ -113,7 +122,7 @@ int main(int argc, char* argv[]) {
|
|||
break;
|
||||
#endif
|
||||
case 3:
|
||||
TestPtrace();
|
||||
TestPtraceDenied();
|
||||
break;
|
||||
case 4:
|
||||
TestCloneUntraced();
|
||||
|
@ -127,6 +136,9 @@ int main(int argc, char* argv[]) {
|
|||
case 7:
|
||||
TestBpfError();
|
||||
break;
|
||||
case 8:
|
||||
TestPtraceBlocked();
|
||||
break;
|
||||
default:
|
||||
printf("Unknown test: %d\n", testno);
|
||||
return EXIT_FAILURE;
|
||||
|
|
Loading…
Reference in New Issue
Block a user