diff --git a/sandboxed_api/sandbox2/policybuilder.cc b/sandboxed_api/sandbox2/policybuilder.cc index 1aa69fd..8d21a4a 100644 --- a/sandboxed_api/sandbox2/policybuilder.cc +++ b/sandboxed_api/sandbox2/policybuilder.cc @@ -127,7 +127,7 @@ PolicyBuilder& PolicyBuilder::AllowScudoMalloc() { PolicyBuilder& PolicyBuilder::AllowTcMalloc() { AllowTime(); - AllowRestartableSequences(); + AllowRestartableSequences(kRequireFastFences); AllowSyscalls( {__NR_munmap, __NR_nanosleep, __NR_brk, __NR_mincore, __NR_membarrier}); AllowLimitedMadvise(); @@ -422,7 +422,8 @@ PolicyBuilder& PolicyBuilder::AllowGetIDs() { }); } -PolicyBuilder& PolicyBuilder::AllowRestartableSequences() { +PolicyBuilder& PolicyBuilder::AllowRestartableSequences( + CpuFenceMode cpu_fence_mode) { AddPolicyOnMmap([](bpf_labels& labels) -> std::vector { return { ARG_32(2), // prot @@ -432,7 +433,10 @@ PolicyBuilder& PolicyBuilder::AllowRestartableSequences() { JEQ32(MAP_PRIVATE | MAP_ANONYMOUS, ALLOW), }; }); - + if (cpu_fence_mode == kAllowSlowFences) { + AddFile("/proc/self/cpuset"); + AllowSyscalls({__NR_sched_getaffinity, __NR_sched_setaffinity}); + } #ifdef __NR_rseq AllowSyscall(__NR_rseq); #endif @@ -804,7 +808,8 @@ PolicyBuilder& PolicyBuilder::AddFileAt(absl::string_view outside, } auto fixed_outside = std::move(fixed_outside_or).value(); - if (absl::StartsWith(fixed_outside, "/proc/self")) { + if (absl::StartsWith(fixed_outside, "/proc/self") && + fixed_outside != "/proc/self/cpuset") { SetError(absl::InvalidArgumentError( absl::StrCat("Cannot add /proc/self mounts, you need to mount the " "whole /proc instead. You tried to mount ", diff --git a/sandboxed_api/sandbox2/policybuilder.h b/sandboxed_api/sandbox2/policybuilder.h index c595614..f6c250c 100644 --- a/sandboxed_api/sandbox2/policybuilder.h +++ b/sandboxed_api/sandbox2/policybuilder.h @@ -89,6 +89,15 @@ namespace sandbox2 { // For a more complicated example, see examples/persistent/persistent_sandbox.cc class PolicyBuilder final { public: + // Possible CPU fence modes for `AllowRestartableSequences()` + enum CpuFenceMode { + // Allow only fast fences for restartable sequences. + kRequireFastFences, + + // Allow fast fences as well as slow fences if fast fences are unavailable. + kAllowSlowFences, + }; + static constexpr absl::string_view kDefaultHostname = "sandbox2"; using BpfInitializer = std::initializer_list; @@ -120,7 +129,16 @@ class PolicyBuilder final { // - membarrier // - futex(WAIT) and futex(WAKE) // - sigmask(SET_MASK) - PolicyBuilder& AllowRestartableSequences(); + // + // If `cpu_fence_mode` is `kAllowSlowFences`, allow for slow cpu fences which + // will enable namespaces and these syscalls and files: + // - sched_getaffinity + // - sched_setaffinity + // - "/proc/self/cpuset" + // + // If `allow_slow_fences` is false, RSEQ functions may not be enabled if + // fast CPU fences are not available. + PolicyBuilder& AllowRestartableSequences(CpuFenceMode cpu_fence_mode); // Appends code to allow the scudo version of malloc, free and // friends. This should be used in conjunction with namespaces. If scudo