execute: support syscall filtering using seccomp filters

This commit is contained in:
Lennart Poettering 2012-07-17 04:17:53 +02:00
parent cd96b3b86a
commit 8351ceaea9
19 changed files with 517 additions and 14 deletions

View File

@ -961,11 +961,15 @@ libsystemd_core_la_SOURCES = \
src/core/switch-root.h \
src/core/switch-root.c \
src/core/killall.h \
src/core/killall.c
src/core/killall.c \
src/core/syscall-list.c \
src/core/syscall-list.h
nodist_libsystemd_core_la_SOURCES = \
src/core/load-fragment-gperf.c \
src/core/load-fragment-gperf-nulstr.c
src/core/load-fragment-gperf-nulstr.c \
src/core/syscall-from-name.h \
src/core/syscall-to-name.h
libsystemd_core_la_CFLAGS = \
$(AM_CFLAGS) \
@ -998,7 +1002,23 @@ EXTRA_DIST += \
CLEANFILES += \
src/core/load-fragment-gperf.gperf \
src/core/load-fragment-gperf.c \
src/core/load-fragment-gperf-nulstr.c
src/core/load-fragment-gperf-nulstr.c \
src/core/syscall-list.txt \
src/core/syscall-from-name.gperf \
src/core/syscall-from-name.h \
src/core/syscall-to-name.h
src/core/syscall-list.txt: Makefile
$(AM_V_GEN)cpp -dM -include sys/syscall.h < /dev/null | $(AWK) '/^#define[ \t]+__NR_[^ ]+[ \t]+[0-9]/ { sub(/__NR_/, "", $$2); print $$2; }' > $@ || rm $@
src/core/syscall-from-name.gperf: src/core/syscall-list.txt Makefile
$(AM_V_GEN)$(AWK) 'BEGIN{ print "struct syscall_name { const char* name; int id; };"; print "%null-strings"; print "%%";} { printf "%s, __NR_%s\n", $$1, $$1 }' < $< > $@
src/core/syscall-from-name.h: src/core/syscall-from-name.gperf Makefile
$(AM_V_GEN)$(GPERF) -L ANSI-C -t --ignore-case -N lookup_syscall -H hash_syscall_name -p -C < $< > $@
src/core/syscall-to-name.h: src/core/syscall-list.txt Makefile
$(AM_V_GEN)$(AWK) 'BEGIN{ print "const char* const syscall_names[] = { "} { printf "[__NR_%s] = \"%s\",\n", $$1, $$1 } END{print "};"}' < $< > $@
# ------------------------------------------------------------------------------
systemd_SOURCES = \

9
TODO
View File

@ -33,12 +33,13 @@ Bugfixes:
Jul 09 18:22:37 mop [21866]: Process 21865 (systemd) dumped core.
Features:
* use cpp -dM for key mapping too?
* change mount access mode of 0700 or so for debugfs?
* logind: wakelock/opportunistic suspend support
* seccomp filters for services
* switch-root: sockets need relabelling
* segfault in journalctl during /var migration
@ -60,8 +61,6 @@ Features:
* load-fragment: when loading a unit file via a chain of symlinks
verify that it isn't masked via any of the names traversed.
* journald: _BOOT_ID triggers too many collisions.
* journald: we currently rotate only after MaxUse+MaxFilesize has been reached.
* nspawn: bind mount /var/log/journal from the host
@ -236,8 +235,6 @@ Features:
* write RPM spec macros for presets
* journal: extend hash tables as we go
* journal: API for looking for retrieving "all values of this field"
* journal: deal nicely with byte-by-byte copied files, especially regards header

View File

