#Cleanup PolicyBuilder API using absl::Span

PiperOrigin-RevId: 415979969
Change-Id: I23e00a48ce9ba14c480f8d137c6ae3981a238e13
This commit is contained in:
Christian Blichmann 2021-12-13 01:31:02 -08:00 committed by Copybara-Service
parent 354cbe89f9
commit 01ffc2a1c2
3 changed files with 32 additions and 62 deletions

View File

@ -299,6 +299,7 @@ target_link_libraries(sandbox2_sandbox2
absl::flat_hash_set absl::flat_hash_set
absl::memory absl::memory
absl::optional absl::optional
absl::span
absl::str_format absl::str_format
absl::strings absl::strings
sapi::strerror sapi::strerror

View File

@ -16,6 +16,7 @@
#include <asm/ioctls.h> // For TCGETS #include <asm/ioctls.h> // For TCGETS
#include <fcntl.h> // For the fcntl flags #include <fcntl.h> // For the fcntl flags
#include <linux/filter.h>
#include <linux/futex.h> #include <linux/futex.h>
#include <linux/net.h> // For SYS_CONNECT #include <linux/net.h> // For SYS_CONNECT
#include <linux/random.h> // For GRND_NONBLOCK #include <linux/random.h> // For GRND_NONBLOCK
@ -23,6 +24,7 @@
#include <sys/socket.h> #include <sys/socket.h>
#include <syscall.h> #include <syscall.h>
#include <array>
#include <csignal> #include <csignal>
#include <cstdint> #include <cstdint>
#include <deque> #include <deque>
@ -51,7 +53,7 @@ namespace {
namespace file = ::sapi::file; namespace file = ::sapi::file;
constexpr PolicyBuilder::SyscallInitializer kMmapSyscalls = { constexpr std::array<uint32_t, 2> kMmapSyscalls = {
#ifdef __NR_mmap2 #ifdef __NR_mmap2
__NR_mmap2, __NR_mmap2,
#endif #endif
@ -72,21 +74,14 @@ bool CheckBpfBounds(const sock_filter& filter, size_t max_jmp) {
} // namespace } // namespace
PolicyBuilder& PolicyBuilder::AllowSyscall(unsigned int num) { PolicyBuilder& PolicyBuilder::AllowSyscall(uint32_t num) {
if (handled_syscalls_.insert(num).second) { if (handled_syscalls_.insert(num).second) {
user_policy_.insert(user_policy_.end(), {SYSCALL(num, ALLOW)}); user_policy_.insert(user_policy_.end(), {SYSCALL(num, ALLOW)});
} }
return *this; return *this;
} }
PolicyBuilder& PolicyBuilder::AllowSyscalls(const std::vector<uint32_t>& nums) { PolicyBuilder& PolicyBuilder::AllowSyscalls(absl::Span<const uint32_t> nums) {
for (auto num : nums) {
AllowSyscall(num);
}
return *this;
}
PolicyBuilder& PolicyBuilder::AllowSyscalls(SyscallInitializer nums) {
for (auto num : nums) { for (auto num : nums) {
AllowSyscall(num); AllowSyscall(num);
} }
@ -94,23 +89,14 @@ PolicyBuilder& PolicyBuilder::AllowSyscalls(SyscallInitializer nums) {
} }
PolicyBuilder& PolicyBuilder::BlockSyscallsWithErrno( PolicyBuilder& PolicyBuilder::BlockSyscallsWithErrno(
const std::vector<uint32_t> nums, int error) { absl::Span<const uint32_t> nums, int error) {
for (auto num : nums) { for (auto num : nums) {
AllowSyscall(num); AllowSyscall(num);
} }
return *this; return *this;
} }
PolicyBuilder& PolicyBuilder::BlockSyscallsWithErrno(SyscallInitializer nums, PolicyBuilder& PolicyBuilder::BlockSyscallWithErrno(uint32_t num, int error) {
int error) {
for (auto num : nums) {
AllowSyscall(num);
}
return *this;
}
PolicyBuilder& PolicyBuilder::BlockSyscallWithErrno(unsigned int num,
int error) {
if (handled_syscalls_.insert(num).second) { if (handled_syscalls_.insert(num).second) {
user_policy_.insert(user_policy_.end(), {SYSCALL(num, ERRNO(error))}); user_policy_.insert(user_policy_.end(), {SYSCALL(num, ERRNO(error))});
if (num == __NR_bpf) { if (num == __NR_bpf) {
@ -724,22 +710,17 @@ PolicyBuilder& PolicyBuilder::AllowDynamicStartup() {
}); });
} }
PolicyBuilder& PolicyBuilder::AddPolicyOnSyscall(unsigned int num,
BpfInitializer policy) {
return AddPolicyOnSyscalls({num}, policy);
}
PolicyBuilder& PolicyBuilder::AddPolicyOnSyscall( PolicyBuilder& PolicyBuilder::AddPolicyOnSyscall(
unsigned int num, const std::vector<sock_filter>& policy) { uint32_t num, absl::Span<const sock_filter> policy) {
return AddPolicyOnSyscalls({num}, policy); return AddPolicyOnSyscalls({num}, policy);
} }
PolicyBuilder& PolicyBuilder::AddPolicyOnSyscall(unsigned int num, BpfFunc f) { PolicyBuilder& PolicyBuilder::AddPolicyOnSyscall(uint32_t num, BpfFunc f) {
return AddPolicyOnSyscalls({num}, f); return AddPolicyOnSyscalls({num}, f);
} }
PolicyBuilder& PolicyBuilder::AddPolicyOnSyscalls( PolicyBuilder& PolicyBuilder::AddPolicyOnSyscalls(
SyscallInitializer nums, const std::vector<sock_filter>& policy) { absl::Span<const uint32_t> nums, absl::Span<const sock_filter> policy) {
std::deque<sock_filter> out; std::deque<sock_filter> out;
// Insert and verify the policy. // Insert and verify the policy.
out.insert(out.end(), policy.begin(), policy.end()); out.insert(out.end(), policy.begin(), policy.end());
@ -800,23 +781,13 @@ PolicyBuilder& PolicyBuilder::AddPolicyOnSyscalls(
return *this; return *this;
} }
PolicyBuilder& PolicyBuilder::AddPolicyOnSyscalls(SyscallInitializer nums, PolicyBuilder& PolicyBuilder::AddPolicyOnSyscalls(
BpfInitializer policy) { absl::Span<const uint32_t> nums, BpfFunc f) {
std::vector<sock_filter> policy_vector(policy);
return AddPolicyOnSyscalls(nums, policy_vector);
}
PolicyBuilder& PolicyBuilder::AddPolicyOnSyscalls(SyscallInitializer nums,
BpfFunc f) {
return AddPolicyOnSyscalls(nums, ResolveBpfFunc(f)); return AddPolicyOnSyscalls(nums, ResolveBpfFunc(f));
} }
PolicyBuilder& PolicyBuilder::AddPolicyOnMmap(BpfInitializer policy) {
return AddPolicyOnSyscalls(kMmapSyscalls, policy);
}
PolicyBuilder& PolicyBuilder::AddPolicyOnMmap( PolicyBuilder& PolicyBuilder::AddPolicyOnMmap(
const std::vector<sock_filter>& policy) { absl::Span<const sock_filter> policy) {
return AddPolicyOnSyscalls(kMmapSyscalls, policy); return AddPolicyOnSyscalls(kMmapSyscalls, policy);
} }

View File

@ -28,9 +28,11 @@
#include <glog/logging.h> #include <glog/logging.h>
#include "absl/base/macros.h" #include "absl/base/macros.h"
#include "absl/container/flat_hash_set.h"
#include "absl/memory/memory.h" #include "absl/memory/memory.h"
#include "absl/status/statusor.h" #include "absl/status/statusor.h"
#include "absl/strings/string_view.h" #include "absl/strings/string_view.h"
#include "absl/types/span.h"
#include "sandboxed_api/sandbox2/mounts.h" #include "sandboxed_api/sandbox2/mounts.h"
#include "sandboxed_api/sandbox2/network_proxy/filtering.h" #include "sandboxed_api/sandbox2/network_proxy/filtering.h"
#include "sandboxed_api/sandbox2/policy.h" #include "sandboxed_api/sandbox2/policy.h"
@ -103,24 +105,23 @@ class PolicyBuilder final {
// We set it lower so that there is for sure some room for the default policy. // We set it lower so that there is for sure some room for the default policy.
static constexpr size_t kMaxUserPolicyLength = 30000; static constexpr size_t kMaxUserPolicyLength = 30000;
using BpfInitializer = std::initializer_list<sock_filter>;
using BpfFunc = const std::function<std::vector<sock_filter>(bpf_labels&)>&; using BpfFunc = const std::function<std::vector<sock_filter>(bpf_labels&)>&;
using SyscallInitializer = std::initializer_list<unsigned int>;
using SyscallInitializer = std::initializer_list<unsigned int>
ABSL_DEPRECATED("Use absl::Span<const uint32_t> instead");
// Appends code to allow a specific syscall // Appends code to allow a specific syscall
PolicyBuilder& AllowSyscall(unsigned int num); PolicyBuilder& AllowSyscall(uint32_t num);
// Appends code to allow a number of syscalls // Appends code to allow a number of syscalls
PolicyBuilder& AllowSyscalls(const std::vector<uint32_t>& nums); PolicyBuilder& AllowSyscalls(absl::Span<const uint32_t> nums);
PolicyBuilder& AllowSyscalls(SyscallInitializer nums);
// Appends code to block a syscalls while setting errno to the error given. // Appends code to block a syscalls while setting errno to the error given.
PolicyBuilder& BlockSyscallsWithErrno(const std::vector<uint32_t> nums, PolicyBuilder& BlockSyscallsWithErrno(absl::Span<const uint32_t> nums,
int error); int error);
PolicyBuilder& BlockSyscallsWithErrno(SyscallInitializer nums, int error);
// Appends code to block a specific syscall and setting errno. // Appends code to block a specific syscall and setting errno.
PolicyBuilder& BlockSyscallWithErrno(unsigned int num, int error); PolicyBuilder& BlockSyscallWithErrno(uint32_t num, int error);
// Appends code to allow exiting. // Appends code to allow exiting.
// Allows these syscalls: // Allows these syscalls:
@ -401,9 +402,8 @@ class PolicyBuilder final {
// Appends a policy, which will be run on the specified syscall. // Appends a policy, which will be run on the specified syscall.
// This policy must be written without labels. If you need labels, use the // This policy must be written without labels. If you need labels, use the
// next function. // next function.
PolicyBuilder& AddPolicyOnSyscall(unsigned int num, BpfInitializer policy); PolicyBuilder& AddPolicyOnSyscall(uint32_t num,
PolicyBuilder& AddPolicyOnSyscall(unsigned int num, absl::Span<const sock_filter> policy);
const std::vector<sock_filter>& policy);
// Appends a policy, which will be run on the specified syscall. // Appends a policy, which will be run on the specified syscall.
// This policy may use labels. // This policy may use labels.
@ -426,24 +426,22 @@ class PolicyBuilder final {
// JEQ(NETLINK_ROUTE, ALLOW), // JEQ(NETLINK_ROUTE, ALLOW),
// }; // };
// }); // });
PolicyBuilder& AddPolicyOnSyscall(unsigned int num, BpfFunc f); PolicyBuilder& AddPolicyOnSyscall(uint32_t num, BpfFunc f);
// Appends a policy, which will be run on the specified syscalls. // Appends a policy, which will be run on the specified syscalls.
// This policy must be written without labels. // This policy must be written without labels.
PolicyBuilder& AddPolicyOnSyscalls(SyscallInitializer nums, PolicyBuilder& AddPolicyOnSyscalls(absl::Span<const uint32_t> nums,
BpfInitializer policy); absl::Span<const sock_filter> policy);
PolicyBuilder& AddPolicyOnSyscalls(SyscallInitializer nums,
const std::vector<sock_filter>& policy);
// Appends a policy, which will be run on the specified syscalls. // Appends a policy, which will be run on the specified syscalls.
// This policy may use labels. // This policy may use labels.
PolicyBuilder& AddPolicyOnSyscalls(SyscallInitializer nums, BpfFunc f); PolicyBuilder& AddPolicyOnSyscalls(absl::Span<const uint32_t> nums,
BpfFunc f);
// Equivalent to AddPolicyOnSyscalls(mmap_syscalls, policy), where // Equivalent to AddPolicyOnSyscalls(mmap_syscalls, policy), where
// mmap_syscalls is a subset of {__NR_mmap, __NR_mmap2}, which exists on the // mmap_syscalls is a subset of {__NR_mmap, __NR_mmap2}, which exists on the
// target architecture. // target architecture.
PolicyBuilder& AddPolicyOnMmap(BpfInitializer policy); PolicyBuilder& AddPolicyOnMmap(absl::Span<const sock_filter> policy);
PolicyBuilder& AddPolicyOnMmap(const std::vector<sock_filter>& policy);
// Equivalent to AddPolicyOnSyscalls(mmap_syscalls, f), where mmap_syscalls is // Equivalent to AddPolicyOnSyscalls(mmap_syscalls, f), where mmap_syscalls is
// a subset of {__NR_mmap, __NR_mmap2}, which exists on the target // a subset of {__NR_mmap, __NR_mmap2}, which exists on the target
@ -615,7 +613,7 @@ class PolicyBuilder final {
// Seccomp fields // Seccomp fields
std::vector<sock_filter> user_policy_; std::vector<sock_filter> user_policy_;
bool user_policy_handles_bpf_ = false; bool user_policy_handles_bpf_ = false;
std::set<unsigned int> handled_syscalls_; absl::flat_hash_set<uint32_t> handled_syscalls_;
// Error handling // Error handling
absl::Status last_status_; absl::Status last_status_;