Skip to content

Commit

Permalink
Add support for using seccomp_bpf on mips64el.
Browse files Browse the repository at this point in the history
Currently, seccomp_bpf is not supported on mips64el, and the build 
configuration sets use_seccomp_bpf=false on mips64el. This CL adds support
for seccomp-bpf on mips64el, and resolves many compiler errors when
compiling on mips64el.

R= machenbach@chromium.org, brettw@chromium.org
TBR=jorgelo

Bug: 742738
Change-Id: I79c5d1800c0a198a70c1f19a818885b726cbcc4f
Reviewed-on: https://chromium-review.googlesource.com/571385
Reviewed-by: Chris Palmer <palmer@chromium.org>
Reviewed-by: Brett Wilson <brettw@chromium.org>
Commit-Queue: Chris Palmer <palmer@chromium.org>
Cr-Commit-Position: refs/heads/master@{#502712}
  • Loading branch information
ClarkWang-2013 authored and Commit Bot committed Sep 18, 2017
1 parent 2821e85 commit 534d7ce
Show file tree
Hide file tree
Showing 20 changed files with 267 additions and 67 deletions.
1 change: 1 addition & 0 deletions AUTHORS
Original file line number Diff line number Diff line change
Expand Up @@ -879,6 +879,7 @@ Google Inc. <*@google.com>
Hewlett-Packard Development Company, L.P. <*@hp.com>
Igalia S.L. <*@igalia.com>
NIKE, Inc. <*@nike.com>
Loongson Technology Corporation Limited. <*@loongson.cn>
NVIDIA Corporation <*@nvidia.com>
Neverware Inc. <*@neverware.com>
Opera Software ASA <*@opera.com>
Expand Down
10 changes: 10 additions & 0 deletions base/macros.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,16 @@

#include <stddef.h> // For size_t.

// Distinguish mips32.
#if defined(__mips__) && (_MIPS_SIM == _ABIO32)
#define __mips32__
#endif

// Distinguish mips64.
#if defined(__mips__) && (_MIPS_SIM == _ABI64)
#define __mips64__
#endif

// Put this in the declarations for a class to be uncopyable.
#define DISALLOW_COPY(TypeName) \
TypeName(const TypeName&) = delete
Expand Down
4 changes: 2 additions & 2 deletions content/common/sandbox_linux/sandbox_seccomp_bpf_linux.cc
Original file line number Diff line number Diff line change
Expand Up @@ -49,9 +49,9 @@ using sandbox::bpf_dsl::ResultExpr;

// Make sure that seccomp-bpf does not get disabled by mistake. Also make sure
// that we think twice about this when adding a new architecture.
#if !defined(ARCH_CPU_ARM64)
#if !defined(ARCH_CPU_ARM64) && !defined(ARCH_CPU_MIPS64EL)
#error "Seccomp-bpf disabled on supported architecture!"
#endif // !defined(ARCH_CPU_ARM64)
#endif // !defined(ARCH_CPU_ARM64) && !defined(ARCH_CPU_MIPS64EL)

#endif // BUILDFLAG(USE_SECCOMP_BPF)

Expand Down
5 changes: 3 additions & 2 deletions sandbox/features.gni
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,14 @@

import("//build/config/nacl/config.gni")

# The seccomp-bpf sandbox is only supported on five architectures
# The seccomp-bpf sandbox is only supported on six architectures
# currently.
# Do not disable seccomp_bpf anywhere without talking to
# security@chromium.org!
use_seccomp_bpf =
(is_linux || is_android) &&
(current_cpu == "x86" || current_cpu == "x64" || current_cpu == "arm" ||
current_cpu == "arm64" || current_cpu == "mipsel")
current_cpu == "arm64" || current_cpu == "mipsel" ||
current_cpu == "mips64el")