@ -1091,6 +1091,54 @@
shell pipelines.</para></listitem>
</varlistentry>
<varlistentry>
<term><varname>NoNewPrivileges=</varname></term>
<listitem><para>Takes a boolean
argument. If true ensures that the
service process and all its children
can never gain new privileges. This
option is more powerful than the respective
secure bits flags (see above), as it
also prohibits UID changes of any
kind. This is the simplest, most
effective way to ensure that a process
and its children can never elevate
privileges again.</para></listitem>
</varlistentry>
<varlistentry>
<term><varname>SystemCallFilter=</varname></term>
<listitem><para>Takes a space
separated list of system call
names. If this setting is used all
system calls executed by the unit
process except for the listed ones
will result in immediate process
termination with the SIGSYS signal
(whitelisting). If the first character
of the list is <literal>~</literal>
the effect is inverted: only the
listed system calls will result in
immediate process termination
(blacklisting). If this option is used
<varname>NoNewPrivileges=yes</varname>
is implied. This feature makes use of
the Secure Computing Mode 2 interfaces
of the kernel ('seccomp filtering')
and is useful for enforcing a minimal
sandboxing environment. Note that the
<function>execve</function>,
<function>rt_sigreturn</function>,
<function>sigreturn</function>,
<function>exit_group</function>,
<function>exit</function> system calls
are implicitly whitelisted and don't
need to be listed
explicitly.</para></listitem>
</varlistentry>
</variablelist>
</refsect1>

4
src/core/.gitignore vendored
View File

@ -1,2 +1,6 @@
/syscall-from-name.gperf
/syscall-from-name.h
/syscall-list.txt
/syscall-to-name.h
/macros.systemd
/systemd.pc

View File

