summaryrefslogtreecommitdiffstats
path: root/sandbox
diff options
context:
space:
mode:
authorjorgelo@chromium.org <jorgelo@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-08-10 08:11:47 +0000
committerjorgelo@chromium.org <jorgelo@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-08-10 08:11:47 +0000
commit8f0e74e7f0ed406d91635334279e5451b8415210 (patch)
treec589a61379a2e36249613c0e5e38874880c06750 /sandbox
parent54f40fa8aa0842440c98c090f3c5427793ca7056 (diff)
downloadchromium_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.gypi6
-rw-r--r--sandbox/linux/seccomp-bpf/sandbox_bpf.cc20
-rw-r--r--sandbox/linux/seccomp-bpf/sandbox_bpf.h71
-rw-r--r--sandbox/linux/seccomp-bpf/sandbox_bpf_unittest.cc20
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