use_seccomp_bpf = use_seccomp_bpf || is_nacl_nonsfi
1 change: 1 addition & 0 deletions sandbox/linux/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -431,6 +431,7 @@ source_set("sandbox_services_headers") {
"system_headers/linux_time.h",
"system_headers/linux_ucontext.h",
"system_headers/mips64_linux_syscalls.h",
"system_headers/mips64_linux_ucontext.h",
"system_headers/mips_linux_syscalls.h",
"system_headers/mips_linux_ucontext.h",
"system_headers/x86_32_linux_syscalls.h",
Expand Down
9 changes: 6 additions & 3 deletions sandbox/linux/bpf_dsl/linux_syscall_ranges.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,16 +33,19 @@
#define MIN_GHOST_SYSCALL (MIN_PRIVATE_SYSCALL + 0xfff0u)
#define MAX_SYSCALL (MIN_GHOST_SYSCALL + 4u)

#elif defined(__mips__) && (_MIPS_SIM == _ABIO32)
#elif defined(__mips32__)

#include <asm/unistd.h> // for __NR_O32_Linux and __NR_Linux_syscalls
#define MIN_SYSCALL __NR_O32_Linux
#define MAX_PUBLIC_SYSCALL (MIN_SYSCALL + __NR_Linux_syscalls)
#define MAX_SYSCALL MAX_PUBLIC_SYSCALL

#elif defined(__mips__) && (_MIPS_SIM == _ABI64)
#elif defined(__mips64__)

#error "Add support to header file"
#include <asm/unistd.h> // for __NR_64_Linux and __NR_64_Linux_syscalls
#define MIN_SYSCALL __NR_64_Linux
#define MAX_PUBLIC_SYSCALL (MIN_SYSCALL + __NR_64_Linux_syscalls)
#define MAX_SYSCALL MAX_PUBLIC_SYSCALL

#elif defined(__aarch64__)

Expand Down
63 changes: 61 additions & 2 deletions sandbox/linux/bpf_dsl/seccomp_macros.h
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,7 @@ typedef user_regs regs_struct;
#define SECCOMP_PT_PARM5(_regs) (_regs).REG_r4
#define SECCOMP_PT_PARM6(_regs) (_regs).REG_r5

#elif defined(__mips__) && (_MIPS_SIM == _MIPS_SIM_ABI32)
#elif defined(__mips32__)
#define SECCOMP_ARCH AUDIT_ARCH_MIPSEL
#define SYSCALL_EIGHT_ARGS
// MIPS sigcontext_t is different from i386/x86_64 and ARM.
Expand Down Expand Up @@ -224,7 +224,7 @@ typedef user_regs regs_struct;
#define SECCOMP_ARG_LSB_IDX(nr) (offsetof(struct arch_seccomp_data, args) + \
8*(nr) + 0)

// On Mips we don't have structures like user_regs or user_regs_struct in
// On MIPS we don't have structures like user_regs or user_regs_struct in
// sys/user.h that we could use, so we just define regs_struct directly.
struct regs_struct {
unsigned long long regs[32];
Expand All @@ -244,6 +244,65 @@ struct regs_struct {
#define SECCOMP_PT_PARM3(_regs) (_regs).REG_a2
#define SECCOMP_PT_PARM4(_regs) (_regs).REG_a3

#elif defined(__mips64__)
#define SECCOMP_ARCH AUDIT_ARCH_MIPSEL64
#define SYSCALL_EIGHT_ARGS
// MIPS sigcontext_t is different from i386/x86_64 and ARM.
// See </arch/mips/include/uapi/asm/sigcontext.h> in the Linux kernel.
#define SECCOMP_REG(_ctx, _reg) ((_ctx)->uc_mcontext.gregs[_reg])
// Based on MIPS n64 ABI syscall convention.
// On MIPS, when an indirect syscall is being made (syscall(__NR_foo)),
// the real identifier (__NR_foo) is not in v0, but in a0.
#define SECCOMP_RESULT(_ctx) SECCOMP_REG(_ctx, 2)
#define SECCOMP_SYSCALL(_ctx) SECCOMP_REG(_ctx, 2)
#define SECCOMP_IP(_ctx) (_ctx)->uc_mcontext.pc
#define SECCOMP_PARM1(_ctx) SECCOMP_REG(_ctx, 4)
#define SECCOMP_PARM2(_ctx) SECCOMP_REG(_ctx, 5)
#define SECCOMP_PARM3(_ctx) SECCOMP_REG(_ctx, 6)
#define SECCOMP_PARM4(_ctx) SECCOMP_REG(_ctx, 7)
#define SECCOMP_PARM5(_ctx) SECCOMP_REG(_ctx, 8)
#define SECCOMP_PARM6(_ctx) SECCOMP_REG(_ctx, 9)
#define SECCOMP_PARM7(_ctx) SECCOMP_REG(_ctx, 10)
#define SECCOMP_PARM8(_ctx) SECCOMP_REG(_ctx, 11)
#define SECCOMP_NR_IDX (offsetof(struct arch_seccomp_data, nr))
#define SECCOMP_ARCH_IDX (offsetof(struct arch_seccomp_data, arch))
#define SECCOMP_IP_MSB_IDX (offsetof(struct arch_seccomp_data, \
instruction_pointer) + 4)
#define SECCOMP_IP_LSB_IDX (offsetof(struct arch_seccomp_data, \
instruction_pointer) + 0)
#define SECCOMP_ARG_MSB_IDX(nr) (offsetof(struct arch_seccomp_data, args) + \
8*(nr) + 4)
#define SECCOMP_ARG_LSB_IDX(nr) (offsetof(struct arch_seccomp_data, args) + \
8*(nr) + 0)