@ -28,6 +28,7 @@
#include "ioprio.h"
#include "strv.h"
#include "dbus-common.h"
#include "syscall-list.h"
DEFINE_BUS_PROPERTY_APPEND_ENUM(bus_execute_append_kill_mode, kill_mode, KillMode);
@ -348,6 +349,32 @@ int bus_execute_append_command(DBusMessageIter *i, const char *property, void *d
return 0;
}
int bus_execute_append_syscall_filter(DBusMessageIter *i, const char *property, void *data) {
ExecContext *c = data;
dbus_bool_t b;
DBusMessageIter sub;
assert(i);
assert(property);
assert(c);
if (!dbus_message_iter_open_container(i, DBUS_TYPE_ARRAY, "u", &sub))
return -ENOMEM;
if (c->syscall_filter)
b = dbus_message_iter_append_fixed_array(&sub, DBUS_TYPE_UINT32, &c->syscall_filter, (syscall_max() + 31) >> 4);
else
b = dbus_message_iter_append_fixed_array(&sub, DBUS_TYPE_UINT32, &c->syscall_filter, 0);
if (!b)
return -ENOMEM;
if (!dbus_message_iter_close_container(i, &sub))
return -ENOMEM;
return 0;
}
const BusProperty bus_exec_context_properties[] = {
{ "Environment", bus_property_append_strv, "as", offsetof(ExecContext, environment), true },
{ "EnvironmentFiles", bus_execute_append_env_files, "a(sb)", offsetof(ExecContext, environment_files), true },
@ -409,6 +436,8 @@ const BusProperty bus_exec_context_properties[] = {
{ "UtmpIdentifier", bus_property_append_string, "s", offsetof(ExecContext, utmp_id), true },
{ "ControlGroupModify", bus_property_append_bool, "b", offsetof(ExecContext, control_group_modify) },
{ "ControlGroupPersistent", bus_property_append_tristate_false, "b", offsetof(ExecContext, control_group_persistent) },
{ "IgnoreSIGPIPE", bus_property_append_bool, "b", offsetof(ExecContext, ignore_sigpipe ) },
{ "IgnoreSIGPIPE", bus_property_append_bool, "b", offsetof(ExecContext, ignore_sigpipe) },
{ "NoNewPrivileges", bus_property_append_bool, "b", offsetof(ExecContext, no_new_privileges) },
{ "SystemCallFilter", bus_execute_append_syscall_filter, "au", 0 },
{ NULL, }
};

View File

@ -96,7 +96,9 @@
" <property name=\"ControlGroupModify\" type=\"b\" access=\"read\"/>\n" \
" <property name=\"ControlGroupPersistent\" type=\"b\" access=\"read\"/>\n" \
" <property name=\"PrivateNetwork\" type=\"b\" access=\"read\"/>\n" \
" <property name=\"IgnoreSIGPIPE\" type=\"b\" access=\"read\"/>\n"
" <property name=\"IgnoreSIGPIPE\" type=\"b\" access=\"read\"/>\n" \
" <property name=\"NoNewPrivileges\" type=\"b\" access=\"read\"/>\n" \
" <property name=\"SystemCallFilter\" type=\"au\" access=\"read\"/>\n"
#define BUS_EXEC_COMMAND_INTERFACE(name) \
" <property name=\"" name "\" type=\"a(sasbttuii)\" access=\"read\"/>\n"
@ -121,5 +123,6 @@ int bus_execute_append_rlimits(DBusMessageIter *i, const char *property, void *d
int bus_execute_append_command(DBusMessageIter *u, const char *property, void *data);
int bus_execute_append_kill_mode(DBusMessageIter *i, const char *property, void *data);
int bus_execute_append_env_files(DBusMessageIter *i, const char *property, void *data);
int bus_execute_append_syscall_filter(DBusMessageIter *i, const char *property, void *data);
#endif

View File

@ -38,6 +38,7 @@
#include <linux/fs.h>
#include <linux/oom.h>
#include <sys/poll.h>
#include <linux/seccomp-bpf.h>
#ifdef HAVE_PAM
#include <security/pam_appl.h>
@ -60,6 +61,7 @@
#include "def.h"
#include "loopback-setup.h"
#include "path-util.h"
#include "syscall-list.h"
#define IDLE_TIMEOUT_USEC (5*USEC_PER_SEC)
@ -924,6 +926,59 @@ static void rename_process_from_path(const char *path) {
rename_process(process_name);
}
static int apply_seccomp(uint32_t *syscall_filter) {
static const struct sock_filter header[] = {
VALIDATE_ARCHITECTURE,
EXAMINE_SYSCALL
};
static const struct sock_filter footer[] = {
_KILL_PROCESS
};
int i;
unsigned n;
struct sock_filter *f;
struct sock_fprog prog;
assert(syscall_filter);
/* First: count the syscalls to check for */
for (i = 0, n = 0; i < syscall_max(); i++)
if (syscall_filter[i >> 4] & (1 << (i & 31)))
n++;
/* Second: build the filter program from a header the syscall
* matches and the footer */
f = alloca(sizeof(struct sock_filter) * (ELEMENTSOF(header) + 2*n + ELEMENTSOF(footer)));
memcpy(f, header, sizeof(header));
for (i = 0, n = 0; i < syscall_max(); i++)
if (syscall_filter[i >> 4] & (1 << (i & 31))) {
struct sock_filter item[] = {
BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, i, 0, 1),
BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_ALLOW)
};
assert_cc(ELEMENTSOF(item) == 2);
f[ELEMENTSOF(header) + 2*n] = item[0];
f[ELEMENTSOF(header) + 2*n+1] = item[1];
n++;
}
memcpy(f + (ELEMENTSOF(header) + 2*n), footer, sizeof(footer));
/* Third: install the filter */
zero(prog);
prog.len = ELEMENTSOF(header) + ELEMENTSOF(footer) + 2*n;
prog.filter = f;
if (prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog) < 0)
return -errno;
return 0;
}
int exec_spawn(ExecCommand *command,
char **argv,
const ExecContext *context,
@ -1355,6 +1410,21 @@ int exec_spawn(ExecCommand *command,
r = EXIT_CAPABILITIES;
goto fail_child;
}
if (context->no_new_privileges)
if (prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0) < 0) {
err = -errno;
r = EXIT_NO_NEW_PRIVILEGES;
goto fail_child;
}
if (context->syscall_filter) {
err = apply_seccomp(context->syscall_filter);
if (err < 0) {
r = EXIT_SECCOMP;
goto fail_child;
}
}
}
if (!(our_env = new0(char*, 7))) {

View File

@ -164,6 +164,8 @@ struct ExecContext {
bool private_tmp;
bool private_network;
bool no_new_privileges;
bool control_group_modify;
int control_group_persistent;
@ -174,6 +176,8 @@ struct ExecContext {
* don't enter a trigger loop. */
bool same_pgrp;
uint32_t *syscall_filter;
bool oom_score_adjust_set:1;
bool nice_set:1;
bool ioprio_set:1;

View File

@ -48,6 +48,8 @@ $1.Capabilities, config_parse_exec_capabilities, 0,
$1.SecureBits, config_parse_exec_secure_bits, 0, offsetof($1, exec_context)
$1.CapabilityBoundingSet, config_parse_bounding_set, 0, offsetof($1, exec_context.capability_bounding_set_drop)
$1.TimerSlackNSec, config_parse_nsec, 0, offsetof($1, exec_context.timer_slack_nsec)
$1.NoNewPrivileges config_parse_bool, 0, offsetof($1, exec_context.no_new_privileges)
$1.SystemCallFilter, config_parse_syscall_filter, 0, offsetof($1, exec_context)
$1.LimitCPU, config_parse_limit, RLIMIT_CPU, offsetof($1, exec_context.rlimit)
$1.LimitFSIZE, config_parse_limit, RLIMIT_FSIZE, offsetof($1, exec_context.rlimit)
$1.LimitDATA, config_parse_limit, RLIMIT_DATA, offsetof($1, exec_context.rlimit)

View File

@ -45,6 +45,7 @@
#include "bus-errors.h"
#include "utf8.h"
#include "path-util.h"
#include "syscall-list.h"
#ifndef HAVE_SYSV_COMPAT
int config_parse_warn_compat(
@ -879,7 +880,7 @@ int config_parse_bounding_set(
if (r < 0) {
log_error("[%s:%u] Failed to parse capability bounding set, ignoring: %s", filename, line, rvalue);
return 0;
continue;
}
sum |= ((uint64_t) 1ULL) << (uint64_t) cap;
@ -2001,6 +2002,88 @@ int config_parse_documentation(
return r;
}
static void syscall_set(uint32_t *p, int nr) {
p[nr >> 4] |= 1 << (nr & 31);
}
static void syscall_unset(uint32_t *p, int nr) {
p[nr >> 4] &= ~(1 << (nr & 31));
}
int config_parse_syscall_filter(
const char *filename,
unsigned line,
const char *section,
const char *lvalue,
int ltype,
const char *rvalue,
void *data,
void *userdata) {
ExecContext *c = data;
Unit *u = userdata;
bool invert;
char *w;
size_t l;
char *state;
assert(filename);
assert(lvalue);
assert(rvalue);
assert(u);
if (rvalue[0] == '~') {
invert = true;
rvalue++;
}
if (!c->syscall_filter) {
size_t n;
n = (syscall_max() + 31) >> 4;
c->syscall_filter = new(uint32_t, n);
if (!c->syscall_filter)
return -ENOMEM;
memset(c->syscall_filter, invert ? 0xFF : 0, n * sizeof(uint32_t));
/* Add these by default */
syscall_set(c->syscall_filter, __NR_execve);
syscall_set(c->syscall_filter, __NR_rt_sigreturn);
#ifdef __NR_sigreturn
syscall_set(c->syscall_filter, __NR_sigreturn);
#endif
syscall_set(c->syscall_filter, __NR_exit_group);
syscall_set(c->syscall_filter, __NR_exit);
}
FOREACH_WORD_QUOTED(w, l, rvalue, state) {
int id;
char *t;
t = strndup(w, l);
if (!t)
return -ENOMEM;
id = syscall_from_name(t);
free(t);
if (id < 0) {
log_error("[%s:%u] Failed to parse syscall, ignoring: %s", filename, line, rvalue);
continue;
}
if (invert)
syscall_unset(c->syscall_filter, id);
else
syscall_set(c->syscall_filter, id);
}
c->no_new_privileges = true;
return 0;
}
#define FOLLOW_MAX 8
static int open_follow(char **filename, FILE **_f, Set *names, char **_final) {

View File

@ -82,6 +82,7 @@ int config_parse_unit_device_allow(const char *filename, unsigned line, const ch
int config_parse_unit_blkio_weight(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
int config_parse_unit_blkio_bandwidth(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
int config_parse_unit_requires_mounts_for(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
int config_parse_syscall_filter(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
/* gperf prototypes */
const struct ConfigPerfItem* load_fragment_gperf_lookup(const char *key, unsigned length);

55
src/core/syscall-list.c Normal file
View File

@ -0,0 +1,55 @@
/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
/***
This file is part of systemd.
Copyright 2012 Lennart Poettering
systemd is free software; you can redistribute it and/or modify it
under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version.
systemd is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
#include <sys/syscall.h>
#include <string.h>
#include "util.h"
#include "syscall-list.h"
const struct syscall_name *lookup_syscall(register const char *str, register unsigned int len);
#include "syscall-to-name.h"
#include "syscall-from-name.h"
const char *syscall_to_name(int id) {
if (id < 0 || id >= (int) ELEMENTSOF(syscall_names))
return NULL;
return syscall_names[id];
}
int syscall_from_name(const char *name) {
const struct syscall_name *sc;
assert(name);
sc = lookup_syscall(name, strlen(name));
if (!sc)
return -1;
return sc->id;
}
int syscall_max(void) {
return ELEMENTSOF(syscall_names);
}

30
src/core/syscall-list.h Normal file
View File

@ -0,0 +1,30 @@
/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
#ifndef foosyscalllisthfoo
#define foosyscalllisthfoo
/***
This file is part of systemd.
Copyright 2012 Lennart Poettering
systemd is free software; you can redistribute it and/or modify it
under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version.
systemd is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
const char *syscall_to_name(int id);
int syscall_from_name(const char *name);
int syscall_max(void);
#endif

View File

@ -1082,6 +1082,29 @@ int generic_print_property(const char *name, DBusMessageIter *iter, bool all) {
puts("");
}
return 1;
} else if (dbus_message_iter_get_element_type(iter) == DBUS_TYPE_UINT32) {
DBusMessageIter sub;
dbus_message_iter_recurse(iter, &sub);
if (all ||
dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_INVALID) {
printf("%s=", name);
while (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_INVALID) {
uint32_t u;
assert(dbus_message_iter_get_arg_type(&sub) == DBUS_TYPE_UINT32);
dbus_message_iter_get_basic(&sub, &u);
printf("%08x", u);
dbus_message_iter_next(&sub);
}
puts("");
}
return 1;
}

View File

@ -122,6 +122,12 @@ const char* exit_status_to_string(ExitStatus status, ExitStatusLevel level) {
case EXIT_NAMESPACE:
return "NAMESPACE";
case EXIT_NO_NEW_PRIVILEGES:
return "NO_NEW_PRIVILEGES";
case EXIT_SECCOMP:
return "SECCOMP";
}
}

View File

@ -66,8 +66,9 @@ typedef enum ExitStatus {
EXIT_TCPWRAP,
EXIT_PAM,
EXIT_NETWORK,
EXIT_NAMESPACE
EXIT_NAMESPACE,
EXIT_NO_NEW_PRIVILEGES,
EXIT_SECCOMP
} ExitStatus;
typedef enum ExitStatusLevel {

View File

@ -0,0 +1,76 @@
/*
* seccomp example for x86 (32-bit and 64-bit) with BPF macros
*
* Copyright (c) 2012 The Chromium OS Authors <chromium-os-dev@chromium.org>
* Authors:
* Will Drewry <wad@chromium.org>
* Kees Cook <keescook@chromium.org>
*
* The code may be used by anyone for any purpose, and can serve as a
* starting point for developing applications using mode 2 seccomp.
*/
#ifndef _SECCOMP_BPF_H_
#define _SECCOMP_BPF_H_
#include <stdio.h>
#include <stddef.h>
#include <stdlib.h>
#include <errno.h>
#include <signal.h>
#include <string.h>
#include <unistd.h>
#include <sys/prctl.h>
#include <linux/unistd.h>
#include <linux/audit.h>
#include <linux/filter.h>
#include <linux/seccomp.h>
#ifndef SECCOMP_MODE_FILTER
# define SECCOMP_MODE_FILTER 2 /* uses user-supplied filter. */
# define SECCOMP_RET_KILL 0x00000000U /* kill the task immediately */
# define SECCOMP_RET_TRAP 0x00030000U /* disallow and force a SIGSYS */
# define SECCOMP_RET_ALLOW 0x7fff0000U /* allow */
struct seccomp_data {
int nr;
__u32 arch;
__u64 instruction_pointer;
__u64 args[6];
};
#endif
#ifndef SYS_SECCOMP
# define SYS_SECCOMP 1
#endif
#define syscall_nr (offsetof(struct seccomp_data, nr))
#define arch_nr (offsetof(struct seccomp_data, arch))
#if defined(__i386__)
# define REG_SYSCALL REG_EAX
# define ARCH_NR AUDIT_ARCH_I386
#elif defined(__x86_64__)
# define REG_SYSCALL REG_RAX
# define ARCH_NR AUDIT_ARCH_X86_64
#else
# warning "Platform does not support seccomp filter yet"
# define REG_SYSCALL 0
# define ARCH_NR 0
#endif
#define VALIDATE_ARCHITECTURE \
BPF_STMT(BPF_LD+BPF_W+BPF_ABS, arch_nr), \
BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, ARCH_NR, 1, 0), \
BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_KILL)
#define EXAMINE_SYSCALL \
BPF_STMT(BPF_LD+BPF_W+BPF_ABS, syscall_nr)
#define ALLOW_SYSCALL(name) \
BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, __NR_##name, 0, 1), \
BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_ALLOW)
#define _KILL_PROCESS \
BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_KILL)
#endif /* _SECCOMP_BPF_H_ */

View File

@ -0,0 +1,47 @@
#ifndef _LINUX_SECCOMP_H
#define _LINUX_SECCOMP_H
#include <linux/types.h>
/* Valid values for seccomp.mode and prctl(PR_SET_SECCOMP, <mode>) */
#define SECCOMP_MODE_DISABLED 0 /* seccomp is not in use. */
#define SECCOMP_MODE_STRICT 1 /* uses hard-coded filter. */
#define SECCOMP_MODE_FILTER 2 /* uses user-supplied filter. */
/*
* All BPF programs must return a 32-bit value.
* The bottom 16-bits are for optional return data.
* The upper 16-bits are ordered from least permissive values to most.
*
* The ordering ensures that a min_t() over composed return values always
* selects the least permissive choice.
*/
#define SECCOMP_RET_KILL 0x00000000U /* kill the task immediately */
#define SECCOMP_RET_TRAP 0x00030000U /* disallow and force a SIGSYS */
#define SECCOMP_RET_ERRNO 0x00050000U /* returns an errno */
#define SECCOMP_RET_TRACE 0x7ff00000U /* pass to a tracer or disallow */
#define SECCOMP_RET_ALLOW 0x7fff0000U /* allow */
/* Masks for the return value sections. */
#define SECCOMP_RET_ACTION 0x7fff0000U
#define SECCOMP_RET_DATA 0x0000ffffU
/**
* struct seccomp_data - the format the BPF program executes over.
* @nr: the system call number
* @arch: indicates system call convention as an AUDIT_ARCH_* value
* as defined in <linux/audit.h>.
* @instruction_pointer: at the time of the system call.
* @args: up to 6 system call arguments always stored as 64-bit values
* regardless of the architecture.
*/
struct seccomp_data {
int nr;
__u32 arch;
__u64 instruction_pointer;
__u64 args[6];
};
#endif /* _LINUX_SECCOMP_H */

View File

@ -188,4 +188,8 @@ static inline pid_t gettid(void) {
#define MS_STRICTATIME (1<<24)
#endif
#ifndef PR_SET_NO_NEW_PRIVS
#define PR_SET_NO_NEW_PRIVS 38
#endif
#endif