Commit af240444 authored by mdempsky's avatar mdempsky Committed by Commit bot

Decouple Trap from ErrorCode

This CL makes a few changes in the direction of removing dependencies
on ErrorCode by pushing them up a layer:

- Trap now simply uses TrapKeys directly to store trap function and
metadata instead of needlessly encoding them as ErrorCode.

- MakeTrap returns a bare trap ID and it's instead the caller's
responsibility to encode in an ErrorCode if needed, which is now
handled by ErrorCode's trap constructor.

- Also, ErrorCodeFromTrapId() is replaced by IsSafeTrapId() to answer
the one question that SandboxBPF was interested in knowing about
existing traps.

- Change a few SandboxBPF trap-constructing functions into static
functions since they don't depend on any SandboxBPF instance member
variables.

BUG=414363

Review URL: https://codereview.chromium.org/572753002

Cr-Commit-Position: refs/heads/master@{#295121}
parent 3f0b69a5
......@@ -27,12 +27,13 @@ ErrorCode::ErrorCode(int err) {
}
}
ErrorCode::ErrorCode(Trap::TrapFnc fnc, const void* aux, bool safe, uint16_t id)
ErrorCode::ErrorCode(Trap::TrapFnc fnc, const void* aux, bool safe)
: error_type_(ET_TRAP),
fnc_(fnc),
aux_(const_cast<void*>(aux)),
safe_(safe),
err_(SECCOMP_RET_TRAP + id) {}
err_(SECCOMP_RET_TRAP + Trap::MakeTrap(fnc, aux, safe)) {
}
ErrorCode::ErrorCode(int argno,
ArgType width,
......
......@@ -155,7 +155,7 @@ class SANDBOX_EXPORT ErrorCode {
// If we are wrapping a callback, we must assign a unique id. This id is
// how the kernel tells us which one of our different SECCOMP_RET_TRAP
// cases has been triggered.
ErrorCode(Trap::TrapFnc fnc, const void* aux, bool safe, uint16_t id);
ErrorCode(Trap::TrapFnc fnc, const void* aux, bool safe);
// Some system calls require inspection of arguments. This constructor
// allows us to specify additional constraints.
......
......@@ -170,9 +170,7 @@ void CheckForUnsafeErrorCodes(Instruction* insn, void* aux) {
if (!*is_unsafe) {
if (BPF_CLASS(insn->code) == BPF_RET && insn->k > SECCOMP_RET_TRAP &&
insn->k - SECCOMP_RET_TRAP <= SECCOMP_RET_DATA) {
const ErrorCode& err =
Trap::ErrorCodeFromTrapId(insn->k & SECCOMP_RET_DATA);
if (err.error_type() != ErrorCode::ET_INVALID && !err.safe()) {
if (!Trap::IsSafeTrapId(insn->k & SECCOMP_RET_DATA)) {
*is_unsafe = true;
}
}
......@@ -1049,11 +1047,11 @@ ErrorCode SandboxBPF::Unexpected64bitArgument() {
}
ErrorCode SandboxBPF::Trap(Trap::TrapFnc fnc, const void* aux) {
return Trap::MakeTrap(fnc, aux, true /* Safe Trap */);
return ErrorCode(fnc, aux, true /* Safe Trap */);
}
ErrorCode SandboxBPF::UnsafeTrap(Trap::TrapFnc fnc, const void* aux) {
return Trap::MakeTrap(fnc, aux, false /* Unsafe Trap */);
return ErrorCode(fnc, aux, false /* Unsafe Trap */);
}
bool SandboxBPF::IsRequiredForUnsafeTrap(int sysno) {
......
......@@ -21,24 +21,11 @@
#include "sandbox/linux/seccomp-bpf/die.h"
#include "sandbox/linux/seccomp-bpf/errorcode.h"
#include "sandbox/linux/seccomp-bpf/linux_seccomp.h"
#include "sandbox/linux/seccomp-bpf/trap.h"
#include "sandbox/sandbox_export.h"
namespace sandbox {
// This must match the kernel's seccomp_data structure.
struct arch_seccomp_data {
int nr;
uint32_t arch;
uint64_t instruction_pointer;
uint64_t args[6];
};
struct arch_sigsys {
void* ip;
int nr;
unsigned int arch;
};
class CodeGen;
class SandboxBPFPolicy;
class SandboxUnittestHelper;
......@@ -116,7 +103,7 @@ class SANDBOX_EXPORT SandboxBPF {
// The "aux" field can carry a pointer to arbitrary data. See EvaluateSyscall
// for a description of how to pass data from SetSandboxPolicy() to a Trap()
// handler.
ErrorCode Trap(Trap::TrapFnc fnc, const void* aux);
static ErrorCode Trap(Trap::TrapFnc fnc, const void* aux);
// Calls a user-space trap handler and disables all sandboxing for system
// calls made from this trap handler.
......@@ -128,7 +115,7 @@ class SANDBOX_EXPORT SandboxBPF {
// very useful to diagnose code that is incompatible with the sandbox.
// If even a single system call returns "UnsafeTrap", the security of
// entire sandbox should be considered compromised.
ErrorCode UnsafeTrap(Trap::TrapFnc fnc, const void* aux);
static ErrorCode UnsafeTrap(Trap::TrapFnc fnc, const void* aux);
// UnsafeTraps require some syscalls to always be allowed.
// This helper function returns true for these calls.
......@@ -170,7 +157,7 @@ class SANDBOX_EXPORT SandboxBPF {
const ErrorCode& failed);
// Kill the program and print an error message.
ErrorCode Kill(const char* msg);
static ErrorCode Kill(const char* msg);
// This is the main public entry point. It finds all system calls that
// need rewriting, sets up the resources needed by the sandbox, and
......@@ -200,7 +187,7 @@ class SANDBOX_EXPORT SandboxBPF {
// Returns the fatal ErrorCode that is used to indicate that somebody
// attempted to pass a 64bit value in a 32bit system call argument.
// This method is primarily needed for testing purposes.
ErrorCode Unexpected64bitArgument();
static ErrorCode Unexpected64bitArgument();
private:
friend class CodeGen;
......
This diff is collapsed.
......@@ -9,14 +9,19 @@
#include <stdint.h>
#include <map>
#include <vector>
#include "base/basictypes.h"
#include "base/macros.h"
#include "sandbox/sandbox_export.h"
namespace sandbox {
class ErrorCode;
// This must match the kernel's seccomp_data structure.
struct arch_seccomp_data {
int nr;
uint32_t arch;
uint64_t instruction_pointer;
uint64_t args[6];
};
// The Trap class allows a BPF filter program to branch out to user space by
// raising a SIGSYS signal.
......@@ -47,7 +52,7 @@ class SANDBOX_EXPORT Trap {
// as needed.
// N.B.: This makes a permanent state change. Traps cannot be unregistered,
// as that would break existing BPF filters that are still active.
static ErrorCode MakeTrap(TrapFnc fnc, const void* aux, bool safe);
static uint16_t MakeTrap(TrapFnc fnc, const void* aux, bool safe);
// Enables support for unsafe traps in the SIGSYS signal handler. This is a
// one-way fuse. It works in conjunction with the BPF compiler emitting code
......@@ -59,11 +64,13 @@ class SANDBOX_EXPORT Trap {
// Returns "true", if unsafe traps were turned on.
static bool EnableUnsafeTrapsInSigSysHandler();
// Returns the ErrorCode associate with a particular trap id.
static ErrorCode ErrorCodeFromTrapId(uint16_t id);
// Returns true if a safe trap handler is associated with a
// particular trap ID.
static bool IsSafeTrapId(uint16_t id);
private:
struct TrapKey {
TrapKey() : fnc(NULL), aux(NULL), safe(false) {}
TrapKey(TrapFnc f, const void* a, bool s) : fnc(f), aux(a), safe(s) {}
TrapFnc fnc;
const void* aux;
......@@ -94,7 +101,7 @@ class SANDBOX_EXPORT Trap {
// dumps.
void SigSys(int nr, siginfo_t* info, void* void_context)
__attribute__((noinline));
ErrorCode MakeTrapImpl(TrapFnc fnc, const void* aux, bool safe);
uint16_t MakeTrapImpl(TrapFnc fnc, const void* aux, bool safe);
bool SandboxDebuggingAllowedByUser() const;
// We have a global singleton that handles all of our SIGSYS traps. This
......@@ -104,7 +111,7 @@ class SANDBOX_EXPORT Trap {
static Trap* global_trap_;
TrapIds trap_ids_; // Maps from TrapKeys to numeric ids
ErrorCode* trap_array_; // Array of ErrorCodes indexed by ids
TrapKey* trap_array_; // Array of TrapKeys indexed by ids
size_t trap_array_size_; // Currently used size of array
size_t trap_array_capacity_; // Currently allocated capacity of array
bool has_unsafe_traps_; // Whether unsafe traps have been enabled
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment