diff options
Diffstat (limited to 'sandbox/linux/seccomp-bpf-helpers/syscall_parameters_restrictions.cc')
-rw-r--r-- | sandbox/linux/seccomp-bpf-helpers/syscall_parameters_restrictions.cc | 372 |
1 files changed, 0 insertions, 372 deletions
diff --git a/sandbox/linux/seccomp-bpf-helpers/syscall_parameters_restrictions.cc b/sandbox/linux/seccomp-bpf-helpers/syscall_parameters_restrictions.cc deleted file mode 100644 index 061bfb4803..0000000000 --- a/sandbox/linux/seccomp-bpf-helpers/syscall_parameters_restrictions.cc +++ /dev/null @@ -1,372 +0,0 @@ -// Copyright (c) 2013 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "sandbox/linux/seccomp-bpf-helpers/syscall_parameters_restrictions.h" - -#include <errno.h> -#include <fcntl.h> -#include <fcntl.h> -#include <linux/net.h> -#include <sched.h> -#include <signal.h> -#include <stdint.h> -#include <sys/mman.h> -#include <sys/prctl.h> -#include <sys/resource.h> -#include <sys/stat.h> -#include <sys/time.h> -#include <sys/types.h> -#include <time.h> -#include <unistd.h> - -#include "base/logging.h" -#include "base/macros.h" -#include "build/build_config.h" -#include "sandbox/linux/bpf_dsl/bpf_dsl.h" -#include "sandbox/linux/bpf_dsl/seccomp_macros.h" -#include "sandbox/linux/seccomp-bpf-helpers/sigsys_handlers.h" -#include "sandbox/linux/seccomp-bpf/sandbox_bpf.h" -#include "sandbox/linux/system_headers/linux_futex.h" -#include "sandbox/linux/system_headers/linux_syscalls.h" -#include "sandbox/linux/system_headers/linux_time.h" - -// PNaCl toolchain does not provide sys/ioctl.h header. -#if !defined(OS_NACL_NONSFI) -#include <sys/ioctl.h> -#endif - -#if defined(OS_ANDROID) - -#if !defined(F_DUPFD_CLOEXEC) -#define F_DUPFD_CLOEXEC (F_LINUX_SPECIFIC_BASE + 6) -#endif - -// https://android.googlesource.com/platform/bionic/+/lollipop-release/libc/private/bionic_prctl.h -#if !defined(PR_SET_VMA) -#define PR_SET_VMA 0x53564d41 -#endif - -#ifndef PR_SET_PTRACER -#define PR_SET_PTRACER 0x59616d61 -#endif - -#endif // defined(OS_ANDROID) - -#if defined(__arm__) && !defined(MAP_STACK) -#define MAP_STACK 0x20000 // Daisy build environment has old headers. -#endif - -#if defined(__mips__) && !defined(MAP_STACK) -#define MAP_STACK 0x40000 -#endif -namespace { - -inline bool IsArchitectureX86_64() { -#if defined(__x86_64__) - return true; -#else - return false; -#endif -} - -inline bool IsArchitectureI386() { -#if defined(__i386__) - return true; -#else - return false; -#endif -} - -inline bool IsAndroid() { -#if defined(OS_ANDROID) - return true; -#else - return false; -#endif -} - -inline bool IsArchitectureMips() { -#if defined(__mips__) - return true; -#else - return false; -#endif -} - -// Ubuntu's version of glibc has a race condition in sem_post that can cause -// it to call futex(2) with bogus op arguments. To workaround this, we need -// to allow those futex(2) calls to fail with EINVAL, instead of crashing the -// process. See crbug.com/598471. -inline bool IsBuggyGlibcSemPost() { -#if defined(LIBC_GLIBC) && !defined(OS_CHROMEOS) - return true; -#else - return false; -#endif -} - -} // namespace. - -#define CASES SANDBOX_BPF_DSL_CASES - -using sandbox::bpf_dsl::Allow; -using sandbox::bpf_dsl::Arg; -using sandbox::bpf_dsl::BoolExpr; -using sandbox::bpf_dsl::Error; -using sandbox::bpf_dsl::If; -using sandbox::bpf_dsl::ResultExpr; - -namespace sandbox { - -#if !defined(OS_NACL_NONSFI) -// Allow Glibc's and Android pthread creation flags, crash on any other -// thread creation attempts and EPERM attempts to use neither -// CLONE_VM, nor CLONE_THREAD, which includes all fork() implementations. -ResultExpr RestrictCloneToThreadsAndEPERMFork() { - const Arg<unsigned long> flags(0); - - // TODO(mdempsky): Extend DSL to support (flags & ~mask1) == mask2. - const uint64_t kAndroidCloneMask = CLONE_VM | CLONE_FS | CLONE_FILES | - CLONE_SIGHAND | CLONE_THREAD | - CLONE_SYSVSEM; - const uint64_t kObsoleteAndroidCloneMask = kAndroidCloneMask | CLONE_DETACHED; - - const uint64_t kGlibcPthreadFlags = - CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND | CLONE_THREAD | - CLONE_SYSVSEM | CLONE_SETTLS | CLONE_PARENT_SETTID | CLONE_CHILD_CLEARTID; - const BoolExpr glibc_test = flags == kGlibcPthreadFlags; - - const BoolExpr android_test = - AnyOf(flags == kAndroidCloneMask, flags == kObsoleteAndroidCloneMask, - flags == kGlibcPthreadFlags); - - return If(IsAndroid() ? android_test : glibc_test, Allow()) - .ElseIf((flags & (CLONE_VM | CLONE_THREAD)) == 0, Error(EPERM)) - .Else(CrashSIGSYSClone()); -} - -ResultExpr RestrictPrctl() { - // Will need to add seccomp compositing in the future. PR_SET_PTRACER is - // used by breakpad but not needed anymore. - const Arg<int> option(0); - return Switch(option) - .CASES((PR_GET_NAME, PR_SET_NAME, PR_GET_DUMPABLE, PR_SET_DUMPABLE -#if defined(OS_ANDROID) - , PR_SET_VMA, PR_SET_PTRACER - -// Enable PR_SET_TIMERSLACK_PID, an Android custom prctl which is used in: -// https://android.googlesource.com/platform/system/core/+/lollipop-release/libcutils/sched_policy.c. -// Depending on the Android kernel version, this prctl may have different -// values. Since we don't know the correct value for the running kernel, we must -// allow them all. -// -// The effect is: -// On 3.14 kernels, this allows PR_SET_TIMERSLACK_PID and 43 and 127 (invalid -// prctls which will return EINVAL) -// On 3.18 kernels, this allows PR_SET_TIMERSLACK_PID, PR_SET_THP_DISABLE, and -// 127 (invalid). -// On 4.1 kernels and up, this allows PR_SET_TIMERSLACK_PID, PR_SET_THP_DISABLE, -// and PR_MPX_ENABLE_MANAGEMENT. - -// https://android.googlesource.com/kernel/common/+/android-3.14/include/uapi/linux/prctl.h -#define PR_SET_TIMERSLACK_PID_1 41 - -// https://android.googlesource.com/kernel/common/+/android-3.18/include/uapi/linux/prctl.h -#define PR_SET_TIMERSLACK_PID_2 43 - -// https://android.googlesource.com/kernel/common/+/android-4.1/include/uapi/linux/prctl.h and up -#define PR_SET_TIMERSLACK_PID_3 127 - - , PR_SET_TIMERSLACK_PID_1 - , PR_SET_TIMERSLACK_PID_2 - , PR_SET_TIMERSLACK_PID_3 -#endif // defined(OS_ANDROID) - ), - Allow()) - .Default(CrashSIGSYSPrctl()); -} - -ResultExpr RestrictIoctl() { - const Arg<int> request(1); - return Switch(request).CASES((TCGETS, FIONREAD), Allow()).Default( - CrashSIGSYSIoctl()); -} - -ResultExpr RestrictMmapFlags() { - // The flags you see are actually the allowed ones, and the variable is a - // "denied" mask because of the negation operator. - // Significantly, we don't permit MAP_HUGETLB, or the newer flags such as - // MAP_POPULATE. - // TODO(davidung), remove MAP_DENYWRITE with updated Tegra libraries. - const uint64_t kAllowedMask = MAP_SHARED | MAP_PRIVATE | MAP_ANONYMOUS | - MAP_STACK | MAP_NORESERVE | MAP_FIXED | - MAP_DENYWRITE; - const Arg<int> flags(3); - return If((flags & ~kAllowedMask) == 0, Allow()).Else(CrashSIGSYS()); -} - -ResultExpr RestrictMprotectFlags() { - // The flags you see are actually the allowed ones, and the variable is a - // "denied" mask because of the negation operator. - // Significantly, we don't permit weird undocumented flags such as - // PROT_GROWSDOWN. - const uint64_t kAllowedMask = PROT_READ | PROT_WRITE | PROT_EXEC; - const Arg<int> prot(2); - return If((prot & ~kAllowedMask) == 0, Allow()).Else(CrashSIGSYS()); -} - -ResultExpr RestrictFcntlCommands() { - // We also restrict the flags in F_SETFL. We don't want to permit flags with - // a history of trouble such as O_DIRECT. The flags you see are actually the - // allowed ones, and the variable is a "denied" mask because of the negation - // operator. - // Glibc overrides the kernel's O_LARGEFILE value. Account for this. - uint64_t kOLargeFileFlag = O_LARGEFILE; - if (IsArchitectureX86_64() || IsArchitectureI386() || IsArchitectureMips()) - kOLargeFileFlag = 0100000; - - const Arg<int> cmd(1); - const Arg<long> long_arg(2); - - const uint64_t kAllowedMask = O_ACCMODE | O_APPEND | O_NONBLOCK | O_SYNC | - kOLargeFileFlag | O_CLOEXEC | O_NOATIME; - return Switch(cmd) - .CASES((F_GETFL, - F_GETFD, - F_SETFD, - F_SETLK, - F_SETLKW, - F_GETLK, - F_DUPFD, - F_DUPFD_CLOEXEC), - Allow()) - .Case(F_SETFL, - If((long_arg & ~kAllowedMask) == 0, Allow()).Else(CrashSIGSYS())) - .Default(CrashSIGSYS()); -} - -#if defined(__i386__) || defined(__mips__) -ResultExpr RestrictSocketcallCommand() { - // Unfortunately, we are unable to restrict the first parameter to - // socketpair(2). Whilst initially sounding bad, it's noteworthy that very - // few protocols actually support socketpair(2). The scary call that we're - // worried about, socket(2), remains blocked. - const Arg<int> call(0); - return Switch(call) - .CASES((SYS_SOCKETPAIR, - SYS_SHUTDOWN, - SYS_RECV, - SYS_SEND, - SYS_RECVFROM, - SYS_SENDTO, - SYS_RECVMSG, - SYS_SENDMSG), - Allow()) - .Default(Error(EPERM)); -} -#endif - -ResultExpr RestrictKillTarget(pid_t target_pid, int sysno) { - switch (sysno) { - case __NR_kill: - case __NR_tgkill: { - const Arg<pid_t> pid(0); - return If(pid == target_pid, Allow()).Else(CrashSIGSYSKill()); - } - case __NR_tkill: - return CrashSIGSYSKill(); - default: - NOTREACHED(); - return CrashSIGSYS(); - } -} - -ResultExpr RestrictFutex() { - const uint64_t kAllowedFutexFlags = FUTEX_PRIVATE_FLAG | FUTEX_CLOCK_REALTIME; - const Arg<int> op(1); - return Switch(op & ~kAllowedFutexFlags) - .CASES((FUTEX_WAIT, FUTEX_WAKE, FUTEX_REQUEUE, FUTEX_CMP_REQUEUE, - FUTEX_WAKE_OP, FUTEX_WAIT_BITSET, FUTEX_WAKE_BITSET), - Allow()) - .Default(IsBuggyGlibcSemPost() ? Error(EINVAL) : CrashSIGSYSFutex()); -} - -ResultExpr RestrictGetSetpriority(pid_t target_pid) { - const Arg<int> which(0); - const Arg<int> who(1); - return If(which == PRIO_PROCESS, - Switch(who).CASES((0, target_pid), Allow()).Default(Error(EPERM))) - .Else(CrashSIGSYS()); -} - -ResultExpr RestrictSchedTarget(pid_t target_pid, int sysno) { - switch (sysno) { - case __NR_sched_getaffinity: - case __NR_sched_getattr: - case __NR_sched_getparam: - case __NR_sched_getscheduler: - case __NR_sched_rr_get_interval: - case __NR_sched_setaffinity: - case __NR_sched_setattr: - case __NR_sched_setparam: - case __NR_sched_setscheduler: { - const Arg<pid_t> pid(0); - return Switch(pid) - .CASES((0, target_pid), Allow()) - .Default(RewriteSchedSIGSYS()); - } - default: - NOTREACHED(); - return CrashSIGSYS(); - } -} - -ResultExpr RestrictPrlimit64(pid_t target_pid) { - const Arg<pid_t> pid(0); - return Switch(pid).CASES((0, target_pid), Allow()).Default(CrashSIGSYS()); -} - -ResultExpr RestrictGetrusage() { - const Arg<int> who(0); - return If(who == RUSAGE_SELF, Allow()).Else(CrashSIGSYS()); -} -#endif // !defined(OS_NACL_NONSFI) - -ResultExpr RestrictClockID() { - static_assert(4 == sizeof(clockid_t), "clockid_t is not 32bit"); - const Arg<clockid_t> clockid(0); - return Switch(clockid) - .CASES(( -#if defined(OS_ANDROID) - CLOCK_BOOTTIME, -#endif - CLOCK_MONOTONIC, - CLOCK_MONOTONIC_COARSE, - CLOCK_PROCESS_CPUTIME_ID, - CLOCK_REALTIME, - CLOCK_REALTIME_COARSE, - CLOCK_THREAD_CPUTIME_ID), - Allow()) - .Default(CrashSIGSYS()); -} - -#if !defined(GRND_NONBLOCK) -#define GRND_NONBLOCK 1 -#endif - -ResultExpr RestrictGetRandom() { - const Arg<unsigned int> flags(2); - const unsigned int kGoodFlags = GRND_NONBLOCK; - return If((flags & ~kGoodFlags) == 0, Allow()).Else(CrashSIGSYS()); -} - -ResultExpr RestrictPrlimitToGetrlimit(pid_t target_pid) { - const Arg<pid_t> pid(0); - const Arg<uintptr_t> new_limit(2); - // Only allow 'get' operations, and only for the current process. - return If(AllOf(new_limit == 0, AnyOf(pid == 0, pid == target_pid)), Allow()) - .Else(Error(EPERM)); -} - -} // namespace sandbox. |