diff options
author | jorgelo@chromium.org <jorgelo@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-08-10 08:11:47 +0000 |
---|---|---|
committer | jorgelo@chromium.org <jorgelo@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-08-10 08:11:47 +0000 |
commit | 8f0e74e7f0ed406d91635334279e5451b8415210 (patch) | |
tree | c589a61379a2e36249613c0e5e38874880c06750 /sandbox | |
parent | 54f40fa8aa0842440c98c090f3c5427793ca7056 (diff) | |
download | chromium_src-8f0e74e7f0ed406d91635334279e5451b8415210.zip chromium_src-8f0e74e7f0ed406d91635334279e5451b8415210.tar.gz chromium_src-8f0e74e7f0ed406d91635334279e5451b8415210.tar.bz2 |
Add basic ARM support to the seccomp-bpf sandbox.
BUG=141157
TEST=unit tests on daisy.
Review URL: https://chromiumcodereview.appspot.com/10827223
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@151007 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'sandbox')
-rw-r--r-- | sandbox/linux/sandbox_linux.gypi | 6 | ||||
-rw-r--r-- | sandbox/linux/seccomp-bpf/sandbox_bpf.cc | 20 | ||||
-rw-r--r-- | sandbox/linux/seccomp-bpf/sandbox_bpf.h | 71 | ||||
-rw-r--r-- | sandbox/linux/seccomp-bpf/sandbox_bpf_unittest.cc | 20 |
4 files changed, 86 insertions, 31 deletions
diff --git a/sandbox/linux/sandbox_linux.gypi b/sandbox/linux/sandbox_linux.gypi index e124007..fb68c73c 100644 --- a/sandbox/linux/sandbox_linux.gypi +++ b/sandbox/linux/sandbox_linux.gypi @@ -24,7 +24,8 @@ ], }], # Similarly, compile seccomp BPF when we support it - [ 'OS=="linux" and (target_arch=="ia32" or target_arch=="x64")', { + [ 'OS=="linux" and (target_arch=="ia32" or target_arch=="x64" ' + 'or target_arch=="arm")', { 'type': 'static_library', 'dependencies': [ 'seccomp_bpf', @@ -47,7 +48,8 @@ '../..', ], 'conditions': [ - [ 'OS=="linux" and (target_arch=="ia32" or target_arch=="x64")', { + [ 'OS=="linux" and (target_arch=="ia32" or target_arch=="x64" ' + 'or target_arch=="arm")', { 'sources': [ 'seccomp-bpf/sandbox_bpf_unittest.cc', ], diff --git a/sandbox/linux/seccomp-bpf/sandbox_bpf.cc b/sandbox/linux/seccomp-bpf/sandbox_bpf.cc index 9599544..dd6ad94 100644 --- a/sandbox/linux/seccomp-bpf/sandbox_bpf.cc +++ b/sandbox/linux/seccomp-bpf/sandbox_bpf.cc @@ -602,8 +602,8 @@ void Sandbox::sigSys(int nr, siginfo_t *info, void *void_context) { memcpy(&sigsys, &info->_sifields, sizeof(sigsys)); // Some more sanity checks. - if (sigsys.ip != reinterpret_cast<void *>(ctx->uc_mcontext.gregs[REG_IP]) || - sigsys.nr != static_cast<int>(ctx->uc_mcontext.gregs[REG_SYSCALL]) || + if (sigsys.ip != reinterpret_cast<void *>(SECCOMP_IP(ctx)) || + sigsys.nr != static_cast<int>(SECCOMP_SYSCALL(ctx)) || sigsys.arch != SECCOMP_ARCH) { goto sigsys_err; } @@ -616,12 +616,12 @@ void Sandbox::sigSys(int nr, siginfo_t *info, void *void_context) { SECCOMP_ARCH, reinterpret_cast<uint64_t>(sigsys.ip), { - static_cast<uint64_t>(ctx->uc_mcontext.gregs[REG_PARM1]), - static_cast<uint64_t>(ctx->uc_mcontext.gregs[REG_PARM2]), - static_cast<uint64_t>(ctx->uc_mcontext.gregs[REG_PARM3]), - static_cast<uint64_t>(ctx->uc_mcontext.gregs[REG_PARM4]), - static_cast<uint64_t>(ctx->uc_mcontext.gregs[REG_PARM5]), - static_cast<uint64_t>(ctx->uc_mcontext.gregs[REG_PARM6]) + static_cast<uint64_t>(SECCOMP_PARM1(ctx)), + static_cast<uint64_t>(SECCOMP_PARM2(ctx)), + static_cast<uint64_t>(SECCOMP_PARM3(ctx)), + static_cast<uint64_t>(SECCOMP_PARM4(ctx)), + static_cast<uint64_t>(SECCOMP_PARM5(ctx)), + static_cast<uint64_t>(SECCOMP_PARM6(ctx)) } }; @@ -633,8 +633,8 @@ void Sandbox::sigSys(int nr, siginfo_t *info, void *void_context) { // Update the CPU register that stores the return code of the system call // that we just handled, and restore "errno" to the value that it had // before entering the signal handler. - ctx->uc_mcontext.gregs[REG_RESULT] = static_cast<greg_t>(rc); - errno = old_errno; + SECCOMP_RESULT(ctx) = static_cast<greg_t>(rc); + errno = old_errno; return; } diff --git a/sandbox/linux/seccomp-bpf/sandbox_bpf.h b/sandbox/linux/seccomp-bpf/sandbox_bpf.h index 414327d..eb99d99 100644 --- a/sandbox/linux/seccomp-bpf/sandbox_bpf.h +++ b/sandbox/linux/seccomp-bpf/sandbox_bpf.h @@ -83,30 +83,65 @@ #define MIN_SYSCALL 0u #define MAX_SYSCALL 1024u #define SECCOMP_ARCH AUDIT_ARCH_I386 -#define REG_RESULT REG_EAX -#define REG_SYSCALL REG_EAX -#define REG_IP REG_EIP -#define REG_PARM1 REG_EBX -#define REG_PARM2 REG_ECX -#define REG_PARM3 REG_EDX -#define REG_PARM4 REG_ESI -#define REG_PARM5 REG_EDI -#define REG_PARM6 REG_EBP + +#define SECCOMP_REG(_ctx, _reg) ((_ctx)->uc_mcontext.gregs[(_reg)]) +#define SECCOMP_RESULT(_ctx) SECCOMP_REG(_ctx, REG_EAX) +#define SECCOMP_SYSCALL(_ctx) SECCOMP_REG(_ctx, REG_EAX) +#define SECCOMP_IP(_ctx) SECCOMP_REG(_ctx, REG_EIP) +#define SECCOMP_PARM1(_ctx) SECCOMP_REG(_ctx, REG_EBX) +#define SECCOMP_PARM2(_ctx) SECCOMP_REG(_ctx, REG_ECX) +#define SECCOMP_PARM3(_ctx) SECCOMP_REG(_ctx, REG_EDX) +#define SECCOMP_PARM4(_ctx) SECCOMP_REG(_ctx, REG_ESI) +#define SECCOMP_PARM5(_ctx) SECCOMP_REG(_ctx, REG_EDI) +#define SECCOMP_PARM6(_ctx) SECCOMP_REG(_ctx, REG_EBP) + #elif defined(__x86_64__) #define MIN_SYSCALL 0u #define MAX_SYSCALL 1024u #define SECCOMP_ARCH AUDIT_ARCH_X86_64 -#define REG_RESULT REG_RAX -#define REG_SYSCALL REG_RAX -#define REG_IP REG_RIP -#define REG_PARM1 REG_RDI -#define REG_PARM2 REG_RSI -#define REG_PARM3 REG_RDX -#define REG_PARM4 REG_R10 -#define REG_PARM5 REG_R8 -#define REG_PARM6 REG_R9 + +#define SECCOMP_REG(_ctx, _reg) ((_ctx)->uc_mcontext.gregs[(_reg)]) +#define SECCOMP_RESULT(_ctx) SECCOMP_REG(_ctx, REG_RAX) +#define SECCOMP_SYSCALL(_ctx) SECCOMP_REG(_ctx, REG_RAX) +#define SECCOMP_IP(_ctx) SECCOMP_REG(_ctx, REG_RIP) +#define SECCOMP_PARM1(_ctx) SECCOMP_REG(_ctx, REG_RDI) +#define SECCOMP_PARM2(_ctx) SECCOMP_REG(_ctx, REG_RSI) +#define SECCOMP_PARM3(_ctx) SECCOMP_REG(_ctx, REG_RDX) +#define SECCOMP_PARM4(_ctx) SECCOMP_REG(_ctx, REG_R10) +#define SECCOMP_PARM5(_ctx) SECCOMP_REG(_ctx, REG_R8) +#define SECCOMP_PARM6(_ctx) SECCOMP_REG(_ctx, REG_R9) + +#elif defined(__arm__) && (defined(__thumb__) || defined(__ARM_EABI__)) +// ARM EABI includes "ARM private" system calls starting at |__ARM_NR_BASE|, +// and a "ghost syscall private to the kernel", cmpxchg, +// at |__ARM_NR_BASE+0x00fff0|. +// See </arch/arm/include/asm/unistd.h> in the Linux kernel. +#define MIN_SYSCALL ((unsigned int)__NR_SYSCALL_BASE) +#define MAX_SYSCALL ((unsigned int)__ARM_NR_BASE + 0x00ffffu) +// <linux/audit.h> includes <linux/elf-em.h>, which does not define EM_ARM. +// <linux/elf.h> only includes <asm/elf.h> if we're in the kernel. +# if !defined(EM_ARM) +# define EM_ARM 40 +# endif +#define SECCOMP_ARCH AUDIT_ARCH_ARM + +// ARM sigcontext_t is different from i386/x86_64. +// See </arch/arm/include/asm/sigcontext.h> in the Linux kernel. +#define SECCOMP_REG(_ctx, _reg) ((_ctx)->uc_mcontext.arm_##_reg) +// ARM EABI syscall convention. +#define SECCOMP_RESULT(_ctx) SECCOMP_REG(_ctx, r0) +#define SECCOMP_SYSCALL(_ctx) SECCOMP_REG(_ctx, r7) +#define SECCOMP_IP(_ctx) SECCOMP_REG(_ctx, pc) +#define SECCOMP_PARM1(_ctx) SECCOMP_REG(_ctx, r0) +#define SECCOMP_PARM2(_ctx) SECCOMP_REG(_ctx, r1) +#define SECCOMP_PARM3(_ctx) SECCOMP_REG(_ctx, r2) +#define SECCOMP_PARM4(_ctx) SECCOMP_REG(_ctx, r3) +#define SECCOMP_PARM5(_ctx) SECCOMP_REG(_ctx, r4) +#define SECCOMP_PARM6(_ctx) SECCOMP_REG(_ctx, r5) + #else #error Unsupported target platform + #endif struct arch_seccomp_data { diff --git a/sandbox/linux/seccomp-bpf/sandbox_bpf_unittest.cc b/sandbox/linux/seccomp-bpf/sandbox_bpf_unittest.cc index b8ae3b7..54fe7a7 100644 --- a/sandbox/linux/seccomp-bpf/sandbox_bpf_unittest.cc +++ b/sandbox/linux/seccomp-bpf/sandbox_bpf_unittest.cc @@ -13,6 +13,9 @@ using namespace playground2; namespace { const int kExpectedReturnValue = 42; +#if defined(__arm__) +const int kArmPublicSysnoCeiling = __NR_SYSCALL_BASE + 1024; +#endif TEST(SandboxBpf, CallSupports) { // We check that we don't crash, but it's ok if the kernel doesn't @@ -234,6 +237,13 @@ Sandbox::ErrorCode SyntheticPolicy(int sysno) { // FIXME: we should really not have to do that in a trivial policy. return ENOSYS; } + + // TODO(jorgelo): remove this restriction once crbug.com/141694 is fixed. +#if defined(__arm__) + if (sysno > kArmPublicSysnoCeiling) + return ENOSYS; +#endif + if (sysno == __NR_exit_group) { // exit_group() is special, we really need it to work. return Sandbox::SB_ALLOWED; @@ -249,8 +259,16 @@ void SyntheticProcess(void) { static_cast<int>(MAX_SYSCALL)) { ExitGroup(1); } + + // TODO(jorgelo): remove this limit once crbug.com/141694 is fixed. +#if defined(__arm__) + const int sysno_ceiling = kArmPublicSysnoCeiling; +#else + const int sysno_ceiling = static_cast<int>(MAX_SYSCALL); +#endif + for (int syscall_number = static_cast<int>(MIN_SYSCALL); - syscall_number <= static_cast<int>(MAX_SYSCALL); + syscall_number <= sysno_ceiling; ++syscall_number) { if (syscall_number == __NR_exit_group) { // exit_group() is special |