go-seccomp: Go support for compiling and installing Seccomp-BPF policy files.
BUG=chromium:489765
TEST=Ran 'go test -cpu=10 -test_install -test_endian' on host.
TEST=Cross compiled test with 'x86_64-cros-linux-gnu-go' and ran on a panther device.
TEST=Cross compiled test with 'i686-pc-linux-gnu-go' and ran on a x86-zgb device.
TEST=Cross compiled test with 'armv7a-cros-linux-gnueabi-go' and ran on a daisy device.
Change-Id: I7aa5d7aed0b8f67a2da8c899d35cc2a2a28591b0
Reviewed-on: https://chromium-review.googlesource.com/272832
Reviewed-by: Jorge Lucangeli Obes <jorgelo@chromium.org>
Reviewed-by: Matthew Dempsky <mdempsky@chromium.org>
Commit-Queue: Rahul Chaudhry <rahulchaudhry@chromium.org>
Tested-by: Rahul Chaudhry <rahulchaudhry@chromium.org>
diff --git a/src/chromiumos/seccomp/audit_386.go b/src/chromiumos/seccomp/audit_386.go
new file mode 100644
index 0000000..ac1fc54
--- /dev/null
+++ b/src/chromiumos/seccomp/audit_386.go
@@ -0,0 +1,13 @@
+// Copyright 2015 The Chromium OS Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package seccomp
+
+// #include <linux/audit.h>
+import "C"
+
+const (
+ auditArch = C.AUDIT_ARCH_I386
+ nbits = 32
+)
diff --git a/src/chromiumos/seccomp/audit_amd64.go b/src/chromiumos/seccomp/audit_amd64.go
new file mode 100644
index 0000000..90b5e6c
--- /dev/null
+++ b/src/chromiumos/seccomp/audit_amd64.go
@@ -0,0 +1,13 @@
+// Copyright 2015 The Chromium OS Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package seccomp
+
+// #include <linux/audit.h>
+import "C"
+
+const (
+ auditArch = C.AUDIT_ARCH_X86_64
+ nbits = 64
+)
diff --git a/src/chromiumos/seccomp/audit_arm.go b/src/chromiumos/seccomp/audit_arm.go
new file mode 100644
index 0000000..d720ec4
--- /dev/null
+++ b/src/chromiumos/seccomp/audit_arm.go
@@ -0,0 +1,13 @@
+// Copyright 2015 The Chromium OS Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package seccomp
+
+// #include <linux/audit.h>
+import "C"
+
+const (
+ auditArch = C.AUDIT_ARCH_ARM
+ nbits = 32
+)
diff --git a/src/chromiumos/seccomp/bpf.go b/src/chromiumos/seccomp/bpf.go
new file mode 100644
index 0000000..ebd6f23
--- /dev/null
+++ b/src/chromiumos/seccomp/bpf.go
@@ -0,0 +1,107 @@
+// Copyright 2015 The Chromium OS Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package seccomp
+
+import (
+ "fmt"
+)
+
+// #include <linux/filter.h>
+import "C"
+
+// BPF machine opcodes. These are the only ones we use.
+const (
+ opLOAD = C.BPF_LD + C.BPF_W + C.BPF_ABS
+ opJEQ = C.BPF_JMP + C.BPF_JEQ + C.BPF_K
+ opJSET = C.BPF_JMP + C.BPF_JSET + C.BPF_K
+ opJUMP = C.BPF_JMP + C.BPF_JA
+ opRET = C.BPF_RET + C.BPF_K
+)
+
+// SockFilter encodes one BPF machine instruction.
+// This struct mirrors struct sock_filter from <linux/filter.h>.
+type SockFilter struct {
+ Code uint16 // Actual filter code.
+ JT uint8 // Jump true.
+ JF uint8 // Jump false.
+ K uint32 // Generic multiuse field.
+}
+
+// SockFprog encodes a BPF machine program.
+// This struct mirrors struct sock_fprog from <linux/filter.h>.
+type SockFprog struct {
+ Len uint16 // Number of BPF machine instructions.
+ Filter *SockFilter // Pointer to the first instruction.
+}
+
+// C versions of the structs used for sanity checking.
+type sock_filter C.struct_sock_filter
+type sock_fprog C.struct_sock_fprog
+
+// bpfInsn constructs one BPF machine instruction.
+func bpfInsn(code uint16, k uint32, jt, jf uint8) SockFilter {
+ return SockFilter{code, jt, jf, k}
+}
+
+// bpfStmt constructs one BPF machine statement.
+func bpfStmt(code uint16, k uint32) SockFilter {
+ return bpfInsn(code, k, 0, 0)
+}
+
+// bpfLoad returns the instruction to load the word at the given offset.
+func bpfLoad(offset uintptr) SockFilter {
+ return bpfStmt(opLOAD, uint32(offset))
+}
+
+// bpfJeq returns an instruction encoding "jump-if-equal".
+// Register A is compared with val.
+// Both jt and jf are relative offsets. Offset 0 means fallthrough.
+func bpfJeq(val uint32, jt, jf uint8) SockFilter {
+ return bpfInsn(opJEQ, val, jt, jf)
+}
+
+// bpfJset returns an instruction encoding "jump-if-set".
+// Register A is bitwise anded with val and result compared with zero.
+// Both jt and jf are relative offsets. Offset 0 means fallthrough.
+func bpfJset(val uint32, jt, jf uint8) SockFilter {
+ return bpfInsn(opJSET, val, jt, jf)
+}
+
+// bpfJump returns an instruction encoding an unconditional jump to a relative offset.
+// Offset 0 means fallthrough (NOP).
+func bpfJump(offset int) SockFilter {
+ return bpfStmt(opJUMP, uint32(offset))
+}
+
+// bpfRet returns the instruction to return the value val.
+func bpfRet(val uint32) SockFilter {
+ return bpfStmt(opRET, val)
+}
+
+// String returns a readable representation of a BPF machine instruction.
+func (f SockFilter) String() string {
+ var code string
+ switch f.Code {
+ case opLOAD:
+ code = "Load"
+ case opJEQ:
+ code = "Jeq"
+ case opJSET:
+ code = "Jset"
+ case opJUMP:
+ code = "Jump"
+ case opRET:
+ code = "Return"
+ default:
+ code = fmt.Sprintf("%04x", f.Code)
+ }
+ return fmt.Sprintf("%8s %08x, %02x, %02x\n", code, f.K, f.JT, f.JF)
+}
+
+// ptr returns a pointer to a copy of the argument, useful in cases
+// where the & syntax isn't allowed. e.g. ptr(bpfInsn(...)).
+func ptr(f SockFilter) *SockFilter {
+ return &f
+}
diff --git a/src/chromiumos/seccomp/sanity_test.go b/src/chromiumos/seccomp/sanity_test.go
new file mode 100644
index 0000000..5f5741e
--- /dev/null
+++ b/src/chromiumos/seccomp/sanity_test.go
@@ -0,0 +1,175 @@
+// Copyright 2015 The Chromium OS Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package seccomp
+
+import (
+ "testing"
+ "unsafe"
+)
+
+func TestSockFilter(t *testing.T) {
+ var f SockFilter
+ var cf sock_filter
+ tests := []struct {
+ desc string
+ g, c uintptr
+ }{
+ {
+ "Sizeof(SockFilter)",
+ unsafe.Sizeof(f),
+ unsafe.Sizeof(cf),
+ },
+ {
+ "Sizeof(SockFilter.Code)",
+ unsafe.Sizeof(f.Code),
+ unsafe.Sizeof(cf.code),
+ },
+ {
+ "Offsetof(SockFilter.Code)",
+ unsafe.Offsetof(f.Code),
+ unsafe.Offsetof(cf.code),
+ },
+ {
+ "Sizeof(SockFilter.Jt)",
+ unsafe.Sizeof(f.JT),
+ unsafe.Sizeof(cf.jt),
+ },
+ {
+ "Offsetof(SockFilter.Jt)",
+ unsafe.Offsetof(f.JT),
+ unsafe.Offsetof(cf.jt),
+ },
+ {
+ "Sizeof(SockFilter.Jf)",
+ unsafe.Sizeof(f.JF),
+ unsafe.Sizeof(cf.jf),
+ },
+ {
+ "Offsetof(SockFilter.Jf)",
+ unsafe.Offsetof(f.JF),
+ unsafe.Offsetof(cf.jf),
+ },
+ {
+ "Sizeof(SockFilter.K)",
+ unsafe.Sizeof(f.K),
+ unsafe.Sizeof(cf.k),
+ },
+ {
+ "Offsetof(SockFilter.K)",
+ unsafe.Offsetof(f.K),
+ unsafe.Offsetof(cf.k),
+ },
+ }
+ for _, test := range tests {
+ if test.g != test.c {
+ t.Errorf("%s = %v; want %v", test.desc, test.g, test.c)
+ }
+ }
+}
+
+func TestSockFprog(t *testing.T) {
+ var p SockFprog
+ var cp sock_fprog
+ tests := []struct {
+ desc string
+ g, c uintptr
+ }{
+ {
+ "Sizeof(SockFprog)",
+ unsafe.Sizeof(p),
+ unsafe.Sizeof(cp),
+ },
+ {
+ "Sizeof(SockFprog.Len)",
+ unsafe.Sizeof(p.Len),
+ unsafe.Sizeof(cp.len),
+ },
+ {
+ "Offsetof(SockFprog.Len)",
+ unsafe.Offsetof(p.Len),
+ unsafe.Offsetof(cp.len),
+ },
+ {
+ "Sizeof(SockFprog.Filter)",
+ unsafe.Sizeof(p.Filter),
+ unsafe.Sizeof(cp.filter),
+ },
+ {
+ "Offsetof(SockFprog.Filter)",
+ unsafe.Offsetof(p.Filter),
+ unsafe.Offsetof(cp.filter),
+ },
+ }
+ for _, test := range tests {
+ if test.g != test.c {
+ t.Errorf("%s = %v; want %v", test.desc, test.g, test.c)
+ }
+ }
+}
+
+func TestSeccompData(t *testing.T) {
+ var d SeccompData
+ var cd seccomp_data
+ tests := []struct {
+ desc string
+ g, c uintptr
+ }{
+ {
+ "Sizeof(SeccompData)",
+ unsafe.Sizeof(d),
+ unsafe.Sizeof(cd),
+ },
+ {
+ "Sizeof(SeccompData.NR)",
+ unsafe.Sizeof(d.NR),
+ unsafe.Sizeof(cd.nr),
+ },
+ {
+ "Offsetof(SeccompData.NR)",
+ unsafe.Offsetof(d.NR),
+ unsafe.Offsetof(cd.nr),
+ },
+ {
+ "Sizeof(SeccompData.Arch)",
+ unsafe.Sizeof(d.Arch),
+ unsafe.Sizeof(cd.arch),
+ },
+ {
+ "Offsetof(SeccompData.Arch)",
+ unsafe.Offsetof(d.Arch),
+ unsafe.Offsetof(cd.arch),
+ },
+ {
+ "Sizeof(SeccompData.InstructionPointer)",
+ unsafe.Sizeof(d.InstructionPointer),
+ unsafe.Sizeof(cd.instruction_pointer),
+ },
+ {
+ "Offsetof(SeccompData.InstructionPointer)",
+ unsafe.Offsetof(d.InstructionPointer),
+ unsafe.Offsetof(cd.instruction_pointer),
+ },
+ {
+ "Sizeof(SeccompData.Args)",
+ unsafe.Sizeof(d.Args),
+ unsafe.Sizeof(cd.args),
+ },
+ {
+ "Offsetof(SeccompData.Args)",
+ unsafe.Offsetof(d.Args),
+ unsafe.Offsetof(cd.args),
+ },
+ {
+ "Sizeof(SeccompData.Args[0])",
+ unsafe.Sizeof(d.Args[0]),
+ unsafe.Sizeof(cd.args[0]),
+ },
+ }
+ for _, test := range tests {
+ if test.g != test.c {
+ t.Errorf("%s = %v; want %v", test.desc, test.g, test.c)
+ }
+ }
+}
diff --git a/src/chromiumos/seccomp/seccomp.go b/src/chromiumos/seccomp/seccomp.go
new file mode 100644
index 0000000..922f42d
--- /dev/null
+++ b/src/chromiumos/seccomp/seccomp.go
@@ -0,0 +1,495 @@
+// Copyright 2015 The Chromium OS Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Package seccomp implements support for compiling and installing Seccomp-BPF policy files.
+// - http://www.chromium.org/chromium-os/developer-guide/chromium-os-sandboxing
+//
+// Typical usage:
+// // Check for the required kernel support for seccomp.
+// if err := seccomp.CheckSupport(); err != nil {
+// log.Fatal(err)
+// }
+//
+// // Compile BPF program from a Chromium-OS policy file.
+// bpf, err := seccomp.Compile(path)
+// if err != nil {
+// log.Fatal(err)
+// }
+//
+// // Install Seccomp-BPF filter program with the kernel.
+// if err := seccomp.Install(bpf); err != nil {
+// log.Fatal(err)
+// }
+//
+// For background and more information:
+// - http://www.tcpdump.org/papers/bpf-usenix93.pdf
+// - http://en.wikipedia.org/wiki/Seccomp
+// - http://lwn.net/Articles/475043/
+// - http://outflux.net/teach-seccomp/
+// - http://www.kernel.org/doc/Documentation/prctl/seccomp_filter.txt
+// - http://github.com/torvalds/linux/blob/master/kernel/seccomp.c
+//
+// TODO:
+// - Exit the program if any thread is killed because of seccomp violation.
+// - Provide a debug mode to log system calls used during normal operation.
+package seccomp
+
+import (
+ "bytes"
+ "fmt"
+ "io/ioutil"
+ "regexp"
+ "runtime"
+ "strconv"
+ "strings"
+ "syscall"
+ "unsafe"
+)
+
+// #include <sys/prctl.h>
+// #include <asm/unistd.h>
+// #include <linux/seccomp.h>
+import "C"
+
+// SeccompData is the format the BPF program executes over.
+// This struct mirrors struct seccomp_data from <linux/seccomp.h>.
+type SeccompData struct {
+ NR int32 // The system call number.
+ Arch uint32 // System call convention as an AUDIT_ARCH_* value.
+ InstructionPointer uint64 // At the time of the system call.
+ Args [6]uint64 // System call arguments (always stored as 64-bit values).
+}
+
+// C version of the struct used for sanity checking.
+type seccomp_data C.struct_seccomp_data
+
+// bpfLoadNR returns the instruction to load the NR field in SeccompData.
+func bpfLoadNR() SockFilter {
+ return bpfLoad(unsafe.Offsetof(SeccompData{}.NR))
+}
+
+// bpfLoadArch returns the instruction to load the Arch field in SeccompData.
+func bpfLoadArch() SockFilter {
+ return bpfLoad(unsafe.Offsetof(SeccompData{}.Arch))
+}
+
+// bpfLoadArg returns the instruction to load one word of an argument in SeccompData.
+func bpfLoadArg(arg, word int) SockFilter {
+ return bpfLoad(unsafe.Offsetof(SeccompData{}.Args) + uintptr(((2*arg)+word)*4))
+}
+
+// retKill returns the code for seccomp kill action.
+func retKill() uint32 {
+ return C.SECCOMP_RET_KILL
+}
+
+// retTrap returns the code for seccomp trap action.
+func retTrap() uint32 {
+ return C.SECCOMP_RET_TRAP
+}
+
+// retErrno returns the code for seccomp errno action with the specified errno embedded.
+func retErrno(errno syscall.Errno) uint32 {
+ return C.SECCOMP_RET_ERRNO | (uint32(errno) & C.SECCOMP_RET_DATA)
+}
+
+// retAllow returns the code for seccomp allow action.
+func retAllow() uint32 {
+ return C.SECCOMP_RET_ALLOW
+}
+
+// policy represents the seccomp policy for a single syscall.
+type policy struct {
+ // name of the syscall.
+ name string
+
+ // expr is evaluated on the syscall arguments.
+ // nil expr evaluates to false.
+ expr orExpr
+
+ // then is executed if the expr evaluates to true.
+ // (cannot be specified in policy file, used in tests only).
+ then SockFilter
+
+ // default action (else) if the expr evaluates to false.
+ // nil means jump to end of program for the overall default.
+ def *SockFilter
+}
+
+// orExpr is a list of and expressions.
+type orExpr []andExpr
+
+// andExpr is a list of arg comparisons.
+type andExpr []argComp
+
+// argComp represents a basic argument comparison in the policy.
+type argComp struct {
+ idx int // 0..5 for indexing into SeccompData.Args.
+ oper string // comparison operator: "==", "!=", or "&".
+ val uint64 // upper 32 bits compared only if nbits>32.
+}
+
+// String converts the internal policy representation back to policy file syntax.
+func (p policy) String() string {
+ var buf bytes.Buffer
+ fmt.Fprintf(&buf, "%s: ", p.name)
+
+ for i, and := range p.expr {
+ if i > 0 {
+ fmt.Fprintf(&buf, " || ")
+ }
+ for j, arg := range and {
+ if j > 0 {
+ fmt.Fprintf(&buf, " && ")
+ }
+ fmt.Fprintf(&buf, "arg%d %s %#x", arg.idx, arg.oper, arg.val)
+ }
+ }
+
+ pret := func(f SockFilter) {
+ if f.Code == opRET {
+ switch f.K & C.SECCOMP_RET_ACTION {
+ case C.SECCOMP_RET_ALLOW:
+ fmt.Fprintf(&buf, "1")
+ return
+ case C.SECCOMP_RET_ERRNO:
+ fmt.Fprintf(&buf, "return %d", f.K&C.SECCOMP_RET_DATA)
+ return
+ }
+ }
+ fmt.Fprintf(&buf, "%s", f)
+ }
+ if p.then != bpfRet(retAllow()) {
+ fmt.Fprintf(&buf, " ? ")
+ pret(p.then)
+ }
+ if p.def != nil {
+ if p.expr != nil {
+ fmt.Fprintf(&buf, "; ")
+ }
+ pret(*p.def)
+ }
+
+ return buf.String()
+}
+
+// Syntax of policy line for a single syscall.
+var (
+ allowRE = regexp.MustCompile(`^([[:word:]]+) *: *1$`)
+ returnRE = regexp.MustCompile(`^([[:word:]]+) *: *return *([[:word:]]+)$`)
+ exprRE = regexp.MustCompile(`^([[:word:]]+) *:([^;]+)$`)
+ exprReturnRE = regexp.MustCompile(`^([[:word:]]+) *:([^;]+); *return *([[:word:]]+)$`)
+
+ argRE = regexp.MustCompile(`^arg([0-5]) *(==|!=|&) *([[:word:]]+)$`)
+)
+
+// parseLine parses the policy line for a single syscall.
+func parseLine(line string) (policy, error) {
+ var name, expr, ret string
+ var then SockFilter
+ var def *SockFilter
+
+ line = strings.TrimSpace(line)
+ if match := allowRE.FindStringSubmatch(line); match != nil {
+ name = match[1]
+ def = ptr(bpfRet(retAllow()))
+ } else if match = returnRE.FindStringSubmatch(line); match != nil {
+ name = match[1]
+ ret = match[2]
+ } else if match = exprRE.FindStringSubmatch(line); match != nil {
+ name = match[1]
+ expr = match[2]
+ } else if match = exprReturnRE.FindStringSubmatch(line); match != nil {
+ name = match[1]
+ expr = match[2]
+ ret = match[3]
+ } else {
+ return policy{}, fmt.Errorf("invalid syntax")
+ }
+
+ if _, ok := syscallNum[name]; !ok {
+ return policy{}, fmt.Errorf("unknown syscall: %s", name)
+ }
+
+ var or orExpr
+ if expr != "" {
+ for _, sub := range strings.Split(expr, "||") {
+ var and andExpr
+ for _, arg := range strings.Split(sub, "&&") {
+ arg = strings.TrimSpace(arg)
+ match := argRE.FindStringSubmatch(arg)
+ if match == nil {
+ return policy{}, fmt.Errorf("invalid expression: %s", arg)
+ }
+ idx, err := strconv.Atoi(match[1])
+ if err != nil {
+ return policy{}, fmt.Errorf("invalid arg: %s", arg)
+ }
+ oper := match[2]
+ val, err := strconv.ParseUint(match[3], 0, 64)
+ if err != nil {
+ return policy{}, fmt.Errorf("invalid value: %s", arg)
+ }
+ and = append(and, argComp{idx, oper, val})
+ }
+ or = append(or, and)
+ }
+ }
+
+ then = bpfRet(retAllow())
+
+ if ret != "" {
+ errno, err := strconv.ParseUint(ret, 0, 16)
+ if err != nil {
+ return policy{}, fmt.Errorf("invalid errno: %s", ret)
+ }
+ def = ptr(bpfRet(retErrno(syscall.Errno(errno))))
+ }
+
+ return policy{name, or, then, def}, nil
+}
+
+// parseLines parses multiple policy lines, each one for a single syscall.
+// Empty lines and lines beginning with "#" are ignored.
+// Multiple policies for a syscall are detected and reported as error.
+func parseLines(lines []string) ([]policy, error) {
+ var ps []policy
+ seen := make(map[string]int)
+ for i, line := range lines {
+ lineno := i + 1
+ if line == "" || strings.HasPrefix(line, "#") {
+ continue
+ }
+ p, err := parseLine(line)
+ if err != nil {
+ return nil, fmt.Errorf("line %d: %v", lineno, err)
+ }
+ if seen[p.name] > 0 {
+ return nil, fmt.Errorf("lines %d,%d: multiple policies for %s",
+ seen[p.name], lineno, p.name)
+ }
+ seen[p.name] = lineno
+ ps = append(ps, p)
+ }
+ return ps, nil
+}
+
+// parseFile reads a Chromium-OS Seccomp-BPF policy file and parses its contents.
+func parseFile(path string) ([]policy, error) {
+ file, err := ioutil.ReadFile(path)
+ if err != nil {
+ return nil, err
+ }
+ return parseLines(strings.Split(string(file), "\n"))
+}
+
+// compile compiles a Seccomp-BPF program implementing the syscall policies.
+// long specifies whether to generate 32-bit or 64-bit argument comparisons.
+// def is the overall default action to take when the syscall does not match
+// any policy in the filter.
+func compile(ps []policy, long bool, def SockFilter) ([]SockFilter, error) {
+ var bpf []SockFilter
+ do := func(insn SockFilter) {
+ bpf = append(bpf, insn)
+ }
+
+ // ref maps a label to addresses of all the instructions that jump to it.
+ ref := make(map[string][]int)
+ jump := func(name string) {
+ // jump to a label with unresolved address: insert a placeholder instruction.
+ ref[name] = append(ref[name], len(bpf))
+ do(SockFilter{})
+ }
+ label := func(name string) {
+ // label address resolved: replace placeholder instructions with actual jumps.
+ for _, i := range ref[name] {
+ bpf[i] = bpfJump(len(bpf) - (i + 1))
+ }
+ delete(ref, name)
+ }
+
+ // Conditional jumps: jump if condition is true, fall through otherwise.
+ jeq := func(val uint32, target string) {
+ // if A == val { goto target }
+ do(bpfJeq(val, 0, 1))
+ jump(target)
+ }
+ jne := func(val uint32, target string) {
+ // if A != val { goto target }
+ do(bpfJeq(val, 1, 0))
+ jump(target)
+ }
+ jset := func(val uint32, target string) {
+ // if A&val != 0 { goto target }
+ do(bpfJset(val, 0, 1))
+ jump(target)
+ }
+ jnset := func(val uint32, target string) {
+ // if A&val == 0 { goto target }
+ do(bpfJset(val, 1, 0))
+ jump(target)
+ }
+
+ do(bpfLoadArch())
+ do(bpfJeq(auditArch, 1, 0))
+ do(bpfRet(retKill()))
+
+ do(bpfLoadNR())
+ for _, p := range ps {
+ nr, ok := syscallNum[p.name]
+ if !ok {
+ return nil, fmt.Errorf("unknown syscall: %s", p.name)
+ }
+ jne(uint32(nr), "nextcall")
+
+ for _, and := range p.expr {
+ for _, arg := range and {
+ val := struct{ high, low uint32 }{uint32(arg.val >> 32), uint32(arg.val)}
+ switch arg.oper {
+ case "==":
+ if long {
+ do(bpfLoadArg(arg.idx, 1))
+ jne(val.high, "nextor")
+ }
+ do(bpfLoadArg(arg.idx, 0))
+ jne(val.low, "nextor")
+ case "!=":
+ if long {
+ do(bpfLoadArg(arg.idx, 1))
+ jne(val.high, "nextand")
+ }
+ do(bpfLoadArg(arg.idx, 0))
+ jeq(val.low, "nextor")
+ case "&":
+ if long {
+ do(bpfLoadArg(arg.idx, 1))
+ jset(val.high, "nextand")
+ }
+ do(bpfLoadArg(arg.idx, 0))
+ jnset(val.low, "nextor")
+ default:
+ return nil, fmt.Errorf("unknown operator: %q", arg.oper)
+ }
+
+ // Comparison was satisfied. Move on to the next comparison in &&.
+ label("nextand")
+ }
+
+ // All comparisons in && were satisfied.
+ do(p.then)
+
+ // Some comparison in && was false. Move on to the next expression in ||.
+ label("nextor")
+ }
+
+ // All expressions in || evaluated to false (or expr was nil).
+ if p.def != nil {
+ do(*p.def)
+ } else {
+ jump("default")
+ }
+
+ label("nextcall")
+ }
+
+ label("default")
+ do(def)
+
+ if len(ref) > 0 {
+ return nil, fmt.Errorf("unresolved labels: %v\n%v", ref, bpf)
+ }
+ return bpf, nil
+}
+
+// Compile reads a Chromium-OS policy file and compiles a
+// Seccomp-BPF filter program implementing the policies.
+func Compile(path string) ([]SockFilter, error) {
+ ps, err := parseFile(path)
+ if err != nil {
+ return nil, err
+ }
+ return compile(ps, nbits > 32, bpfRet(retKill()))
+}
+
+// prctl is a wrapper for the 'prctl' system call.
+// See 'man prctl' for details.
+func prctl(option uintptr, args ...uintptr) error {
+ if len(args) > 4 {
+ return syscall.E2BIG
+ }
+ var arg [4]uintptr
+ copy(arg[:], args)
+ _, _, e := syscall.Syscall6(C.__NR_prctl, option, arg[0], arg[1], arg[2], arg[3], 0)
+ if e != 0 {
+ return e
+ }
+ return nil
+}
+
+// seccomp is a wrapper for the 'seccomp' system call.
+// See <linux/seccomp.h> for valid op and flag values.
+// uargs is typically a pointer to struct sock_fprog.
+func seccomp(op, flags uintptr, uargs unsafe.Pointer) error {
+ _, _, e := syscall.Syscall(C.__NR_seccomp, op, flags, uintptr(uargs))
+ if e != 0 {
+ return e
+ }
+ return nil
+}
+
+// CheckSupport checks for the required seccomp support in the kernel.
+func CheckSupport() error {
+ // This is based on http://outflux.net/teach-seccomp/autodetect.html.
+ if err := prctl(C.PR_GET_SECCOMP); err != nil {
+ return fmt.Errorf("seccomp not available: %v", err)
+ }
+ if err := prctl(C.PR_SET_SECCOMP, C.SECCOMP_MODE_FILTER, 0); err != syscall.EFAULT {
+ return fmt.Errorf("seccomp filter not available: %v", err)
+ }
+ if err := seccomp(C.SECCOMP_SET_MODE_FILTER, 0, nil); err != syscall.EFAULT {
+ return fmt.Errorf("seccomp syscall not available: %v", err)
+ }
+ if err := seccomp(C.SECCOMP_SET_MODE_FILTER, C.SECCOMP_FILTER_FLAG_TSYNC, nil); err != syscall.EFAULT {
+ return fmt.Errorf("seccomp tsync not available: %v", err)
+ }
+ return nil
+}
+
+// Load makes the seccomp system call to install the bpf filter for
+// all threads (with tsync). prctl(set_no_new_privs, 1) must have
+// been called (from the same thread) before calling Load for the
+// first time.
+// Most users of this library should use Install instead of calling
+// Load directly. There are a couple of situations where it may be
+// necessary to use Load instead of Install:
+// - If a previous call to Install has disabled the 'prctl' system
+// call, Install cannot be called again. In that case, it is safe
+// to add additional filters directly with Load.
+// - If the process is running as a priviledged user, and you want
+// to load the seccomp filter without setting no_new_privs.
+func Load(bpf []SockFilter) error {
+ if size, limit := len(bpf), 0xffff; size > limit {
+ return fmt.Errorf("filter program too big: %d bpf instructions (limit = %d)", size, limit)
+ }
+ prog := &SockFprog{
+ Filter: &bpf[0],
+ Len: uint16(len(bpf)),
+ }
+ return seccomp(C.SECCOMP_SET_MODE_FILTER, C.SECCOMP_FILTER_FLAG_TSYNC, unsafe.Pointer(prog))
+}
+
+// Install makes the necessary system calls to install the Seccomp-BPF
+// filter for the current process (all threads). Install can be called
+// multiple times to install additional filters.
+func Install(bpf []SockFilter) error {
+ // prctl(set_no_new_privs, 1) must be called (from the same thread)
+ // before a seccomp filter can be installed by an unprivileged user:
+ // - http://www.kernel.org/doc/Documentation/prctl/no_new_privs.txt.
+ runtime.LockOSThread()
+ defer runtime.UnlockOSThread()
+ if err := prctl(C.PR_SET_NO_NEW_PRIVS, 1); err != nil {
+ return err
+ }
+ return Load(bpf)
+}
diff --git a/src/chromiumos/seccomp/seccomp_test.go b/src/chromiumos/seccomp/seccomp_test.go
new file mode 100644
index 0000000..a5b90ab
--- /dev/null
+++ b/src/chromiumos/seccomp/seccomp_test.go
@@ -0,0 +1,529 @@
+// Copyright 2015 The Chromium OS Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package seccomp
+
+import (
+ "flag"
+ "os"
+ "runtime"
+ "syscall"
+ "testing"
+ "unsafe"
+)
+
+var (
+ parseFilePath = flag.String("parse_file", "", "path for TestParseFile")
+ testInstall = flag.Bool("test_install", false, "enable TestInstall (use with -cpu=N)")
+ testEndian = flag.Bool("test_endian", false, "enable TestEndian")
+)
+
+func TestParseLine(t *testing.T) {
+ tests := []struct {
+ policy string
+ want string
+ err string
+ }{
+ {policy: "read: 1"},
+ {policy: "open: return 1"},
+ {policy: "prctl: arg0 == 0xf"},
+ {policy: "prctl: arg0 != 0xf"},
+ {policy: "ioctl: arg1 & 0x5401"},
+ {policy: "ioctl: arg1 == 0x4024700a || arg1 == 0x541b"},
+ {policy: "ioctl: arg1 == 0x4024700a && arg1 == 0x541b"},
+ {policy: "ioctl: arg1 == 0x5401 || arg1 == 0x700a || arg2 & 0x541b"},
+ {policy: "ioctl: arg1 == 0x5401 && arg1 == 0x700a && arg3 & 0x541b"},
+ {policy: "ioctl: arg1 == 0x5401 || arg1 == 0x700a && arg4 & 0x541b"},
+ {policy: "ioctl: arg1 == 0x5401 && arg1 == 0x700a || arg5 & 0x541b"},
+ {policy: "ioctl: arg1 == 0x5401 && arg1 == 0x700a || arg5 & 0x541b; return 1"},
+ {
+ // different spacing around colon.
+ policy: "read :1",
+ want: "read: 1",
+ },
+ {
+ // leading and trailing whitespace.
+ policy: " open : return 1 ",
+ want: "open: return 1",
+ },
+ {
+ // return hexadecimal errno.
+ policy: "open: return 0x10",
+ want: "open: return 16",
+ },
+ {
+ // return octal errno.
+ policy: "open: return 010",
+ want: "open: return 8",
+ },
+ {
+ // return highest errno.
+ policy: "open: return 0xffff",
+ want: "open: return 65535",
+ },
+ {
+ // expression with no spaces.
+ policy: "ioctl:arg1==0x5401&&arg1==0x700a||arg2&0x541b",
+ want: "ioctl: arg1 == 0x5401 && arg1 == 0x700a || arg2 & 0x541b",
+ },
+ {
+ // compare with decimal value.
+ policy: "ioctl: arg1 == 5401 && arg1 == 0x700a || arg2 & 0x541b",
+ want: "ioctl: arg1 == 0x1519 && arg1 == 0x700a || arg2 & 0x541b",
+ },
+ {
+ // compare with octal value.
+ policy: "ioctl: arg1 == 05401 && arg1 == 0x700a || arg2 & 0x541b",
+ want: "ioctl: arg1 == 0xb01 && arg1 == 0x700a || arg2 & 0x541b",
+ },
+ {
+ // all decimal comparisons.
+ policy: "clone: arg0 == 1 || arg0 == 2 || arg0 == 16",
+ want: "clone: arg0 == 0x1 || arg0 == 0x2 || arg0 == 0x10",
+ },
+ {
+ // missing syscall name.
+ policy: ": 1",
+ err: "invalid syntax",
+ },
+ {
+ // malformed syscall name.
+ policy: "two words: 1",
+ err: "invalid syntax",
+ },
+ {
+ // missing colon.
+ policy: "read = 1",
+ err: "invalid syntax",
+ },
+ {
+ // trailing semicolon after return.
+ policy: "open: return 1;",
+ err: "invalid syntax",
+ },
+ {
+ // trailing semicolon after expression.
+ policy: "prctl: arg0 == 0xf;",
+ err: "invalid syntax",
+ },
+ {
+ // missing return after semicolon.
+ policy: "prctl: arg0 == 0xf; 1",
+ err: "invalid syntax",
+ },
+ {
+ // bad syscall name.
+ policy: "bad: 1",
+ err: "unknown syscall: bad",
+ },
+ {
+ // symbolic errno is not supported.
+ policy: "open: return EPERM",
+ err: "invalid errno: EPERM",
+ },
+ {
+ // errno must fit in 16 bits.
+ policy: "open: return 0x10000",
+ err: "invalid errno: 0x10000",
+ },
+ {
+ // missing argument index.
+ policy: "prctl: arg == 0xf",
+ err: "invalid expression: arg == 0xf",
+ },
+ {
+ // arg index out of range.
+ policy: "prctl: arg6 == 0xf",
+ err: "invalid expression: arg6 == 0xf",
+ },
+ {
+ // bitwise and with argument not supported.
+ policy: "prctl: arg0 & 0xf == 0xf",
+ err: "invalid expression: arg0 & 0xf == 0xf",
+ },
+ {
+ // unknown operator.
+ policy: "prctl: arg0 !== 0xf",
+ err: "invalid expression: arg0 !== 0xf",
+ },
+ {
+ // invalid hexadecimal value.
+ policy: "prctl: arg0 == 0xfdx",
+ err: "invalid value: arg0 == 0xfdx",
+ },
+ {
+ // invalid decimal value.
+ policy: "prctl: arg0 == 123a",
+ err: "invalid value: arg0 == 123a",
+ },
+ {
+ // invalid octal value.
+ policy: "prctl: arg0 == 0129",
+ err: "invalid value: arg0 == 0129",
+ },
+ {
+ // invalid subexpression.
+ policy: "prctl: arg0 == 0x100 && arg1 = 0x101 || arg2 == 0x102",
+ err: "invalid expression: arg1 = 0x101",
+ },
+ }
+ for _, test := range tests {
+ var err string
+ p, e := parseLine(test.policy)
+ if e != nil {
+ err = e.Error()
+ }
+ if err != "" || test.err != "" {
+ if err != test.err {
+ t.Errorf("parseLine(%q): error = %q; want %q", test.policy, err, test.err)
+ }
+ continue
+ }
+ want := test.want
+ if want == "" {
+ want = test.policy
+ }
+ if got := p.String(); got != want {
+ t.Errorf("parseLine(%q) = %q; want %q", test.policy, got, test.want)
+ }
+ }
+}
+
+func TestParseLines(t *testing.T) {
+ tests := []struct {
+ file []string
+ err string
+ }{
+ {
+ // simple policy file.
+ file: []string{
+ "read: 1",
+ "write: 1",
+ "open: return 1",
+ },
+ },
+ {
+ // comment lines are ignored.
+ file: []string{
+ "read: 1",
+ "write: 1",
+ "# open: return EPERM",
+ "open: return 1",
+ },
+ },
+ {
+ // blank lines are ignored.
+ file: []string{
+ "read: 1",
+ "write: 1",
+ "",
+ "open: return 1",
+ },
+ },
+ {
+ // leading space on comment line.
+ file: []string{
+ "read: 1",
+ "write: 1",
+ " # open: return EPERM",
+ "open: return 1",
+ },
+ err: "line 3: invalid syntax",
+ },
+ {
+ // line consisting of whitespace only.
+ file: []string{
+ "read: 1",
+ "write: 1",
+ " ",
+ "open: return 1",
+ },
+ err: "line 3: invalid syntax",
+ },
+ {
+ // parse error on one line.
+ file: []string{
+ "read: 1",
+ "write: return 019",
+ "open: return 1",
+ },
+ err: "line 2: invalid errno: 019",
+ },
+ {
+ // multiple policies for a syscall.
+ file: []string{
+ "read: 1",
+ "write: 1",
+ "read: return 1",
+ "open: return 1",
+ },
+ err: "lines 1,3: multiple policies for read",
+ },
+ }
+ for _, test := range tests {
+ var err string
+ _, e := parseLines(test.file)
+ if e != nil {
+ err = e.Error()
+ }
+ if err != "" || test.err != "" {
+ if err != test.err {
+ t.Errorf("parseLines(%q): error = %q; want %q", test.file, err, test.err)
+ }
+ }
+ }
+}
+
+func TestParseFile(t *testing.T) {
+ if *parseFilePath == "" {
+ t.Skip("use -parse_file to enable.")
+ }
+
+ if _, err := parseFile(*parseFilePath); err != nil {
+ t.Errorf("parseFile(%q): %v", *parseFilePath, err)
+ }
+}
+
+func TestCompile(t *testing.T) {
+ syscallName := make(map[int32]string)
+ for name, nr := range syscallNum {
+ syscallName[int32(nr)] = name
+ }
+
+ call := func(name string, args ...uint64) SeccompData {
+ nr, ok := syscallNum[name]
+ if !ok {
+ t.Fatalf("unknown syscall: %s", name)
+ }
+ data := SeccompData{
+ NR: int32(nr),
+ Arch: auditArch,
+ }
+ copy(data.Args[:], args)
+ return data
+ }
+
+ eval := func(bpf []SockFilter, data SeccompData) uint32 {
+ var A uint32
+ IP := 0
+ for {
+ Insn := bpf[IP]
+ IP++
+ switch Insn.Code {
+ case opLOAD:
+ A = *(*uint32)(unsafe.Pointer(uintptr(unsafe.Pointer(&data)) + uintptr(Insn.K)))
+ case opJEQ:
+ if A == Insn.K {
+ IP += int(Insn.JT)
+ } else {
+ IP += int(Insn.JF)
+ }
+ case opJSET:
+ if A&Insn.K != 0 {
+ IP += int(Insn.JT)
+ } else {
+ IP += int(Insn.JF)
+ }
+ case opJUMP:
+ IP += int(Insn.K)
+ case opRET:
+ return Insn.K
+ default:
+ t.Fatalf("unsupported instruction: %v", Insn)
+ }
+ }
+ }
+
+ file := []string{
+ "read: 1",
+ "open: return 1",
+ "write: arg0 == 1",
+ "close: arg0 == 2; return 9",
+ "dup: arg0 == 1 || arg0 == 2",
+ "pipe: arg0 == 1 && arg1 == 2",
+ "link: arg0 != 1 && arg1 != 2 || arg2 == 3",
+ "unlink: arg0 != 1 || arg1 != 2 && arg2 == 3",
+ "creat: arg0 & 0xf00 && arg1 & 0x0f0 && arg2 & 0x00f",
+ "lseek: arg0 & 0x0f000f000f000f00 && arg1 & 0x00f000f000f000f0 && arg2 & 0x000f000f000f000f",
+ "stat: arg0 != 0x0123456789abcdef && arg1 != 0x123456789abcdef0 || arg2 == 0x00f000f000000000",
+ "fstat: arg0 != 0x0123456789abcdef || arg1 != 0x123456789abcdef0 && arg2 == 0x00f000f000000000",
+ }
+ tests := []struct {
+ data SeccompData
+ want uint32
+ }{
+ {call("fork"), retKill()},
+ {call("read"), retAllow()},
+ {call("open"), retErrno(1)},
+ {call("write", 0), retKill()},
+ {call("write", 1), retAllow()},
+ {call("close", 1), retErrno(9)},
+ {call("close", 2), retAllow()},
+ {call("dup", 0), retKill()},
+ {call("dup", 1), retAllow()},
+ {call("dup", 2), retAllow()},
+ {call("dup", 3), retKill()},
+ {call("pipe", 1, 1), retKill()},
+ {call("pipe", 1, 2), retAllow()},
+ {call("pipe", 2, 1), retKill()},
+ {call("pipe", 2, 2), retKill()},
+ {call("link", 1, 2, 3), retAllow()},
+ {call("link", 1, 2, 2), retKill()},
+ {call("link", 2, 2, 2), retKill()},
+ {call("link", 2, 1, 2), retAllow()},
+ {call("unlink", 2, 1, 2), retAllow()},
+ {call("unlink", 1, 1, 2), retKill()},
+ {call("unlink", 1, 1, 3), retAllow()},
+ {call("unlink", 1, 2, 3), retKill()},
+ {call("creat", 0x100, 0x100, 0x101), retKill()},
+ {call("creat", 0x200, 0x110, 0x101), retAllow()},
+ {call("creat", 0x400, 0x110, 0x110), retKill()},
+ {call("creat", 0x800, 0x110, 0x007), retAllow()},
+ {call("lseek", 0x0100, 0x0100, 0x0101), retKill()},
+ {call("lseek", 0x0200, 0x0110, 0x0101), retAllow()},
+ {call("lseek", 0x0400, 0x0110, 0x0110), retKill()},
+ {call("lseek", 0x0800, 0x0110, 0x0007), retAllow()},
+ {call("lseek", 0x0100000000000000, 0x0100000000000000, 0x0101000000000000), retKill()},
+ {call("lseek", 0x0200000000000000, 0x0110000000000000, 0x0101000000000000), retAllow()},
+ {call("lseek", 0x0400000000000000, 0x0110000000000000, 0x0110000000000000), retKill()},
+ {call("lseek", 0x0800000000000000, 0x0110000000000000, 0x0007000000000000), retAllow()},
+ {call("stat", 0x0123456789abcdef, 0x123456789abcdef0, 0x00f000f000000000), retAllow()},
+ {call("stat", 0x0123456789abcdef, 0x123456789abcdef0, 0x007000f000000000), retKill()},
+ {call("stat", 0x0133456789abcdef, 0x123457789abcdef0, 0x007000f000000000), retAllow()},
+ {call("stat", 0x0133456789abcdef, 0x123456789abcdef0, 0x007000f000000000), retKill()},
+ {call("fstat", 0x0123456789abcdef, 0x123456789abcdef0, 0x00f000f000000000), retKill()},
+ {call("fstat", 0x0133456789abcdef, 0x123456789abcdef0, 0x00f000f000000000), retAllow()},
+ {call("fstat", 0x0123456789abcdef, 0x123457789abcdef0, 0x00f000f000000000), retAllow()},
+ {call("fstat", 0x0123456789abcdef, 0x123457789abcdef0, 0x007000f000000000), retKill()},
+ }
+
+ ps, err := parseLines(file)
+ if err != nil {
+ t.Fatalf("parse failed: %v", err)
+ }
+ bpf, err := compile(ps, true, bpfRet(retKill()))
+ if err != nil {
+ t.Fatalf("compile failed: %v", err)
+ }
+ t.Logf("len(bpf) = %d", len(bpf))
+ for _, test := range tests {
+ if got := eval(bpf, test.data); got != test.want {
+ t.Errorf("%s%#x = %#08x; want %#08x", syscallName[test.data.NR], test.data.Args, got, test.want)
+ }
+ }
+}
+
+func TestSupport(t *testing.T) {
+ if err := CheckSupport(); err != nil {
+ t.Error(err)
+ }
+}
+
+func TestInstall(t *testing.T) {
+ if !*testInstall {
+ t.Skip("use -test_install (with -cpu=N) to enable.")
+ }
+
+ file := []string{
+ "# open: return EPERM",
+ "open: return 1",
+ "# default: ALLOW",
+ }
+
+ ps, err := parseLines(file)
+ if err != nil {
+ t.Fatalf("parse failed: %v", err)
+ }
+ bpf, err := compile(ps, nbits > 32, bpfRet(retAllow()))
+ if err != nil {
+ t.Fatalf("compile failed: %v", err)
+ }
+ if err = Install(bpf); err != nil {
+ t.Fatalf("install failed: %v", err)
+ }
+
+ N := runtime.GOMAXPROCS(0)
+ opened := make(chan bool)
+ for i := 0; i < N; i++ {
+ go func() {
+ if f, err := os.Open("/dev/null"); err != nil {
+ t.Logf("open() failed: %v", err)
+ opened <- false
+ } else {
+ t.Logf("open() succeeded")
+ f.Close()
+ opened <- true
+ }
+ }()
+ }
+ for i := 0; i < N; i++ {
+ if <-opened {
+ t.Fail()
+ }
+ }
+}
+
+func TestEndian(t *testing.T) {
+ if !*testEndian {
+ t.Skip("use -test_endian to enable.")
+ }
+
+ pass := syscall.EDOM
+ fail := syscall.ERANGE
+ name := map[error]string{
+ pass: "pass",
+ fail: "fail",
+ nil: "<nil>",
+ }
+
+ type seccomp [3]uintptr
+ ps := []policy{
+ {
+ name: "seccomp",
+ expr: orExpr{
+ andExpr{
+ argComp{0, "==", 0x0123456789abcdef},
+ },
+ andExpr{
+ argComp{1, "!=", 0x01234567},
+ argComp{2, "&", 0x01010101},
+ },
+ },
+ then: bpfRet(retErrno(pass)),
+ def: ptr(bpfRet(retErrno(fail))),
+ },
+ }
+ tests := []struct {
+ args seccomp
+ want error
+ }{
+ {seccomp{0x01234567, 0, 0}, fail},
+ {seccomp{0x89abcdef, 0, 0}, pass},
+ {seccomp{0, 0x01234567, 0}, fail},
+ {seccomp{0, 0x12345678, 0}, fail},
+ {seccomp{0, 0x01234567, 1}, fail},
+ {seccomp{0, 0x12345678, 1}, pass},
+ }
+ call := func(args seccomp) error {
+ if nr, ok := syscallNum["seccomp"]; ok {
+ if _, _, e := syscall.Syscall(uintptr(nr), args[0], args[1], args[2]); e != 0 {
+ return e
+ }
+ }
+ return nil
+ }
+
+ bpf, err := compile(ps, false, bpfRet(retAllow()))
+ if err != nil {
+ t.Fatalf("compile failed: %v", err)
+ }
+ if err = Install(bpf); err != nil {
+ t.Fatalf("install failed: %v", err)
+ }
+ for _, test := range tests {
+ if got := call(test.args); got != test.want {
+ t.Errorf("seccomp%#x = %v; want %v", test.args, name[got], name[test.want])
+ }
+ }
+}
diff --git a/src/chromiumos/seccomp/syscalls_386.go b/src/chromiumos/seccomp/syscalls_386.go
new file mode 100644
index 0000000..edb3c5d
--- /dev/null
+++ b/src/chromiumos/seccomp/syscalls_386.go
@@ -0,0 +1,365 @@
+// DO NOT EDIT. Autogenerated by syscalls_gen.go
+
+package seccomp
+
+// #include <asm/unistd.h>
+import "C"
+
+// syscallNum maps system call names to numbers.
+var syscallNum = map[string]int{
+ "restart_syscall": C.__NR_restart_syscall,
+ "exit": C.__NR_exit,
+ "fork": C.__NR_fork,
+ "read": C.__NR_read,
+ "write": C.__NR_write,
+ "open": C.__NR_open,
+ "close": C.__NR_close,
+ "waitpid": C.__NR_waitpid,
+ "creat": C.__NR_creat,
+ "link": C.__NR_link,
+ "unlink": C.__NR_unlink,
+ "execve": C.__NR_execve,
+ "chdir": C.__NR_chdir,
+ "time": C.__NR_time,
+ "mknod": C.__NR_mknod,
+ "chmod": C.__NR_chmod,
+ "lchown": C.__NR_lchown,
+ "break": C.__NR_break,
+ "oldstat": C.__NR_oldstat,
+ "lseek": C.__NR_lseek,
+ "getpid": C.__NR_getpid,
+ "mount": C.__NR_mount,
+ "umount": C.__NR_umount,
+ "setuid": C.__NR_setuid,
+ "getuid": C.__NR_getuid,
+ "stime": C.__NR_stime,
+ "ptrace": C.__NR_ptrace,
+ "alarm": C.__NR_alarm,
+ "oldfstat": C.__NR_oldfstat,
+ "pause": C.__NR_pause,
+ "utime": C.__NR_utime,
+ "stty": C.__NR_stty,
+ "gtty": C.__NR_gtty,
+ "access": C.__NR_access,
+ "nice": C.__NR_nice,
+ "ftime": C.__NR_ftime,
+ "sync": C.__NR_sync,
+ "kill": C.__NR_kill,
+ "rename": C.__NR_rename,
+ "mkdir": C.__NR_mkdir,
+ "rmdir": C.__NR_rmdir,
+ "dup": C.__NR_dup,
+ "pipe": C.__NR_pipe,
+ "times": C.__NR_times,
+ "prof": C.__NR_prof,
+ "brk": C.__NR_brk,
+ "setgid": C.__NR_setgid,
+ "getgid": C.__NR_getgid,
+ "signal": C.__NR_signal,
+ "geteuid": C.__NR_geteuid,
+ "getegid": C.__NR_getegid,
+ "acct": C.__NR_acct,
+ "umount2": C.__NR_umount2,
+ "lock": C.__NR_lock,
+ "ioctl": C.__NR_ioctl,
+ "fcntl": C.__NR_fcntl,
+ "mpx": C.__NR_mpx,
+ "setpgid": C.__NR_setpgid,
+ "ulimit": C.__NR_ulimit,
+ "oldolduname": C.__NR_oldolduname,
+ "umask": C.__NR_umask,
+ "chroot": C.__NR_chroot,
+ "ustat": C.__NR_ustat,
+ "dup2": C.__NR_dup2,
+ "getppid": C.__NR_getppid,
+ "getpgrp": C.__NR_getpgrp,
+ "setsid": C.__NR_setsid,
+ "sigaction": C.__NR_sigaction,
+ "sgetmask": C.__NR_sgetmask,
+ "ssetmask": C.__NR_ssetmask,
+ "setreuid": C.__NR_setreuid,
+ "setregid": C.__NR_setregid,
+ "sigsuspend": C.__NR_sigsuspend,
+ "sigpending": C.__NR_sigpending,
+ "sethostname": C.__NR_sethostname,
+ "setrlimit": C.__NR_setrlimit,
+ "getrlimit": C.__NR_getrlimit,
+ "getrusage": C.__NR_getrusage,
+ "gettimeofday": C.__NR_gettimeofday,
+ "settimeofday": C.__NR_settimeofday,
+ "getgroups": C.__NR_getgroups,
+ "setgroups": C.__NR_setgroups,
+ "select": C.__NR_select,
+ "symlink": C.__NR_symlink,
+ "oldlstat": C.__NR_oldlstat,
+ "readlink": C.__NR_readlink,
+ "uselib": C.__NR_uselib,
+ "swapon": C.__NR_swapon,
+ "reboot": C.__NR_reboot,
+ "readdir": C.__NR_readdir,
+ "mmap": C.__NR_mmap,
+ "munmap": C.__NR_munmap,
+ "truncate": C.__NR_truncate,
+ "ftruncate": C.__NR_ftruncate,
+ "fchmod": C.__NR_fchmod,
+ "fchown": C.__NR_fchown,
+ "getpriority": C.__NR_getpriority,
+ "setpriority": C.__NR_setpriority,
+ "profil": C.__NR_profil,
+ "statfs": C.__NR_statfs,
+ "fstatfs": C.__NR_fstatfs,
+ "ioperm": C.__NR_ioperm,
+ "socketcall": C.__NR_socketcall,
+ "syslog": C.__NR_syslog,
+ "setitimer": C.__NR_setitimer,
+ "getitimer": C.__NR_getitimer,
+ "stat": C.__NR_stat,
+ "lstat": C.__NR_lstat,
+ "fstat": C.__NR_fstat,
+ "olduname": C.__NR_olduname,
+ "iopl": C.__NR_iopl,
+ "vhangup": C.__NR_vhangup,
+ "idle": C.__NR_idle,
+ "vm86old": C.__NR_vm86old,
+ "wait4": C.__NR_wait4,
+ "swapoff": C.__NR_swapoff,
+ "sysinfo": C.__NR_sysinfo,
+ "ipc": C.__NR_ipc,
+ "fsync": C.__NR_fsync,
+ "sigreturn": C.__NR_sigreturn,
+ "clone": C.__NR_clone,
+ "setdomainname": C.__NR_setdomainname,
+ "uname": C.__NR_uname,
+ "modify_ldt": C.__NR_modify_ldt,
+ "adjtimex": C.__NR_adjtimex,
+ "mprotect": C.__NR_mprotect,
+ "sigprocmask": C.__NR_sigprocmask,
+ "create_module": C.__NR_create_module,
+ "init_module": C.__NR_init_module,
+ "delete_module": C.__NR_delete_module,
+ "get_kernel_syms": C.__NR_get_kernel_syms,
+ "quotactl": C.__NR_quotactl,
+ "getpgid": C.__NR_getpgid,
+ "fchdir": C.__NR_fchdir,
+ "bdflush": C.__NR_bdflush,
+ "sysfs": C.__NR_sysfs,
+ "personality": C.__NR_personality,
+ "afs_syscall": C.__NR_afs_syscall,
+ "setfsuid": C.__NR_setfsuid,
+ "setfsgid": C.__NR_setfsgid,
+ "_llseek": C.__NR__llseek,
+ "getdents": C.__NR_getdents,
+ "_newselect": C.__NR__newselect,
+ "flock": C.__NR_flock,
+ "msync": C.__NR_msync,
+ "readv": C.__NR_readv,
+ "writev": C.__NR_writev,
+ "getsid": C.__NR_getsid,
+ "fdatasync": C.__NR_fdatasync,
+ "_sysctl": C.__NR__sysctl,
+ "mlock": C.__NR_mlock,
+ "munlock": C.__NR_munlock,
+ "mlockall": C.__NR_mlockall,
+ "munlockall": C.__NR_munlockall,
+ "sched_setparam": C.__NR_sched_setparam,
+ "sched_getparam": C.__NR_sched_getparam,
+ "sched_setscheduler": C.__NR_sched_setscheduler,
+ "sched_getscheduler": C.__NR_sched_getscheduler,
+ "sched_yield": C.__NR_sched_yield,
+ "sched_get_priority_max": C.__NR_sched_get_priority_max,
+ "sched_get_priority_min": C.__NR_sched_get_priority_min,
+ "sched_rr_get_interval": C.__NR_sched_rr_get_interval,
+ "nanosleep": C.__NR_nanosleep,
+ "mremap": C.__NR_mremap,
+ "setresuid": C.__NR_setresuid,
+ "getresuid": C.__NR_getresuid,
+ "vm86": C.__NR_vm86,
+ "query_module": C.__NR_query_module,
+ "poll": C.__NR_poll,
+ "nfsservctl": C.__NR_nfsservctl,
+ "setresgid": C.__NR_setresgid,
+ "getresgid": C.__NR_getresgid,
+ "prctl": C.__NR_prctl,
+ "rt_sigreturn": C.__NR_rt_sigreturn,
+ "rt_sigaction": C.__NR_rt_sigaction,
+ "rt_sigprocmask": C.__NR_rt_sigprocmask,
+ "rt_sigpending": C.__NR_rt_sigpending,
+ "rt_sigtimedwait": C.__NR_rt_sigtimedwait,
+ "rt_sigqueueinfo": C.__NR_rt_sigqueueinfo,
+ "rt_sigsuspend": C.__NR_rt_sigsuspend,
+ "pread64": C.__NR_pread64,
+ "pwrite64": C.__NR_pwrite64,
+ "chown": C.__NR_chown,
+ "getcwd": C.__NR_getcwd,
+ "capget": C.__NR_capget,
+ "capset": C.__NR_capset,
+ "sigaltstack": C.__NR_sigaltstack,
+ "sendfile": C.__NR_sendfile,
+ "getpmsg": C.__NR_getpmsg,
+ "putpmsg": C.__NR_putpmsg,
+ "vfork": C.__NR_vfork,
+ "ugetrlimit": C.__NR_ugetrlimit,
+ "mmap2": C.__NR_mmap2,
+ "truncate64": C.__NR_truncate64,
+ "ftruncate64": C.__NR_ftruncate64,
+ "stat64": C.__NR_stat64,
+ "lstat64": C.__NR_lstat64,
+ "fstat64": C.__NR_fstat64,
+ "lchown32": C.__NR_lchown32,
+ "getuid32": C.__NR_getuid32,
+ "getgid32": C.__NR_getgid32,
+ "geteuid32": C.__NR_geteuid32,
+ "getegid32": C.__NR_getegid32,
+ "setreuid32": C.__NR_setreuid32,
+ "setregid32": C.__NR_setregid32,
+ "getgroups32": C.__NR_getgroups32,
+ "setgroups32": C.__NR_setgroups32,
+ "fchown32": C.__NR_fchown32,
+ "setresuid32": C.__NR_setresuid32,
+ "getresuid32": C.__NR_getresuid32,
+ "setresgid32": C.__NR_setresgid32,
+ "getresgid32": C.__NR_getresgid32,
+ "chown32": C.__NR_chown32,
+ "setuid32": C.__NR_setuid32,
+ "setgid32": C.__NR_setgid32,
+ "setfsuid32": C.__NR_setfsuid32,
+ "setfsgid32": C.__NR_setfsgid32,
+ "pivot_root": C.__NR_pivot_root,
+ "mincore": C.__NR_mincore,
+ "madvise": C.__NR_madvise,
+ "getdents64": C.__NR_getdents64,
+ "fcntl64": C.__NR_fcntl64,
+ "gettid": C.__NR_gettid,
+ "readahead": C.__NR_readahead,
+ "setxattr": C.__NR_setxattr,
+ "lsetxattr": C.__NR_lsetxattr,
+ "fsetxattr": C.__NR_fsetxattr,
+ "getxattr": C.__NR_getxattr,
+ "lgetxattr": C.__NR_lgetxattr,
+ "fgetxattr": C.__NR_fgetxattr,
+ "listxattr": C.__NR_listxattr,
+ "llistxattr": C.__NR_llistxattr,
+ "flistxattr": C.__NR_flistxattr,
+ "removexattr": C.__NR_removexattr,
+ "lremovexattr": C.__NR_lremovexattr,
+ "fremovexattr": C.__NR_fremovexattr,
+ "tkill": C.__NR_tkill,
+ "sendfile64": C.__NR_sendfile64,
+ "futex": C.__NR_futex,
+ "sched_setaffinity": C.__NR_sched_setaffinity,
+ "sched_getaffinity": C.__NR_sched_getaffinity,
+ "set_thread_area": C.__NR_set_thread_area,
+ "get_thread_area": C.__NR_get_thread_area,
+ "io_setup": C.__NR_io_setup,
+ "io_destroy": C.__NR_io_destroy,
+ "io_getevents": C.__NR_io_getevents,
+ "io_submit": C.__NR_io_submit,
+ "io_cancel": C.__NR_io_cancel,
+ "fadvise64": C.__NR_fadvise64,
+ "exit_group": C.__NR_exit_group,
+ "lookup_dcookie": C.__NR_lookup_dcookie,
+ "epoll_create": C.__NR_epoll_create,
+ "epoll_ctl": C.__NR_epoll_ctl,
+ "epoll_wait": C.__NR_epoll_wait,
+ "remap_file_pages": C.__NR_remap_file_pages,
+ "set_tid_address": C.__NR_set_tid_address,
+ "timer_create": C.__NR_timer_create,
+ "timer_settime": C.__NR_timer_settime,
+ "timer_gettime": C.__NR_timer_gettime,
+ "timer_getoverrun": C.__NR_timer_getoverrun,
+ "timer_delete": C.__NR_timer_delete,
+ "clock_settime": C.__NR_clock_settime,
+ "clock_gettime": C.__NR_clock_gettime,
+ "clock_getres": C.__NR_clock_getres,
+ "clock_nanosleep": C.__NR_clock_nanosleep,
+ "statfs64": C.__NR_statfs64,
+ "fstatfs64": C.__NR_fstatfs64,
+ "tgkill": C.__NR_tgkill,
+ "utimes": C.__NR_utimes,
+ "fadvise64_64": C.__NR_fadvise64_64,
+ "vserver": C.__NR_vserver,
+ "mbind": C.__NR_mbind,
+ "get_mempolicy": C.__NR_get_mempolicy,
+ "set_mempolicy": C.__NR_set_mempolicy,
+ "mq_open": C.__NR_mq_open,
+ "mq_unlink": C.__NR_mq_unlink,
+ "mq_timedsend": C.__NR_mq_timedsend,
+ "mq_timedreceive": C.__NR_mq_timedreceive,
+ "mq_notify": C.__NR_mq_notify,
+ "mq_getsetattr": C.__NR_mq_getsetattr,
+ "kexec_load": C.__NR_kexec_load,
+ "waitid": C.__NR_waitid,
+ "add_key": C.__NR_add_key,
+ "request_key": C.__NR_request_key,
+ "keyctl": C.__NR_keyctl,
+ "ioprio_set": C.__NR_ioprio_set,
+ "ioprio_get": C.__NR_ioprio_get,
+ "inotify_init": C.__NR_inotify_init,
+ "inotify_add_watch": C.__NR_inotify_add_watch,
+ "inotify_rm_watch": C.__NR_inotify_rm_watch,
+ "migrate_pages": C.__NR_migrate_pages,
+ "openat": C.__NR_openat,
+ "mkdirat": C.__NR_mkdirat,
+ "mknodat": C.__NR_mknodat,
+ "fchownat": C.__NR_fchownat,
+ "futimesat": C.__NR_futimesat,
+ "fstatat64": C.__NR_fstatat64,
+ "unlinkat": C.__NR_unlinkat,
+ "renameat": C.__NR_renameat,
+ "linkat": C.__NR_linkat,
+ "symlinkat": C.__NR_symlinkat,
+ "readlinkat": C.__NR_readlinkat,
+ "fchmodat": C.__NR_fchmodat,
+ "faccessat": C.__NR_faccessat,
+ "pselect6": C.__NR_pselect6,
+ "ppoll": C.__NR_ppoll,
+ "unshare": C.__NR_unshare,
+ "set_robust_list": C.__NR_set_robust_list,
+ "get_robust_list": C.__NR_get_robust_list,
+ "splice": C.__NR_splice,
+ "sync_file_range": C.__NR_sync_file_range,
+ "tee": C.__NR_tee,
+ "vmsplice": C.__NR_vmsplice,
+ "move_pages": C.__NR_move_pages,
+ "getcpu": C.__NR_getcpu,
+ "epoll_pwait": C.__NR_epoll_pwait,
+ "utimensat": C.__NR_utimensat,
+ "signalfd": C.__NR_signalfd,
+ "timerfd_create": C.__NR_timerfd_create,
+ "eventfd": C.__NR_eventfd,
+ "fallocate": C.__NR_fallocate,
+ "timerfd_settime": C.__NR_timerfd_settime,
+ "timerfd_gettime": C.__NR_timerfd_gettime,
+ "signalfd4": C.__NR_signalfd4,
+ "eventfd2": C.__NR_eventfd2,
+ "epoll_create1": C.__NR_epoll_create1,
+ "dup3": C.__NR_dup3,
+ "pipe2": C.__NR_pipe2,
+ "inotify_init1": C.__NR_inotify_init1,
+ "preadv": C.__NR_preadv,
+ "pwritev": C.__NR_pwritev,
+ "rt_tgsigqueueinfo": C.__NR_rt_tgsigqueueinfo,
+ "perf_event_open": C.__NR_perf_event_open,
+ "recvmmsg": C.__NR_recvmmsg,
+ "fanotify_init": C.__NR_fanotify_init,
+ "fanotify_mark": C.__NR_fanotify_mark,
+ "prlimit64": C.__NR_prlimit64,
+ "name_to_handle_at": C.__NR_name_to_handle_at,
+ "open_by_handle_at": C.__NR_open_by_handle_at,
+ "clock_adjtime": C.__NR_clock_adjtime,
+ "syncfs": C.__NR_syncfs,
+ "sendmmsg": C.__NR_sendmmsg,
+ "setns": C.__NR_setns,
+ "process_vm_readv": C.__NR_process_vm_readv,
+ "process_vm_writev": C.__NR_process_vm_writev,
+ "kcmp": C.__NR_kcmp,
+ "finit_module": C.__NR_finit_module,
+ "sched_setattr": C.__NR_sched_setattr,
+ "sched_getattr": C.__NR_sched_getattr,
+ "renameat2": C.__NR_renameat2,
+ "seccomp": C.__NR_seccomp,
+ "getrandom": C.__NR_getrandom,
+ "memfd_create": C.__NR_memfd_create,
+ "bpf": C.__NR_bpf,
+ "execveat": C.__NR_execveat,
+}
diff --git a/src/chromiumos/seccomp/syscalls_amd64.go b/src/chromiumos/seccomp/syscalls_amd64.go
new file mode 100644
index 0000000..749cfeb
--- /dev/null
+++ b/src/chromiumos/seccomp/syscalls_amd64.go
@@ -0,0 +1,333 @@
+// DO NOT EDIT. Autogenerated by syscalls_gen.go
+
+package seccomp
+
+// #include <asm/unistd.h>
+import "C"
+
+// syscallNum maps system call names to numbers.
+var syscallNum = map[string]int{
+ "read": C.__NR_read,
+ "write": C.__NR_write,
+ "open": C.__NR_open,
+ "close": C.__NR_close,
+ "stat": C.__NR_stat,
+ "fstat": C.__NR_fstat,
+ "lstat": C.__NR_lstat,
+ "poll": C.__NR_poll,
+ "lseek": C.__NR_lseek,
+ "mmap": C.__NR_mmap,
+ "mprotect": C.__NR_mprotect,
+ "munmap": C.__NR_munmap,
+ "brk": C.__NR_brk,
+ "rt_sigaction": C.__NR_rt_sigaction,
+ "rt_sigprocmask": C.__NR_rt_sigprocmask,
+ "rt_sigreturn": C.__NR_rt_sigreturn,
+ "ioctl": C.__NR_ioctl,
+ "pread64": C.__NR_pread64,
+ "pwrite64": C.__NR_pwrite64,
+ "readv": C.__NR_readv,
+ "writev": C.__NR_writev,
+ "access": C.__NR_access,
+ "pipe": C.__NR_pipe,
+ "select": C.__NR_select,
+ "sched_yield": C.__NR_sched_yield,
+ "mremap": C.__NR_mremap,
+ "msync": C.__NR_msync,
+ "mincore": C.__NR_mincore,
+ "madvise": C.__NR_madvise,
+ "shmget": C.__NR_shmget,
+ "shmat": C.__NR_shmat,
+ "shmctl": C.__NR_shmctl,
+ "dup": C.__NR_dup,
+ "dup2": C.__NR_dup2,
+ "pause": C.__NR_pause,
+ "nanosleep": C.__NR_nanosleep,
+ "getitimer": C.__NR_getitimer,
+ "alarm": C.__NR_alarm,
+ "setitimer": C.__NR_setitimer,
+ "getpid": C.__NR_getpid,
+ "sendfile": C.__NR_sendfile,
+ "socket": C.__NR_socket,
+ "connect": C.__NR_connect,
+ "accept": C.__NR_accept,
+ "sendto": C.__NR_sendto,
+ "recvfrom": C.__NR_recvfrom,
+ "sendmsg": C.__NR_sendmsg,
+ "recvmsg": C.__NR_recvmsg,
+ "shutdown": C.__NR_shutdown,
+ "bind": C.__NR_bind,
+ "listen": C.__NR_listen,
+ "getsockname": C.__NR_getsockname,
+ "getpeername": C.__NR_getpeername,
+ "socketpair": C.__NR_socketpair,
+ "setsockopt": C.__NR_setsockopt,
+ "getsockopt": C.__NR_getsockopt,
+ "clone": C.__NR_clone,
+ "fork": C.__NR_fork,
+ "vfork": C.__NR_vfork,
+ "execve": C.__NR_execve,
+ "exit": C.__NR_exit,
+ "wait4": C.__NR_wait4,
+ "kill": C.__NR_kill,
+ "uname": C.__NR_uname,
+ "semget": C.__NR_semget,
+ "semop": C.__NR_semop,
+ "semctl": C.__NR_semctl,
+ "shmdt": C.__NR_shmdt,
+ "msgget": C.__NR_msgget,
+ "msgsnd": C.__NR_msgsnd,
+ "msgrcv": C.__NR_msgrcv,
+ "msgctl": C.__NR_msgctl,
+ "fcntl": C.__NR_fcntl,
+ "flock": C.__NR_flock,
+ "fsync": C.__NR_fsync,
+ "fdatasync": C.__NR_fdatasync,
+ "truncate": C.__NR_truncate,
+ "ftruncate": C.__NR_ftruncate,
+ "getdents": C.__NR_getdents,
+ "getcwd": C.__NR_getcwd,
+ "chdir": C.__NR_chdir,
+ "fchdir": C.__NR_fchdir,
+ "rename": C.__NR_rename,
+ "mkdir": C.__NR_mkdir,
+ "rmdir": C.__NR_rmdir,
+ "creat": C.__NR_creat,
+ "link": C.__NR_link,
+ "unlink": C.__NR_unlink,
+ "symlink": C.__NR_symlink,
+ "readlink": C.__NR_readlink,
+ "chmod": C.__NR_chmod,
+ "fchmod": C.__NR_fchmod,
+ "chown": C.__NR_chown,
+ "fchown": C.__NR_fchown,
+ "lchown": C.__NR_lchown,
+ "umask": C.__NR_umask,
+ "gettimeofday": C.__NR_gettimeofday,
+ "getrlimit": C.__NR_getrlimit,
+ "getrusage": C.__NR_getrusage,
+ "sysinfo": C.__NR_sysinfo,
+ "times": C.__NR_times,
+ "ptrace": C.__NR_ptrace,
+ "getuid": C.__NR_getuid,
+ "syslog": C.__NR_syslog,
+ "getgid": C.__NR_getgid,
+ "setuid": C.__NR_setuid,
+ "setgid": C.__NR_setgid,
+ "geteuid": C.__NR_geteuid,
+ "getegid": C.__NR_getegid,
+ "setpgid": C.__NR_setpgid,
+ "getppid": C.__NR_getppid,
+ "getpgrp": C.__NR_getpgrp,
+ "setsid": C.__NR_setsid,
+ "setreuid": C.__NR_setreuid,
+ "setregid": C.__NR_setregid,
+ "getgroups": C.__NR_getgroups,
+ "setgroups": C.__NR_setgroups,
+ "setresuid": C.__NR_setresuid,
+ "getresuid": C.__NR_getresuid,
+ "setresgid": C.__NR_setresgid,
+ "getresgid": C.__NR_getresgid,
+ "getpgid": C.__NR_getpgid,
+ "setfsuid": C.__NR_setfsuid,
+ "setfsgid": C.__NR_setfsgid,
+ "getsid": C.__NR_getsid,
+ "capget": C.__NR_capget,
+ "capset": C.__NR_capset,
+ "rt_sigpending": C.__NR_rt_sigpending,
+ "rt_sigtimedwait": C.__NR_rt_sigtimedwait,
+ "rt_sigqueueinfo": C.__NR_rt_sigqueueinfo,
+ "rt_sigsuspend": C.__NR_rt_sigsuspend,
+ "sigaltstack": C.__NR_sigaltstack,
+ "utime": C.__NR_utime,
+ "mknod": C.__NR_mknod,
+ "uselib": C.__NR_uselib,
+ "personality": C.__NR_personality,
+ "ustat": C.__NR_ustat,
+ "statfs": C.__NR_statfs,
+ "fstatfs": C.__NR_fstatfs,
+ "sysfs": C.__NR_sysfs,
+ "getpriority": C.__NR_getpriority,
+ "setpriority": C.__NR_setpriority,
+ "sched_setparam": C.__NR_sched_setparam,
+ "sched_getparam": C.__NR_sched_getparam,
+ "sched_setscheduler": C.__NR_sched_setscheduler,
+ "sched_getscheduler": C.__NR_sched_getscheduler,
+ "sched_get_priority_max": C.__NR_sched_get_priority_max,
+ "sched_get_priority_min": C.__NR_sched_get_priority_min,
+ "sched_rr_get_interval": C.__NR_sched_rr_get_interval,
+ "mlock": C.__NR_mlock,
+ "munlock": C.__NR_munlock,
+ "mlockall": C.__NR_mlockall,
+ "munlockall": C.__NR_munlockall,
+ "vhangup": C.__NR_vhangup,
+ "modify_ldt": C.__NR_modify_ldt,
+ "pivot_root": C.__NR_pivot_root,
+ "_sysctl": C.__NR__sysctl,
+ "prctl": C.__NR_prctl,
+ "arch_prctl": C.__NR_arch_prctl,
+ "adjtimex": C.__NR_adjtimex,
+ "setrlimit": C.__NR_setrlimit,
+ "chroot": C.__NR_chroot,
+ "sync": C.__NR_sync,
+ "acct": C.__NR_acct,
+ "settimeofday": C.__NR_settimeofday,
+ "mount": C.__NR_mount,
+ "umount2": C.__NR_umount2,
+ "swapon": C.__NR_swapon,
+ "swapoff": C.__NR_swapoff,
+ "reboot": C.__NR_reboot,
+ "sethostname": C.__NR_sethostname,
+ "setdomainname": C.__NR_setdomainname,
+ "iopl": C.__NR_iopl,
+ "ioperm": C.__NR_ioperm,
+ "create_module": C.__NR_create_module,
+ "init_module": C.__NR_init_module,
+ "delete_module": C.__NR_delete_module,
+ "get_kernel_syms": C.__NR_get_kernel_syms,
+ "query_module": C.__NR_query_module,
+ "quotactl": C.__NR_quotactl,
+ "nfsservctl": C.__NR_nfsservctl,
+ "getpmsg": C.__NR_getpmsg,
+ "putpmsg": C.__NR_putpmsg,
+ "afs_syscall": C.__NR_afs_syscall,
+ "tuxcall": C.__NR_tuxcall,
+ "security": C.__NR_security,
+ "gettid": C.__NR_gettid,
+ "readahead": C.__NR_readahead,
+ "setxattr": C.__NR_setxattr,
+ "lsetxattr": C.__NR_lsetxattr,
+ "fsetxattr": C.__NR_fsetxattr,
+ "getxattr": C.__NR_getxattr,
+ "lgetxattr": C.__NR_lgetxattr,
+ "fgetxattr": C.__NR_fgetxattr,
+ "listxattr": C.__NR_listxattr,
+ "llistxattr": C.__NR_llistxattr,
+ "flistxattr": C.__NR_flistxattr,
+ "removexattr": C.__NR_removexattr,
+ "lremovexattr": C.__NR_lremovexattr,
+ "fremovexattr": C.__NR_fremovexattr,
+ "tkill": C.__NR_tkill,
+ "time": C.__NR_time,
+ "futex": C.__NR_futex,
+ "sched_setaffinity": C.__NR_sched_setaffinity,
+ "sched_getaffinity": C.__NR_sched_getaffinity,
+ "set_thread_area": C.__NR_set_thread_area,
+ "io_setup": C.__NR_io_setup,
+ "io_destroy": C.__NR_io_destroy,
+ "io_getevents": C.__NR_io_getevents,
+ "io_submit": C.__NR_io_submit,
+ "io_cancel": C.__NR_io_cancel,
+ "get_thread_area": C.__NR_get_thread_area,
+ "lookup_dcookie": C.__NR_lookup_dcookie,
+ "epoll_create": C.__NR_epoll_create,
+ "epoll_ctl_old": C.__NR_epoll_ctl_old,
+ "epoll_wait_old": C.__NR_epoll_wait_old,
+ "remap_file_pages": C.__NR_remap_file_pages,
+ "getdents64": C.__NR_getdents64,
+ "set_tid_address": C.__NR_set_tid_address,
+ "restart_syscall": C.__NR_restart_syscall,
+ "semtimedop": C.__NR_semtimedop,
+ "fadvise64": C.__NR_fadvise64,
+ "timer_create": C.__NR_timer_create,
+ "timer_settime": C.__NR_timer_settime,
+ "timer_gettime": C.__NR_timer_gettime,
+ "timer_getoverrun": C.__NR_timer_getoverrun,
+ "timer_delete": C.__NR_timer_delete,
+ "clock_settime": C.__NR_clock_settime,
+ "clock_gettime": C.__NR_clock_gettime,
+ "clock_getres": C.__NR_clock_getres,
+ "clock_nanosleep": C.__NR_clock_nanosleep,
+ "exit_group": C.__NR_exit_group,
+ "epoll_wait": C.__NR_epoll_wait,
+ "epoll_ctl": C.__NR_epoll_ctl,
+ "tgkill": C.__NR_tgkill,
+ "utimes": C.__NR_utimes,
+ "vserver": C.__NR_vserver,
+ "mbind": C.__NR_mbind,
+ "set_mempolicy": C.__NR_set_mempolicy,
+ "get_mempolicy": C.__NR_get_mempolicy,
+ "mq_open": C.__NR_mq_open,
+ "mq_unlink": C.__NR_mq_unlink,
+ "mq_timedsend": C.__NR_mq_timedsend,
+ "mq_timedreceive": C.__NR_mq_timedreceive,
+ "mq_notify": C.__NR_mq_notify,
+ "mq_getsetattr": C.__NR_mq_getsetattr,
+ "kexec_load": C.__NR_kexec_load,
+ "waitid": C.__NR_waitid,
+ "add_key": C.__NR_add_key,
+ "request_key": C.__NR_request_key,
+ "keyctl": C.__NR_keyctl,
+ "ioprio_set": C.__NR_ioprio_set,
+ "ioprio_get": C.__NR_ioprio_get,
+ "inotify_init": C.__NR_inotify_init,
+ "inotify_add_watch": C.__NR_inotify_add_watch,
+ "inotify_rm_watch": C.__NR_inotify_rm_watch,
+ "migrate_pages": C.__NR_migrate_pages,
+ "openat": C.__NR_openat,
+ "mkdirat": C.__NR_mkdirat,
+ "mknodat": C.__NR_mknodat,
+ "fchownat": C.__NR_fchownat,
+ "futimesat": C.__NR_futimesat,
+ "newfstatat": C.__NR_newfstatat,
+ "unlinkat": C.__NR_unlinkat,
+ "renameat": C.__NR_renameat,
+ "linkat": C.__NR_linkat,
+ "symlinkat": C.__NR_symlinkat,
+ "readlinkat": C.__NR_readlinkat,
+ "fchmodat": C.__NR_fchmodat,
+ "faccessat": C.__NR_faccessat,
+ "pselect6": C.__NR_pselect6,
+ "ppoll": C.__NR_ppoll,
+ "unshare": C.__NR_unshare,
+ "set_robust_list": C.__NR_set_robust_list,
+ "get_robust_list": C.__NR_get_robust_list,
+ "splice": C.__NR_splice,
+ "tee": C.__NR_tee,
+ "sync_file_range": C.__NR_sync_file_range,
+ "vmsplice": C.__NR_vmsplice,
+ "move_pages": C.__NR_move_pages,
+ "utimensat": C.__NR_utimensat,
+ "epoll_pwait": C.__NR_epoll_pwait,
+ "signalfd": C.__NR_signalfd,
+ "timerfd_create": C.__NR_timerfd_create,
+ "eventfd": C.__NR_eventfd,
+ "fallocate": C.__NR_fallocate,
+ "timerfd_settime": C.__NR_timerfd_settime,
+ "timerfd_gettime": C.__NR_timerfd_gettime,
+ "accept4": C.__NR_accept4,
+ "signalfd4": C.__NR_signalfd4,
+ "eventfd2": C.__NR_eventfd2,
+ "epoll_create1": C.__NR_epoll_create1,
+ "dup3": C.__NR_dup3,
+ "pipe2": C.__NR_pipe2,
+ "inotify_init1": C.__NR_inotify_init1,
+ "preadv": C.__NR_preadv,
+ "pwritev": C.__NR_pwritev,
+ "rt_tgsigqueueinfo": C.__NR_rt_tgsigqueueinfo,
+ "perf_event_open": C.__NR_perf_event_open,
+ "recvmmsg": C.__NR_recvmmsg,
+ "fanotify_init": C.__NR_fanotify_init,
+ "fanotify_mark": C.__NR_fanotify_mark,
+ "prlimit64": C.__NR_prlimit64,
+ "name_to_handle_at": C.__NR_name_to_handle_at,
+ "open_by_handle_at": C.__NR_open_by_handle_at,
+ "clock_adjtime": C.__NR_clock_adjtime,
+ "syncfs": C.__NR_syncfs,
+ "sendmmsg": C.__NR_sendmmsg,
+ "setns": C.__NR_setns,
+ "getcpu": C.__NR_getcpu,
+ "process_vm_readv": C.__NR_process_vm_readv,
+ "process_vm_writev": C.__NR_process_vm_writev,
+ "kcmp": C.__NR_kcmp,
+ "finit_module": C.__NR_finit_module,
+ "sched_setattr": C.__NR_sched_setattr,
+ "sched_getattr": C.__NR_sched_getattr,
+ "renameat2": C.__NR_renameat2,
+ "seccomp": C.__NR_seccomp,
+ "getrandom": C.__NR_getrandom,
+ "memfd_create": C.__NR_memfd_create,
+ "kexec_file_load": C.__NR_kexec_file_load,
+ "bpf": C.__NR_bpf,
+ "execveat": C.__NR_execveat,
+}
diff --git a/src/chromiumos/seccomp/syscalls_arm.go b/src/chromiumos/seccomp/syscalls_arm.go
new file mode 100644
index 0000000..829a0ac
--- /dev/null
+++ b/src/chromiumos/seccomp/syscalls_arm.go
@@ -0,0 +1,359 @@
+// DO NOT EDIT. Autogenerated by syscalls_gen.go
+
+package seccomp
+
+// #include <asm/unistd.h>
+import "C"
+
+// syscallNum maps system call names to numbers.
+var syscallNum = map[string]int{
+ "restart_syscall": C.__NR_restart_syscall,
+ "exit": C.__NR_exit,
+ "fork": C.__NR_fork,
+ "read": C.__NR_read,
+ "write": C.__NR_write,
+ "open": C.__NR_open,
+ "close": C.__NR_close,
+ "creat": C.__NR_creat,
+ "link": C.__NR_link,
+ "unlink": C.__NR_unlink,
+ "execve": C.__NR_execve,
+ "chdir": C.__NR_chdir,
+ "mknod": C.__NR_mknod,
+ "chmod": C.__NR_chmod,
+ "lchown": C.__NR_lchown,
+ "lseek": C.__NR_lseek,
+ "getpid": C.__NR_getpid,
+ "mount": C.__NR_mount,
+ "setuid": C.__NR_setuid,
+ "getuid": C.__NR_getuid,
+ "ptrace": C.__NR_ptrace,
+ "pause": C.__NR_pause,
+ "access": C.__NR_access,
+ "nice": C.__NR_nice,
+ "sync": C.__NR_sync,
+ "kill": C.__NR_kill,
+ "rename": C.__NR_rename,
+ "mkdir": C.__NR_mkdir,
+ "rmdir": C.__NR_rmdir,
+ "dup": C.__NR_dup,
+ "pipe": C.__NR_pipe,
+ "times": C.__NR_times,
+ "brk": C.__NR_brk,
+ "setgid": C.__NR_setgid,
+ "getgid": C.__NR_getgid,
+ "geteuid": C.__NR_geteuid,
+ "getegid": C.__NR_getegid,
+ "acct": C.__NR_acct,
+ "umount2": C.__NR_umount2,
+ "ioctl": C.__NR_ioctl,
+ "fcntl": C.__NR_fcntl,
+ "setpgid": C.__NR_setpgid,
+ "umask": C.__NR_umask,
+ "chroot": C.__NR_chroot,
+ "ustat": C.__NR_ustat,
+ "dup2": C.__NR_dup2,
+ "getppid": C.__NR_getppid,
+ "getpgrp": C.__NR_getpgrp,
+ "setsid": C.__NR_setsid,
+ "sigaction": C.__NR_sigaction,
+ "setreuid": C.__NR_setreuid,
+ "setregid": C.__NR_setregid,
+ "sigsuspend": C.__NR_sigsuspend,
+ "sigpending": C.__NR_sigpending,
+ "sethostname": C.__NR_sethostname,
+ "setrlimit": C.__NR_setrlimit,
+ "getrusage": C.__NR_getrusage,
+ "gettimeofday": C.__NR_gettimeofday,
+ "settimeofday": C.__NR_settimeofday,
+ "getgroups": C.__NR_getgroups,
+ "setgroups": C.__NR_setgroups,
+ "symlink": C.__NR_symlink,
+ "readlink": C.__NR_readlink,
+ "uselib": C.__NR_uselib,
+ "swapon": C.__NR_swapon,
+ "reboot": C.__NR_reboot,
+ "munmap": C.__NR_munmap,
+ "truncate": C.__NR_truncate,
+ "ftruncate": C.__NR_ftruncate,
+ "fchmod": C.__NR_fchmod,
+ "fchown": C.__NR_fchown,
+ "getpriority": C.__NR_getpriority,
+ "setpriority": C.__NR_setpriority,
+ "statfs": C.__NR_statfs,
+ "fstatfs": C.__NR_fstatfs,
+ "syslog": C.__NR_syslog,
+ "setitimer": C.__NR_setitimer,
+ "getitimer": C.__NR_getitimer,
+ "stat": C.__NR_stat,
+ "lstat": C.__NR_lstat,
+ "fstat": C.__NR_fstat,
+ "vhangup": C.__NR_vhangup,
+ "wait4": C.__NR_wait4,
+ "swapoff": C.__NR_swapoff,
+ "sysinfo": C.__NR_sysinfo,
+ "fsync": C.__NR_fsync,
+ "sigreturn": C.__NR_sigreturn,
+ "clone": C.__NR_clone,
+ "setdomainname": C.__NR_setdomainname,
+ "uname": C.__NR_uname,
+ "adjtimex": C.__NR_adjtimex,
+ "mprotect": C.__NR_mprotect,
+ "sigprocmask": C.__NR_sigprocmask,
+ "init_module": C.__NR_init_module,
+ "delete_module": C.__NR_delete_module,
+ "quotactl": C.__NR_quotactl,
+ "getpgid": C.__NR_getpgid,
+ "fchdir": C.__NR_fchdir,
+ "bdflush": C.__NR_bdflush,
+ "sysfs": C.__NR_sysfs,
+ "personality": C.__NR_personality,
+ "setfsuid": C.__NR_setfsuid,
+ "setfsgid": C.__NR_setfsgid,
+ "_llseek": C.__NR__llseek,
+ "getdents": C.__NR_getdents,
+ "_newselect": C.__NR__newselect,
+ "flock": C.__NR_flock,
+ "msync": C.__NR_msync,
+ "readv": C.__NR_readv,
+ "writev": C.__NR_writev,
+ "getsid": C.__NR_getsid,
+ "fdatasync": C.__NR_fdatasync,
+ "_sysctl": C.__NR__sysctl,
+ "mlock": C.__NR_mlock,
+ "munlock": C.__NR_munlock,
+ "mlockall": C.__NR_mlockall,
+ "munlockall": C.__NR_munlockall,
+ "sched_setparam": C.__NR_sched_setparam,
+ "sched_getparam": C.__NR_sched_getparam,
+ "sched_setscheduler": C.__NR_sched_setscheduler,
+ "sched_getscheduler": C.__NR_sched_getscheduler,
+ "sched_yield": C.__NR_sched_yield,
+ "sched_get_priority_max": C.__NR_sched_get_priority_max,
+ "sched_get_priority_min": C.__NR_sched_get_priority_min,
+ "sched_rr_get_interval": C.__NR_sched_rr_get_interval,
+ "nanosleep": C.__NR_nanosleep,
+ "mremap": C.__NR_mremap,
+ "setresuid": C.__NR_setresuid,
+ "getresuid": C.__NR_getresuid,
+ "poll": C.__NR_poll,
+ "nfsservctl": C.__NR_nfsservctl,
+ "setresgid": C.__NR_setresgid,
+ "getresgid": C.__NR_getresgid,
+ "prctl": C.__NR_prctl,
+ "rt_sigreturn": C.__NR_rt_sigreturn,
+ "rt_sigaction": C.__NR_rt_sigaction,
+ "rt_sigprocmask": C.__NR_rt_sigprocmask,
+ "rt_sigpending": C.__NR_rt_sigpending,
+ "rt_sigtimedwait": C.__NR_rt_sigtimedwait,
+ "rt_sigqueueinfo": C.__NR_rt_sigqueueinfo,
+ "rt_sigsuspend": C.__NR_rt_sigsuspend,
+ "pread64": C.__NR_pread64,
+ "pwrite64": C.__NR_pwrite64,
+ "chown": C.__NR_chown,
+ "getcwd": C.__NR_getcwd,
+ "capget": C.__NR_capget,
+ "capset": C.__NR_capset,
+ "sigaltstack": C.__NR_sigaltstack,
+ "sendfile": C.__NR_sendfile,
+ "vfork": C.__NR_vfork,
+ "ugetrlimit": C.__NR_ugetrlimit,
+ "mmap2": C.__NR_mmap2,
+ "truncate64": C.__NR_truncate64,
+ "ftruncate64": C.__NR_ftruncate64,
+ "stat64": C.__NR_stat64,
+ "lstat64": C.__NR_lstat64,
+ "fstat64": C.__NR_fstat64,
+ "lchown32": C.__NR_lchown32,
+ "getuid32": C.__NR_getuid32,
+ "getgid32": C.__NR_getgid32,
+ "geteuid32": C.__NR_geteuid32,
+ "getegid32": C.__NR_getegid32,
+ "setreuid32": C.__NR_setreuid32,
+ "setregid32": C.__NR_setregid32,
+ "getgroups32": C.__NR_getgroups32,
+ "setgroups32": C.__NR_setgroups32,
+ "fchown32": C.__NR_fchown32,
+ "setresuid32": C.__NR_setresuid32,
+ "getresuid32": C.__NR_getresuid32,
+ "setresgid32": C.__NR_setresgid32,
+ "getresgid32": C.__NR_getresgid32,
+ "chown32": C.__NR_chown32,
+ "setuid32": C.__NR_setuid32,
+ "setgid32": C.__NR_setgid32,
+ "setfsuid32": C.__NR_setfsuid32,
+ "setfsgid32": C.__NR_setfsgid32,
+ "getdents64": C.__NR_getdents64,
+ "pivot_root": C.__NR_pivot_root,
+ "mincore": C.__NR_mincore,
+ "madvise": C.__NR_madvise,
+ "fcntl64": C.__NR_fcntl64,
+ "gettid": C.__NR_gettid,
+ "readahead": C.__NR_readahead,
+ "setxattr": C.__NR_setxattr,
+ "lsetxattr": C.__NR_lsetxattr,
+ "fsetxattr": C.__NR_fsetxattr,
+ "getxattr": C.__NR_getxattr,
+ "lgetxattr": C.__NR_lgetxattr,
+ "fgetxattr": C.__NR_fgetxattr,
+ "listxattr": C.__NR_listxattr,
+ "llistxattr": C.__NR_llistxattr,
+ "flistxattr": C.__NR_flistxattr,
+ "removexattr": C.__NR_removexattr,
+ "lremovexattr": C.__NR_lremovexattr,
+ "fremovexattr": C.__NR_fremovexattr,
+ "tkill": C.__NR_tkill,
+ "sendfile64": C.__NR_sendfile64,
+ "futex": C.__NR_futex,
+ "sched_setaffinity": C.__NR_sched_setaffinity,
+ "sched_getaffinity": C.__NR_sched_getaffinity,
+ "io_setup": C.__NR_io_setup,
+ "io_destroy": C.__NR_io_destroy,
+ "io_getevents": C.__NR_io_getevents,
+ "io_submit": C.__NR_io_submit,
+ "io_cancel": C.__NR_io_cancel,
+ "exit_group": C.__NR_exit_group,
+ "lookup_dcookie": C.__NR_lookup_dcookie,
+ "epoll_create": C.__NR_epoll_create,
+ "epoll_ctl": C.__NR_epoll_ctl,
+ "epoll_wait": C.__NR_epoll_wait,
+ "remap_file_pages": C.__NR_remap_file_pages,
+ "set_tid_address": C.__NR_set_tid_address,
+ "timer_create": C.__NR_timer_create,
+ "timer_settime": C.__NR_timer_settime,
+ "timer_gettime": C.__NR_timer_gettime,
+ "timer_getoverrun": C.__NR_timer_getoverrun,
+ "timer_delete": C.__NR_timer_delete,
+ "clock_settime": C.__NR_clock_settime,
+ "clock_gettime": C.__NR_clock_gettime,
+ "clock_getres": C.__NR_clock_getres,
+ "clock_nanosleep": C.__NR_clock_nanosleep,
+ "statfs64": C.__NR_statfs64,
+ "fstatfs64": C.__NR_fstatfs64,
+ "tgkill": C.__NR_tgkill,
+ "utimes": C.__NR_utimes,
+ "arm_fadvise64_64": C.__NR_arm_fadvise64_64,
+ "pciconfig_iobase": C.__NR_pciconfig_iobase,
+ "pciconfig_read": C.__NR_pciconfig_read,
+ "pciconfig_write": C.__NR_pciconfig_write,
+ "mq_open": C.__NR_mq_open,
+ "mq_unlink": C.__NR_mq_unlink,
+ "mq_timedsend": C.__NR_mq_timedsend,
+ "mq_timedreceive": C.__NR_mq_timedreceive,
+ "mq_notify": C.__NR_mq_notify,
+ "mq_getsetattr": C.__NR_mq_getsetattr,
+ "waitid": C.__NR_waitid,
+ "socket": C.__NR_socket,
+ "bind": C.__NR_bind,
+ "connect": C.__NR_connect,
+ "listen": C.__NR_listen,
+ "accept": C.__NR_accept,
+ "getsockname": C.__NR_getsockname,
+ "getpeername": C.__NR_getpeername,
+ "socketpair": C.__NR_socketpair,
+ "send": C.__NR_send,
+ "sendto": C.__NR_sendto,
+ "recv": C.__NR_recv,
+ "recvfrom": C.__NR_recvfrom,
+ "shutdown": C.__NR_shutdown,
+ "setsockopt": C.__NR_setsockopt,
+ "getsockopt": C.__NR_getsockopt,
+ "sendmsg": C.__NR_sendmsg,
+ "recvmsg": C.__NR_recvmsg,
+ "semop": C.__NR_semop,
+ "semget": C.__NR_semget,
+ "semctl": C.__NR_semctl,
+ "msgsnd": C.__NR_msgsnd,
+ "msgrcv": C.__NR_msgrcv,
+ "msgget": C.__NR_msgget,
+ "msgctl": C.__NR_msgctl,
+ "shmat": C.__NR_shmat,
+ "shmdt": C.__NR_shmdt,
+ "shmget": C.__NR_shmget,
+ "shmctl": C.__NR_shmctl,
+ "add_key": C.__NR_add_key,
+ "request_key": C.__NR_request_key,
+ "keyctl": C.__NR_keyctl,
+ "semtimedop": C.__NR_semtimedop,
+ "vserver": C.__NR_vserver,
+ "ioprio_set": C.__NR_ioprio_set,
+ "ioprio_get": C.__NR_ioprio_get,
+ "inotify_init": C.__NR_inotify_init,
+ "inotify_add_watch": C.__NR_inotify_add_watch,
+ "inotify_rm_watch": C.__NR_inotify_rm_watch,
+ "mbind": C.__NR_mbind,
+ "get_mempolicy": C.__NR_get_mempolicy,
+ "set_mempolicy": C.__NR_set_mempolicy,
+ "openat": C.__NR_openat,
+ "mkdirat": C.__NR_mkdirat,
+ "mknodat": C.__NR_mknodat,
+ "fchownat": C.__NR_fchownat,
+ "futimesat": C.__NR_futimesat,
+ "fstatat64": C.__NR_fstatat64,
+ "unlinkat": C.__NR_unlinkat,
+ "renameat": C.__NR_renameat,
+ "linkat": C.__NR_linkat,
+ "symlinkat": C.__NR_symlinkat,
+ "readlinkat": C.__NR_readlinkat,
+ "fchmodat": C.__NR_fchmodat,
+ "faccessat": C.__NR_faccessat,
+ "pselect6": C.__NR_pselect6,
+ "ppoll": C.__NR_ppoll,
+ "unshare": C.__NR_unshare,
+ "set_robust_list": C.__NR_set_robust_list,
+ "get_robust_list": C.__NR_get_robust_list,
+ "splice": C.__NR_splice,
+ "arm_sync_file_range": C.__NR_arm_sync_file_range,
+ "sync_file_range2": C.__NR_sync_file_range2,
+ "tee": C.__NR_tee,
+ "vmsplice": C.__NR_vmsplice,
+ "move_pages": C.__NR_move_pages,
+ "getcpu": C.__NR_getcpu,
+ "epoll_pwait": C.__NR_epoll_pwait,
+ "kexec_load": C.__NR_kexec_load,
+ "utimensat": C.__NR_utimensat,
+ "signalfd": C.__NR_signalfd,
+ "timerfd_create": C.__NR_timerfd_create,
+ "eventfd": C.__NR_eventfd,
+ "fallocate": C.__NR_fallocate,
+ "timerfd_settime": C.__NR_timerfd_settime,
+ "timerfd_gettime": C.__NR_timerfd_gettime,
+ "signalfd4": C.__NR_signalfd4,
+ "eventfd2": C.__NR_eventfd2,
+ "epoll_create1": C.__NR_epoll_create1,
+ "dup3": C.__NR_dup3,
+ "pipe2": C.__NR_pipe2,
+ "inotify_init1": C.__NR_inotify_init1,
+ "preadv": C.__NR_preadv,
+ "pwritev": C.__NR_pwritev,
+ "rt_tgsigqueueinfo": C.__NR_rt_tgsigqueueinfo,
+ "perf_event_open": C.__NR_perf_event_open,
+ "recvmmsg": C.__NR_recvmmsg,
+ "accept4": C.__NR_accept4,
+ "fanotify_init": C.__NR_fanotify_init,
+ "fanotify_mark": C.__NR_fanotify_mark,
+ "prlimit64": C.__NR_prlimit64,
+ "name_to_handle_at": C.__NR_name_to_handle_at,
+ "open_by_handle_at": C.__NR_open_by_handle_at,
+ "clock_adjtime": C.__NR_clock_adjtime,
+ "syncfs": C.__NR_syncfs,
+ "sendmmsg": C.__NR_sendmmsg,
+ "setns": C.__NR_setns,
+ "process_vm_readv": C.__NR_process_vm_readv,
+ "process_vm_writev": C.__NR_process_vm_writev,
+ "kcmp": C.__NR_kcmp,
+ "finit_module": C.__NR_finit_module,
+ "sched_setattr": C.__NR_sched_setattr,
+ "sched_getattr": C.__NR_sched_getattr,
+ "renameat2": C.__NR_renameat2,
+ "seccomp": C.__NR_seccomp,
+ "getrandom": C.__NR_getrandom,
+ "memfd_create": C.__NR_memfd_create,
+ "bpf": C.__NR_bpf,
+ "execveat": C.__NR_execveat,
+ "ARM_breakpoint": C.__ARM_NR_breakpoint,
+ "ARM_cacheflush": C.__ARM_NR_cacheflush,
+ "ARM_usr26": C.__ARM_NR_usr26,
+ "ARM_usr32": C.__ARM_NR_usr32,
+ "ARM_set_tls": C.__ARM_NR_set_tls,
+}
diff --git a/src/chromiumos/seccomp/syscalls_gen.go b/src/chromiumos/seccomp/syscalls_gen.go
new file mode 100644
index 0000000..8dc1cbc
--- /dev/null
+++ b/src/chromiumos/seccomp/syscalls_gen.go
@@ -0,0 +1,61 @@
+// Copyright 2015 The Chromium OS Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// +build ignore
+
+// syscalls_gen processes system headers and generates a mapping from system call names to numbers.
+// Usage:
+// $ echo "#include <asm/unistd.h>" | x86_64-cros-linux-gnu-gcc -E -dD - | go run syscalls_gen.go | gofmt > syscalls_amd64.go
+// $ echo "#include <asm/unistd.h>" | i686-pc-linux-gnu-gcc -E -dD - | go run syscalls_gen.go | gofmt > syscalls_386.go
+// $ echo "#include <asm/unistd.h>" | armv7a-cros-linux-gnueabi-gcc -E -dD - | go run syscalls_gen.go | gofmt > syscalls_arm.go
+package main
+
+import (
+ "bufio"
+ "fmt"
+ "log"
+ "os"
+ "regexp"
+)
+
+func main() {
+ type syscall struct {
+ prefix string
+ name string
+ }
+
+ define := regexp.MustCompile(`^#define __([A-Z]+_)?NR_([a-z0-9_]+)`)
+ undef := regexp.MustCompile(`^#undef __([A-Z]+_)?NR_([a-z0-9_]+)`)
+
+ defined := []syscall{}
+ undefed := map[syscall]bool{}
+
+ scanner := bufio.NewScanner(os.Stdin)
+ for scanner.Scan() {
+ line := scanner.Text()
+ if match := define.FindStringSubmatch(line); match != nil {
+ defined = append(defined, syscall{match[1], match[2]})
+ }
+ if match := undef.FindStringSubmatch(line); match != nil {
+ undefed[syscall{match[1], match[2]}] = true
+ }
+ }
+ if err := scanner.Err(); err != nil {
+ log.Fatalf("Error reading standard input: %v", err)
+ }
+
+ fmt.Println("// DO NOT EDIT. Autogenerated by syscalls_gen.go")
+ fmt.Println()
+ fmt.Println("package seccomp")
+ fmt.Println("// #include <asm/unistd.h>")
+ fmt.Println("import \"C\"")
+ fmt.Println("// syscallNum maps system call names to numbers.")
+ fmt.Println("var syscallNum = map[string]int{")
+ for _, call := range defined {
+ if !undefed[call] {
+ fmt.Printf("%q: C.__%sNR_%s,\n", call.prefix+call.name, call.prefix, call.name)
+ }
+ }
+ fmt.Println("}")
+}