| Index: sandbox/linux/seccomp-bpf/sandbox_bpf.h
|
| diff --git a/sandbox/linux/seccomp-bpf/sandbox_bpf.h b/sandbox/linux/seccomp-bpf/sandbox_bpf.h
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..866e7641c32bb6a99561f81a5cf8d6bd958c869c
|
| --- /dev/null
|
| +++ b/sandbox/linux/seccomp-bpf/sandbox_bpf.h
|
| @@ -0,0 +1,160 @@
|
| +// Copyright (c) 2012 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.
|
| +
|
| +#ifndef SANDBOX_LINUX_SECCOMP_BPF_SANDBOX_BPF_H__
|
| +#define SANDBOX_LINUX_SECCOMP_BPF_SANDBOX_BPF_H__
|
| +
|
| +#include <stdint.h>
|
| +
|
| +#include "base/compiler_specific.h"
|
| +#include "base/macros.h"
|
| +#include "base/memory/scoped_ptr.h"
|
| +#include "sandbox/linux/seccomp-bpf/codegen.h"
|
| +#include "sandbox/sandbox_export.h"
|
| +
|
| +namespace sandbox {
|
| +struct arch_seccomp_data;
|
| +namespace bpf_dsl {
|
| +class SandboxBPFDSLPolicy;
|
| +}
|
| +
|
| +class SANDBOX_EXPORT SandboxBPF {
|
| + public:
|
| + enum SandboxStatus {
|
| + STATUS_UNKNOWN, // Status prior to calling supportsSeccompSandbox()
|
| + STATUS_UNSUPPORTED, // The kernel does not appear to support sandboxing
|
| + STATUS_UNAVAILABLE, // Currently unavailable but might work again later
|
| + STATUS_AVAILABLE, // Sandboxing is available but not currently active
|
| + STATUS_ENABLED // The sandbox is now active
|
| + };
|
| +
|
| + // Depending on the level of kernel support, seccomp-bpf may require the
|
| + // process to be single-threaded in order to enable it. When calling
|
| + // StartSandbox(), the program should indicate whether or not the sandbox
|
| + // should try and engage with multi-thread support.
|
| + enum SandboxThreadState {
|
| + PROCESS_INVALID,
|
| + PROCESS_SINGLE_THREADED, // The program is currently single-threaded.
|
| + // Note: PROCESS_MULTI_THREADED requires experimental kernel support that
|
| + // has not been contributed to upstream Linux.
|
| + PROCESS_MULTI_THREADED, // The program may be multi-threaded.
|
| + };
|
| +
|
| + // Constructors and destructors.
|
| + // NOTE: Setting a policy and starting the sandbox is a one-way operation.
|
| + // The kernel does not provide any option for unloading a loaded
|
| + // sandbox. Strictly speaking, that means we should disallow calling
|
| + // the destructor, if StartSandbox() has ever been called. In practice,
|
| + // this makes it needlessly complicated to operate on "Sandbox"
|
| + // objects. So, we instead opted to allow object destruction. But it
|
| + // should be noted that during its lifetime, the object probably made
|
| + // irreversible state changes to the runtime environment. These changes
|
| + // stay in effect even after the destructor has been run.
|
| + SandboxBPF();
|
| + ~SandboxBPF();
|
| +
|
| + // Checks whether a particular system call number is valid on the current
|
| + // architecture. E.g. on ARM there's a non-contiguous range of private
|
| + // system calls.
|
| + static bool IsValidSyscallNumber(int sysnum);
|
| +
|
| + // There are a lot of reasons why the Seccomp sandbox might not be available.
|
| + // This could be because the kernel does not support Seccomp mode, or it
|
| + // could be because another sandbox is already active.
|
| + // "proc_fd" should be a file descriptor for "/proc", or -1 if not
|
| + // provided by the caller.
|
| + static SandboxStatus SupportsSeccompSandbox(int proc_fd);
|
| +
|
| + // Determines if the kernel has support for the seccomp() system call to
|
| + // synchronize BPF filters across a thread group.
|
| + static SandboxStatus SupportsSeccompThreadFilterSynchronization();
|
| +
|
| + // The sandbox needs to be able to access files in "/proc/self". If this
|
| + // directory is not accessible when "startSandbox()" gets called, the caller
|
| + // can provide an already opened file descriptor by calling "set_proc_fd()".
|
| + // The sandbox becomes the new owner of this file descriptor and will
|
| + // eventually close it when "StartSandbox()" executes.
|
| + void set_proc_fd(int proc_fd);
|
| +
|
| + // Set the BPF policy as |policy|. Ownership of |policy| is transfered here
|
| + // to the sandbox object.
|
| + void SetSandboxPolicy(bpf_dsl::SandboxBPFDSLPolicy* policy);
|
| +
|
| + // UnsafeTraps require some syscalls to always be allowed.
|
| + // This helper function returns true for these calls.
|
| + static bool IsRequiredForUnsafeTrap(int sysno);
|
| +
|
| + // From within an UnsafeTrap() it is often useful to be able to execute
|
| + // the system call that triggered the trap. The ForwardSyscall() method
|
| + // makes this easy. It is more efficient than calling glibc's syscall()
|
| + // function, as it avoid the extra round-trip to the signal handler. And
|
| + // it automatically does the correct thing to report kernel-style error
|
| + // conditions, rather than setting errno. See the comments for TrapFnc for
|
| + // details. In other words, the return value from ForwardSyscall() is
|
| + // directly suitable as a return value for a trap handler.
|
| + static intptr_t ForwardSyscall(const struct arch_seccomp_data& args);
|
| +
|
| + // This is the main public entry point. It finds all system calls that
|
| + // need rewriting, sets up the resources needed by the sandbox, and
|
| + // enters Seccomp mode.
|
| + // The calling process must specify its current SandboxThreadState, as a way
|
| + // to tell the sandbox which type of kernel support it should engage.
|
| + // It is possible to stack multiple sandboxes by creating separate "Sandbox"
|
| + // objects and calling "StartSandbox()" on each of them. Please note, that
|
| + // this requires special care, though, as newly stacked sandboxes can never
|
| + // relax restrictions imposed by earlier sandboxes. Furthermore, installing
|
| + // a new policy requires making system calls, that might already be
|
| + // disallowed.
|
| + // Finally, stacking does add more kernel overhead than having a single
|
| + // combined policy. So, it should only be used if there are no alternatives.
|
| + bool StartSandbox(SandboxThreadState thread_state) WARN_UNUSED_RESULT;
|
| +
|
| + // Assembles a BPF filter program from the current policy. After calling this
|
| + // function, you must not call any other sandboxing function.
|
| + // Typically, AssembleFilter() is only used by unit tests and by sandbox
|
| + // internals. It should not be used by production code.
|
| + // For performance reasons, we normally only run the assembled BPF program
|
| + // through the verifier, iff the program was built in debug mode.
|
| + // But by setting "force_verification", the caller can request that the
|
| + // verifier is run unconditionally. This is useful for unittests.
|
| + scoped_ptr<CodeGen::Program> AssembleFilter(bool force_verification);
|
| +
|
| + private:
|
| + // Get a file descriptor pointing to "/proc", if currently available.
|
| + int proc_fd() { return proc_fd_; }
|
| +
|
| + // Creates a subprocess and runs "code_in_sandbox" inside of the specified
|
| + // policy. The caller has to make sure that "this" has not yet been
|
| + // initialized with any other policies.
|
| + bool RunFunctionInPolicy(void (*code_in_sandbox)(),
|
| + scoped_ptr<bpf_dsl::SandboxBPFDSLPolicy> policy);
|
| +
|
| + // Performs a couple of sanity checks to verify that the kernel supports the
|
| + // features that we need for successful sandboxing.
|
| + // The caller has to make sure that "this" has not yet been initialized with
|
| + // any other policies.
|
| + bool KernelSupportSeccompBPF();
|
| +
|
| + // Assembles and installs a filter based on the policy that has previously
|
| + // been configured with SetSandboxPolicy().
|
| + void InstallFilter(bool must_sync_threads);
|
| +
|
| + // Verify the correctness of a compiled program by comparing it against the
|
| + // current policy. This function should only ever be called by unit tests and
|
| + // by the sandbox internals. It should not be used by production code.
|
| + void VerifyProgram(const CodeGen::Program& program);
|
| +
|
| + static SandboxStatus status_;
|
| +
|
| + bool quiet_;
|
| + int proc_fd_;
|
| + bool sandbox_has_started_;
|
| + scoped_ptr<bpf_dsl::SandboxBPFDSLPolicy> policy_;
|
| +
|
| + DISALLOW_COPY_AND_ASSIGN(SandboxBPF);
|
| +};
|
| +
|
| +} // namespace sandbox
|
| +
|
| +#endif // SANDBOX_LINUX_SECCOMP_BPF_SANDBOX_BPF_H__
|
|
|