// On MIPS we don't have structures like user_regs or user_regs_struct in
// sys/user.h that we could use, so we just define regs_struct directly.
struct regs_struct {
unsigned long long regs[32];
};

#define REG_a7 regs[11]
#define REG_a6 regs[10]
#define REG_a5 regs[9]
#define REG_a4 regs[8]
#define REG_a3 regs[7]
#define REG_a2 regs[6]
#define REG_a1 regs[5]
#define REG_a0 regs[4]
#define REG_v1 regs[3]
#define REG_v0 regs[2]

#define SECCOMP_PT_RESULT(_regs) (_regs).REG_v0
#define SECCOMP_PT_SYSCALL(_regs) (_regs).REG_v0
#define SECCOMP_PT_PARM1(_regs) (_regs).REG_a0
#define SECCOMP_PT_PARM2(_regs) (_regs).REG_a1
#define SECCOMP_PT_PARM3(_regs) (_regs).REG_a2
#define SECCOMP_PT_PARM4(_regs) (_regs).REG_a3
#define SECCOMP_PT_PARM5(_regs) (_regs).REG_a4
#define SECCOMP_PT_PARM6(_regs) (_regs).REG_a5
#define SECCOMP_PT_PARM7(_regs) (_regs).REG_a6
#define SECCOMP_PT_PARM8(_regs) (_regs).REG_a7

#elif defined(__aarch64__)
struct regs_struct {
unsigned long long regs[31];
Expand Down
5 changes: 4 additions & 1 deletion sandbox/linux/bpf_dsl/syscall_set.cc
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,12 @@ namespace sandbox {

namespace {

#if defined(__mips__) && (_MIPS_SIM == _MIPS_SIM_ABI32)
#if defined(__mips32__)
// This is true for Mips O32 ABI.
static_assert(MIN_SYSCALL == __NR_Linux, "min syscall number should be 4000");
#elif defined(__mips64__)
// This is true for MIPS N64 ABI.
static_assert(MIN_SYSCALL == __NR_Linux, "min syscall number should be 5000");
#else
// This true for supported architectures (Intel and ARM EABI).
static_assert(MIN_SYSCALL == 0u,
Expand Down
8 changes: 4 additions & 4 deletions sandbox/linux/seccomp-bpf-helpers/baseline_policy.cc
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ bool IsBaselinePolicyWatched(int sysno) {
SyscallSets::IsNuma(sysno) ||
SyscallSets::IsPrctl(sysno) ||
SyscallSets::IsProcessGroupOrSession(sysno) ||
#if defined(__i386__) || defined(__mips__)
#if defined(__i386__) || defined(__mips32__)
SyscallSets::IsSocketCall(sysno) ||
#endif
#if defined(__arm__)
Expand Down Expand Up @@ -147,7 +147,7 @@ ResultExpr EvaluateSyscallImpl(int fs_denied_errno,
if (sysno == __NR_fcntl)
return RestrictFcntlCommands();

#if defined(__i386__) || defined(__arm__) || defined(__mips__)
#if defined(__i386__) || defined(__arm__) || defined(__mips32__)
if (sysno == __NR_fcntl64)
return RestrictFcntlCommands();
#endif
Expand Down Expand Up @@ -191,7 +191,7 @@ ResultExpr EvaluateSyscallImpl(int fs_denied_errno,
return RestrictMmapFlags();
#endif

#if defined(__i386__) || defined(__arm__) || defined(__mips__)
#if defined(__i386__) || defined(__arm__) || defined(__mips32__)
if (sysno == __NR_mmap2)
return RestrictMmapFlags();
#endif
Expand Down Expand Up @@ -241,7 +241,7 @@ ResultExpr EvaluateSyscallImpl(int fs_denied_errno,
return Error(EPERM);
}

#if defined(__i386__) || defined(__mips__)
#if defined(__i386__) || defined(__mips32__)
if (SyscallSets::IsSocketCall(sysno))
return RestrictSocketcallCommand();
#endif
Expand Down
2 changes: 1 addition & 1 deletion sandbox/linux/seccomp-bpf-helpers/sigsys_handlers.cc
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ void PrintSyscallError(uint32_t sysno) {
sysno_base10[i] = '0' + mod;
}

#if defined(__mips__) && (_MIPS_SIM == _MIPS_SIM_ABI32)
#if defined(__mips32__)
static const char kSeccompErrorPrefix[] = __FILE__
":**CRASHING**:" SECCOMP_MESSAGE_COMMON_CONTENT " in syscall 4000 + ";
#else
Expand Down
Loading

0 comments on commit 534d7ce

Please sign in to comment.