summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--README3
-rw-r--r--configure.ac2
-rw-r--r--include/seccomp.h.in72
-rw-r--r--src/Makefile.am6
-rw-r--r--src/api.c11
-rw-r--r--src/arch-aarch64-syscalls.c10
-rw-r--r--src/arch-arm-syscalls.c12
-rw-r--r--src/arch-mips-syscalls.c10
-rw-r--r--src/arch-mips64-syscalls.c10
-rw-r--r--src/arch-mips64n32-syscalls.c10
-rw-r--r--src/arch-ppc-syscalls.c510
-rw-r--r--src/arch-ppc.c33
-rw-r--r--src/arch-ppc.h38
-rw-r--r--src/arch-ppc64-syscalls.c510
-rw-r--r--src/arch-ppc64.c40
-rw-r--r--src/arch-ppc64.h39
-rw-r--r--src/arch-s390-syscalls.c10
-rw-r--r--src/arch-s390x-syscalls.c10
-rw-r--r--src/arch-syscall-check.c28
-rw-r--r--src/arch-syscall-dump.c13
-rwxr-xr-xsrc/arch-syscall-validate77
-rw-r--r--src/arch-x32-syscalls.c10
-rw-r--r--src/arch-x86-syscalls.c10
-rw-r--r--src/arch-x86.c29
-rw-r--r--src/arch-x86.h2
-rw-r--r--src/arch-x86_64-syscalls.c10
-rw-r--r--src/arch.c62
-rw-r--r--src/arch.h3
-rw-r--r--src/db.c5
-rw-r--r--src/db.h5
-rw-r--r--src/gen_bpf.c1
-rw-r--r--src/python/libseccomp.pxd3
-rw-r--r--src/python/seccomp.pyx11
-rw-r--r--tests/.gitignore2
-rw-r--r--tests/12-sim-basic_masked_ops.tests61
-rw-r--r--tests/16-sim-arch_basic.c3
-rwxr-xr-xtests/16-sim-arch_basic.py1
-rw-r--r--tests/23-sim-arch_all_le_basic.c3
-rwxr-xr-xtests/23-sim-arch_all_le_basic.py1
-rw-r--r--tests/26-sim-arch_all_be_basic.c6
-rwxr-xr-xtests/26-sim-arch_all_be_basic.py2
-rw-r--r--tests/29-sim-pseudo_syscall.c71
-rw-r--r--tests/29-sim-pseudo_syscall.py51
-rw-r--r--tests/29-sim-pseudo_syscall.tests23
-rw-r--r--tests/Makefile.am12
-rw-r--r--tests/miniseq.c57
-rwxr-xr-xtests/regression60
-rw-r--r--tools/scmp_arch_detect.c9
-rw-r--r--tools/scmp_bpf_disasm.c308
-rw-r--r--tools/scmp_bpf_sim.c24
-rw-r--r--tools/util.c24
-rw-r--r--tools/util.h11
52 files changed, 2112 insertions, 222 deletions
diff --git a/README b/README
index a469e96..6987b5f 100644
--- a/README
+++ b/README
@@ -18,7 +18,8 @@ The project mailing list is currently hosted on Google Groups at the URL below,
please note that a Google account is not required to subscribe to the mailing
list.
- -> https://groups.google.com/d/forum/libseccomp
+ -> https://groups.google.com/forum/#!forum/libseccomp
+ -> https://groups.google.com/forum/#!forum/libseccomp/join
* Documentation
diff --git a/configure.ac b/configure.ac
index 357cf87..75f721e 100644
--- a/configure.ac
+++ b/configure.ac
@@ -121,7 +121,7 @@ AS_IF([test "$enable_python" = yes], [
])
AM_CONDITIONAL([ENABLE_PYTHON], [test "$enable_python" = yes])
AC_DEFINE_UNQUOTED([ENABLE_PYTHON],
- [$(test "$enable_python" == yes && echo 1 || echo 0)],
+ [$(test "$enable_python" = yes && echo 1 || echo 0)],
[Python bindings build flag.])
dnl ####
diff --git a/include/seccomp.h.in b/include/seccomp.h.in
index 907fe67..adab19a 100644
--- a/include/seccomp.h.in
+++ b/include/seccomp.h.in
@@ -163,13 +163,19 @@ struct scmp_arg_cmp {
#define SCMP_ARCH_MIPSEL64N32 AUDIT_ARCH_MIPSEL64N32
/**
- * The S390 architecture token
+ * The PowerPC architecture tokens
*/
-#define SCMP_ARCH_S390 AUDIT_ARCH_S390
+#define SCMP_ARCH_PPC AUDIT_ARCH_PPC
+#define SCMP_ARCH_PPC64 AUDIT_ARCH_PPC64
+#ifndef AUDIT_ARCH_PPC64LE
+#define AUDIT_ARCH_PPC64LE (EM_PPC64|__AUDIT_ARCH_64BIT|__AUDIT_ARCH_LE)
+#endif
+#define SCMP_ARCH_PPC64LE AUDIT_ARCH_PPC64LE
/**
- * The S390X architecture token
+ * The S390 architecture tokens
*/
+#define SCMP_ARCH_S390 AUDIT_ARCH_S390
#define SCMP_ARCH_S390X AUDIT_ARCH_S390X
/**
@@ -1486,29 +1492,69 @@ int seccomp_export_bpf(const scmp_filter_ctx ctx, int fd);
#define __NR_usr32 __PNR_usr32
#endif /* __ARM_NR_usr32 */
-#define __PNR_get_mempolicy -10180
+#define __PNR_multiplexer -10186
+#ifndef __NR_multiplexer
+#define __NR_multiplexer __PNR_multiplexer
+#endif /* __NR_multiplexer */
+
+#define __PNR_rtas -10187
+#ifndef __NR_rtas
+#define __NR_rtas __PNR_rtas
+#endif /* __NR_rtas */
+
+#define __PNR_spu_create -10188
+#ifndef __NR_spu_create
+#define __NR_spu_create __PNR_spu_create
+#endif /* __NR_spu_create */
+
+#define __PNR_spu_run -10189
+#ifndef __NR_spu_run
+#define __NR_spu_run __PNR_spu_run
+#endif /* __NR_spu_run */
+
+#define __PNR_subpage_prot -10189
+#ifndef __NR_subpage_prot
+#define __NR_subpage_prot __PNR_subpage_prot
+#endif /* __NR_subpage_prot */
+
+#define __PNR_swapcontext -10190
+#ifndef __NR_swapcontext
+#define __NR_swapcontext __PNR_swapcontext
+#endif /* __NR_swapcontext */
+
+#define __PNR_sys_debug_setcontext -10191
+#ifndef __NR_sys_debug_setcontext
+#define __NR_sys_debug_setcontext __PNR_sys_debug_setcontext
+#endif /* __NR_sys_debug_setcontext */
+
+#define __PNR_switch_endian -10191
+#ifndef __NR_switch_endian
+#define __NR_switch_endian __PNR_switch_endian
+#endif /* __NR_switch_endian */
+
+#define __PNR_get_mempolicy -10192
#ifndef __NR_get_mempolicy
-#define __NR_get_mempolicy __PNR_get_mempolicy
+#define __NR_get_mempolicy __PNR_get_mempolicy
#endif /* __NR_get_mempolicy */
-#define __PNR_move_pages -10181
+#define __PNR_move_pages -10193
#ifndef __NR_move_pages
-#define __NR_move_pages __PNR_move_pages
+#define __NR_move_pages __PNR_move_pages
#endif /* __NR_move_pages */
-#define __PNR_mbind -10182
+#define __PNR_mbind -10194
#ifndef __NR_mbind
-#define __NR_mbind __PNR_mbind
+#define __NR_mbind __PNR_mbind
#endif /* __NR_mbind */
-#define __PNR_set_mempolicy -10183
+#define __PNR_set_mempolicy -10195
#ifndef __NR_set_mempolicy
-#define __NR_set_mempolicy __PNR_set_mempolicy
+#define __NR_set_mempolicy __PNR_set_mempolicy
#endif /* __NR_set_mempolicy */
-#define __PNR_s390_runtime_instr -10184
+#define __PNR_s390_runtime_instr -10196
#ifndef __NR_s390_runtime_instr
-#define __NR_s390_runtime_instr __PNR_s390_runtime_instr
+#define __NR_s390_runtime_instr __PNR_s390_runtime_instr
#endif /* __NR_s390_runtime_instr */
#ifdef __cplusplus
diff --git a/src/Makefile.am b/src/Makefile.am
index f5ce997..ba9b9f4 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -31,8 +31,10 @@ SOURCES_ARCH = \
arch-mips.h arch-mips.c arch-mips-syscalls.c \
arch-mips64.h arch-mips64.c arch-mips64-syscalls.c \
arch-mips64n32.h arch-mips64n32.c arch-mips64n32-syscalls.c \
- arch-s390x.h arch-s390x.c arch-s390x-syscalls.c \
- arch-s390.h arch-s390.c arch-s390-syscalls.c
+ arch-ppc.h arch-ppc.c arch-ppc-syscalls.c \
+ arch-ppc64.h arch-ppc64.c arch-ppc64-syscalls.c \
+ arch-s390.h arch-s390.c arch-s390-syscalls.c \
+ arch-s390x.h arch-s390x.c arch-s390x-syscalls.c
SOURCES_GEN = \
api.c system.h system.c \
diff --git a/src/api.c b/src/api.c
index 182b896..0cfa407 100644
--- a/src/api.c
+++ b/src/api.c
@@ -298,6 +298,7 @@ API int seccomp_syscall_resolve_name_arch(uint32_t arch_token, const char *name)
API int seccomp_syscall_resolve_name_rewrite(uint32_t arch_token,
const char *name)
{
+ int rc;
int syscall;
const struct arch_def *arch;
@@ -315,7 +316,11 @@ API int seccomp_syscall_resolve_name_rewrite(uint32_t arch_token,
syscall = arch_syscall_resolve_name(arch, name);
if (syscall == __NR_SCMP_ERROR)
return __NR_SCMP_ERROR;
- if (arch_syscall_rewrite(arch, 0, &syscall) < 0)
+ rc = arch_syscall_rewrite(arch, &syscall);
+ if (rc == -EDOM)
+ /* if we can't rewrite the syscall, just pass it through */
+ return syscall;
+ else if (rc < 0)
return __NR_SCMP_ERROR;
return syscall;
@@ -356,7 +361,7 @@ API int seccomp_syscall_priority(scmp_filter_ctx ctx,
* since priorities are a "best effort" thing - as we
* want to catch the -EDOM error and bail on this
* architecture */
- rc_tmp = arch_syscall_rewrite(filter->arch, 1, &sc_tmp);
+ rc_tmp = arch_syscall_rewrite(filter->arch, &sc_tmp);
if (rc_tmp == -EDOM)
continue;
if (rc_tmp < 0)
@@ -483,7 +488,7 @@ static int _seccomp_rule_add(struct db_filter_col *col,
/* mangle the private chain copy */
rc_tmp = arch_filter_rewrite(filter->arch, strict,
&sc_tmp, chain_tmp);
- if ((rc == -EDOM) && (!strict)) {
+ if ((rc_tmp == -EDOM) && (!strict)) {
free(chain_tmp);
continue;
}
diff --git a/src/arch-aarch64-syscalls.c b/src/arch-aarch64-syscalls.c
index fa9dce3..9ac1dd0 100644
--- a/src/arch-aarch64-syscalls.c
+++ b/src/arch-aarch64-syscalls.c
@@ -26,7 +26,7 @@
#include "arch.h"
#include "arch-aarch64.h"
-/* NOTE: based on Linux 3.19 */
+/* NOTE: based on Linux 4.2-rc5 */
const struct arch_syscall_def aarch64_syscall_table[] = { \
{ "_llseek", __PNR__llseek },
{ "_newselect", __PNR__newselect },
@@ -224,6 +224,7 @@ const struct arch_syscall_def aarch64_syscall_table[] = { \
{ "msgrcv", 188 },
{ "msgsnd", 189 },
{ "msync", 227 },
+ { "multiplexer", __PNR_multiplexer },
{ "munlock", 229 },
{ "munlockall", 231 },
{ "munmap", 215 },
@@ -294,6 +295,7 @@ const struct arch_syscall_def aarch64_syscall_table[] = { \
{ "rt_sigsuspend", 133 },
{ "rt_sigtimedwait", 137 },
{ "rt_tgsigqueueinfo", 240 },
+ { "rtas", __PNR_rtas },
{ "s390_runtime_instr", __PNR_s390_runtime_instr },
{ "sched_get_priority_max", 125 },
{ "sched_get_priority_min", 126 },
@@ -373,6 +375,8 @@ const struct arch_syscall_def aarch64_syscall_table[] = { \
{ "socketcall", __PNR_socketcall },
{ "socketpair", 199 },
{ "splice", 76 },
+ { "spu_create", __PNR_spu_create },
+ { "spu_run", __PNR_spu_run },
{ "ssetmask", __PNR_ssetmask },
{ "stat", __PNR_stat },
{ "stat64", __PNR_stat64 },
@@ -380,8 +384,11 @@ const struct arch_syscall_def aarch64_syscall_table[] = { \
{ "statfs64", __PNR_statfs64 },
{ "stime", __PNR_stime },
{ "stty", __PNR_stty },
+ { "subpage_prot", __PNR_subpage_prot },
+ { "swapcontext", __PNR_swapcontext },
{ "swapoff", 225 },
{ "swapon", 224 },
+ { "switch_endian", __PNR_switch_endian },
{ "symlink", __PNR_symlink },
{ "symlinkat", 36 },
{ "sync", 81 },
@@ -389,6 +396,7 @@ const struct arch_syscall_def aarch64_syscall_table[] = { \
{ "sync_file_range2", __PNR_sync_file_range2 },
{ "syncfs", 267 },
{ "syscall", __PNR_syscall },
+ { "sys_debug_setcontext", __PNR_sys_debug_setcontext },
{ "sysfs", __PNR_sysfs },
{ "sysinfo", 179 },
{ "syslog", 116 },
diff --git a/src/arch-arm-syscalls.c b/src/arch-arm-syscalls.c
index 2ac2652..c4fd31e 100644
--- a/src/arch-arm-syscalls.c
+++ b/src/arch-arm-syscalls.c
@@ -37,7 +37,7 @@
#define __NR_SYSCALL_BASE __NR_OABI_SYSCALL_BASE
#endif
-/* NOTE: based on Linux 3.19 */
+/* NOTE: based on Linux 4.2-rc5 */
const struct arch_syscall_def arm_syscall_table[] = { \
/* NOTE: arm_sync_file_range() and sync_file_range2() share values */
{ "_llseek", (__NR_SYSCALL_BASE + 140) },
@@ -236,6 +236,7 @@ const struct arch_syscall_def arm_syscall_table[] = { \
{ "msgrcv", (__NR_SYSCALL_BASE + 302) },
{ "msgsnd", (__NR_SYSCALL_BASE + 301) },
{ "msync", (__NR_SYSCALL_BASE + 144) },
+ { "multiplexer", __PNR_multiplexer },
{ "munlock", (__NR_SYSCALL_BASE + 151) },
{ "munlockall", (__NR_SYSCALL_BASE + 153) },
{ "munmap", (__NR_SYSCALL_BASE + 91) },
@@ -306,6 +307,7 @@ const struct arch_syscall_def arm_syscall_table[] = { \
{ "rt_sigsuspend", (__NR_SYSCALL_BASE + 179) },
{ "rt_sigtimedwait", (__NR_SYSCALL_BASE + 177) },
{ "rt_tgsigqueueinfo", (__NR_SYSCALL_BASE + 363) },
+ { "rtas", __PNR_rtas },
{ "s390_runtime_instr", __PNR_s390_runtime_instr },
{ "sched_get_priority_max", (__NR_SYSCALL_BASE + 159) },
{ "sched_get_priority_min", (__NR_SYSCALL_BASE + 160) },
@@ -385,6 +387,8 @@ const struct arch_syscall_def arm_syscall_table[] = { \
{ "socketcall", __PNR_socketcall },
{ "socketpair", (__NR_SYSCALL_BASE + 288) },
{ "splice", (__NR_SYSCALL_BASE + 340) },
+ { "spu_create", __PNR_spu_create },
+ { "spu_run", __PNR_spu_run },
{ "ssetmask", __PNR_ssetmask },
{ "stat", (__NR_SYSCALL_BASE + 106) },
{ "stat64", (__NR_SYSCALL_BASE + 195) },
@@ -392,15 +396,19 @@ const struct arch_syscall_def arm_syscall_table[] = { \
{ "statfs64", (__NR_SYSCALL_BASE + 266) },
{ "stime", __PNR_stime },
{ "stty", __PNR_stty },
+ { "subpage_prot", __PNR_subpage_prot },
+ { "swapcontext", __PNR_swapcontext },
{ "swapoff", (__NR_SYSCALL_BASE + 115) },
{ "swapon", (__NR_SYSCALL_BASE + 87) },
+ { "switch_endian", __PNR_switch_endian },
{ "symlink", (__NR_SYSCALL_BASE + 83) },
{ "symlinkat", (__NR_SYSCALL_BASE + 331) },
{ "sync", (__NR_SYSCALL_BASE + 36) },
{ "sync_file_range", __PNR_sync_file_range },
{ "sync_file_range2", (__NR_SYSCALL_BASE + 341) },
{ "syncfs", (__NR_SYSCALL_BASE + 373) },
- { "syscall", __PNR_syscall },
+ { "syscall", (__PNR_syscall) },
+ { "sys_debug_setcontext", __PNR_sys_debug_setcontext },
{ "sysfs", (__NR_SYSCALL_BASE + 135) },
{ "sysinfo", (__NR_SYSCALL_BASE + 116) },
{ "syslog", (__NR_SYSCALL_BASE + 103) },
diff --git a/src/arch-mips-syscalls.c b/src/arch-mips-syscalls.c
index 21b9318..ae5ebf7 100644
--- a/src/arch-mips-syscalls.c
+++ b/src/arch-mips-syscalls.c
@@ -30,7 +30,7 @@
/* O32 ABI */
#define __NR_SYSCALL_BASE 4000
-/* NOTE: based on Linux 3.19 */
+/* NOTE: based on Linux 4.2-rc5 */
const struct arch_syscall_def mips_syscall_table[] = { \
{ "_llseek", (__NR_SYSCALL_BASE + 140) },
{ "_newselect", (__NR_SYSCALL_BASE + 142) },
@@ -228,6 +228,7 @@ const struct arch_syscall_def mips_syscall_table[] = { \
{ "msgrcv", __PNR_msgrcv },
{ "msgsnd", __PNR_msgsnd },
{ "msync", (__NR_SYSCALL_BASE + 144) },
+ { "multiplexer", __PNR_multiplexer },
{ "munlock", (__NR_SYSCALL_BASE + 155) },
{ "munlockall", (__NR_SYSCALL_BASE + 157) },
{ "munmap", (__NR_SYSCALL_BASE + 91) },
@@ -298,6 +299,7 @@ const struct arch_syscall_def mips_syscall_table[] = { \
{ "rt_sigsuspend", (__NR_SYSCALL_BASE + 199) },
{ "rt_sigtimedwait", (__NR_SYSCALL_BASE + 197) },
{ "rt_tgsigqueueinfo", (__NR_SYSCALL_BASE + 332) },
+ { "rtas", __PNR_rtas },
{ "s390_runtime_instr", __PNR_s390_runtime_instr },
{ "sched_get_priority_max", (__NR_SYSCALL_BASE + 163) },
{ "sched_get_priority_min", (__NR_SYSCALL_BASE + 164) },
@@ -377,6 +379,8 @@ const struct arch_syscall_def mips_syscall_table[] = { \
{ "socketcall", (__NR_SYSCALL_BASE + 102) },
{ "socketpair", (__NR_SYSCALL_BASE + 184) },
{ "splice", (__NR_SYSCALL_BASE + 304) },
+ { "spu_create", __PNR_spu_create },
+ { "spu_run", __PNR_spu_run },
{ "ssetmask", (__NR_SYSCALL_BASE + 69) },
{ "stat", (__NR_SYSCALL_BASE + 106) },
{ "stat64", (__NR_SYSCALL_BASE + 213) },
@@ -384,8 +388,11 @@ const struct arch_syscall_def mips_syscall_table[] = { \
{ "statfs64", (__NR_SYSCALL_BASE + 255) },
{ "stime", (__NR_SYSCALL_BASE + 25) },
{ "stty", (__NR_SYSCALL_BASE + 31) },
+ { "subpage_prot", __PNR_subpage_prot },
+ { "swapcontext", __PNR_swapcontext },
{ "swapoff", (__NR_SYSCALL_BASE + 115) },
{ "swapon", (__NR_SYSCALL_BASE + 87) },
+ { "switch_endian", __PNR_switch_endian },
{ "symlink", (__NR_SYSCALL_BASE + 83) },
{ "symlinkat", (__NR_SYSCALL_BASE + 297) },
{ "sync", (__NR_SYSCALL_BASE + 36) },
@@ -393,6 +400,7 @@ const struct arch_syscall_def mips_syscall_table[] = { \
{ "sync_file_range2", __PNR_sync_file_range2 },
{ "syncfs", (__NR_SYSCALL_BASE + 342) },
{ "syscall", (__NR_SYSCALL_BASE + 0) },
+ { "sys_debug_setcontext", __PNR_sys_debug_setcontext },
{ "sysfs", (__NR_SYSCALL_BASE + 135) },
{ "sysinfo", (__NR_SYSCALL_BASE + 116) },
{ "syslog", (__NR_SYSCALL_BASE + 103) },
diff --git a/src/arch-mips64-syscalls.c b/src/arch-mips64-syscalls.c
index 7ad6afb..baffe20 100644
--- a/src/arch-mips64-syscalls.c
+++ b/src/arch-mips64-syscalls.c
@@ -30,7 +30,7 @@
/* 64 ABI */
#define __NR_SYSCALL_BASE 5000
-/* NOTE: based on Linux 3.19 */
+/* NOTE: based on Linux 4.2-rc5 */
const struct arch_syscall_def mips64_syscall_table[] = { \
{ "_llseek", __PNR__llseek },
{ "_newselect", (__NR_SYSCALL_BASE + 22) },
@@ -228,6 +228,7 @@ const struct arch_syscall_def mips64_syscall_table[] = { \
{ "msgrcv", (__NR_SYSCALL_BASE + 68) },
{ "msgsnd", (__NR_SYSCALL_BASE + 67) },
{ "msync", (__NR_SYSCALL_BASE + 25) },
+ { "multiplexer", __PNR_multiplexer },
{ "munlock", (__NR_SYSCALL_BASE + 147) },
{ "munlockall", (__NR_SYSCALL_BASE + 149) },
{ "munmap", (__NR_SYSCALL_BASE + 11) },
@@ -298,6 +299,7 @@ const struct arch_syscall_def mips64_syscall_table[] = { \
{ "rt_sigsuspend", (__NR_SYSCALL_BASE + 128) },
{ "rt_sigtimedwait", (__NR_SYSCALL_BASE + 126) },
{ "rt_tgsigqueueinfo", (__NR_SYSCALL_BASE + 291) },
+ { "rtas", __PNR_rtas },
{ "s390_runtime_instr", __PNR_s390_runtime_instr },
{ "sched_get_priority_max", (__NR_SYSCALL_BASE + 143) },
{ "sched_get_priority_min", (__NR_SYSCALL_BASE + 144) },
@@ -377,6 +379,8 @@ const struct arch_syscall_def mips64_syscall_table[] = { \
{ "socketcall", __PNR_socketcall },
{ "socketpair", (__NR_SYSCALL_BASE + 52) },
{ "splice", (__NR_SYSCALL_BASE + 263) },
+ { "spu_create", __PNR_spu_create },
+ { "spu_run", __PNR_spu_run },
{ "ssetmask", __PNR_ssetmask },
{ "stat", (__NR_SYSCALL_BASE + 4) },
{ "stat64", __PNR_stat64 },
@@ -384,8 +388,11 @@ const struct arch_syscall_def mips64_syscall_table[] = { \
{ "statfs64", __PNR_statfs64 },
{ "stime", __PNR_stime },
{ "stty", __PNR_stty },
+ { "subpage_prot", __PNR_subpage_prot },
+ { "swapcontext", __PNR_swapcontext },
{ "swapoff", (__NR_SYSCALL_BASE + 163) },
{ "swapon", (__NR_SYSCALL_BASE + 162) },
+ { "switch_endian", __PNR_switch_endian },
{ "symlink", (__NR_SYSCALL_BASE + 86) },
{ "symlinkat", (__NR_SYSCALL_BASE + 256) },
{ "sync", (__NR_SYSCALL_BASE + 157) },
@@ -393,6 +400,7 @@ const struct arch_syscall_def mips64_syscall_table[] = { \
{ "sync_file_range2", __PNR_sync_file_range2 },
{ "syncfs", (__NR_SYSCALL_BASE + 301) },
{ "syscall", __PNR_syscall },
+ { "sys_debug_setcontext", __PNR_sys_debug_setcontext },
{ "sysfs", (__NR_SYSCALL_BASE + 136) },
{ "sysinfo", (__NR_SYSCALL_BASE + 97) },
{ "syslog", (__NR_SYSCALL_BASE + 101) },
diff --git a/src/arch-mips64n32-syscalls.c b/src/arch-mips64n32-syscalls.c
index e31987e..dd6966e 100644
--- a/src/arch-mips64n32-syscalls.c
+++ b/src/arch-mips64n32-syscalls.c
@@ -30,7 +30,7 @@
/* N32 ABI */
#define __NR_SYSCALL_BASE 6000
-/* NOTE: based on Linux 3.19 */
+/* NOTE: based on Linux 4.2-rc5 */
const struct arch_syscall_def mips64n32_syscall_table[] = { \
{ "_llseek", __PNR__llseek },
{ "_newselect", (__NR_SYSCALL_BASE + 22) },
@@ -228,6 +228,7 @@ const struct arch_syscall_def mips64n32_syscall_table[] = { \
{ "msgrcv", (__NR_SYSCALL_BASE + 68) },
{ "msgsnd", (__NR_SYSCALL_BASE + 67) },
{ "msync", (__NR_SYSCALL_BASE + 25) },
+ { "multiplexer", __PNR_multiplexer },
{ "munlock", (__NR_SYSCALL_BASE + 147) },
{ "munlockall", (__NR_SYSCALL_BASE + 149) },
{ "munmap", (__NR_SYSCALL_BASE + 11) },
@@ -298,6 +299,7 @@ const struct arch_syscall_def mips64n32_syscall_table[] = { \
{ "rt_sigsuspend", (__NR_SYSCALL_BASE + 128) },
{ "rt_sigtimedwait", (__NR_SYSCALL_BASE + 126) },
{ "rt_tgsigqueueinfo", (__NR_SYSCALL_BASE + 295) },
+ { "rtas", __PNR_rtas },
{ "s390_runtime_instr", __PNR_s390_runtime_instr },
{ "sched_get_priority_max", (__NR_SYSCALL_BASE + 143) },
{ "sched_get_priority_min", (__NR_SYSCALL_BASE + 144) },
@@ -377,6 +379,8 @@ const struct arch_syscall_def mips64n32_syscall_table[] = { \
{ "socketcall", __PNR_socketcall },
{ "socketpair", (__NR_SYSCALL_BASE + 52) },
{ "splice", (__NR_SYSCALL_BASE + 267) },
+ { "spu_create", __PNR_spu_create },
+ { "spu_run", __PNR_spu_run },
{ "ssetmask", __PNR_ssetmask },
{ "stat", (__NR_SYSCALL_BASE + 4) },
{ "stat64", __PNR_stat64 },
@@ -384,8 +388,11 @@ const struct arch_syscall_def mips64n32_syscall_table[] = { \
{ "statfs64", (__NR_SYSCALL_BASE + 217) },
{ "stime", __PNR_stime },
{ "stty", __PNR_stty },
+ { "subpage_prot", __PNR_subpage_prot },
+ { "swapcontext", __PNR_swapcontext },
{ "swapoff", (__NR_SYSCALL_BASE + 163) },
{ "swapon", (__NR_SYSCALL_BASE + 162) },
+ { "switch_endian", __PNR_switch_endian },
{ "symlink", (__NR_SYSCALL_BASE + 86) },
{ "symlinkat", (__NR_SYSCALL_BASE + 260) },
{ "sync", (__NR_SYSCALL_BASE + 157) },
@@ -393,6 +400,7 @@ const struct arch_syscall_def mips64n32_syscall_table[] = { \
{ "sync_file_range2", __PNR_sync_file_range2 },
{ "syncfs", (__NR_SYSCALL_BASE + 306) },
{ "syscall", __PNR_syscall },
+ { "sys_debug_setcontext", __PNR_sys_debug_setcontext },
{ "sysfs", (__NR_SYSCALL_BASE + 136) },
{ "sysinfo", (__NR_SYSCALL_BASE + 97) },
{ "syslog", (__NR_SYSCALL_BASE + 101) },
diff --git a/src/arch-ppc-syscalls.c b/src/arch-ppc-syscalls.c
new file mode 100644
index 0000000..8ddb750
--- /dev/null
+++ b/src/arch-ppc-syscalls.c
@@ -0,0 +1,510 @@
+/**
+ * Enhanced Seccomp PPC Specific Code
+ *
+ * Copyright (c) 2015 Freescale <bogdan.purcareata@freescale.com>
+ * Author: Bogdan Purcareata <bogdan.purcareata@freescale.com>
+ *
+ */
+
+/*
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of version 2.1 of the GNU Lesser General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This library 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 this library; if not, see <http://www.gnu.org/licenses>.
+ */
+
+#include <string.h>
+
+#include <seccomp.h>
+
+#include "arch.h"
+#include "arch-ppc.h"
+
+/* NOTE: based on Linux 4.2-rc5 */
+const struct arch_syscall_def ppc_syscall_table[] = { \
+ { "_llseek", 140 },
+ { "_newselect", 142 },
+ { "_sysctl", 149 },
+ { "accept", 330 },
+ { "accept4", 344 },
+ { "access", 33 },
+ { "acct", 51 },
+ { "add_key", 269 },
+ { "adjtimex", 124 },
+ { "afs_syscall", 137 },
+ { "alarm", 27 },
+ { "arm_fadvise64_64", __PNR_arm_fadvise64_64 },
+ { "arm_sync_file_range", __PNR_arm_sync_file_range },
+ { "arch_prctl", __PNR_arch_prctl },
+ { "bdflush", 134 },
+ { "bind", 327 },
+ { "bpf", 361 },
+ { "break", 17 },
+ { "breakpoint", __PNR_breakpoint },
+ { "brk", 45 },
+ { "cachectl", __PNR_cachectl },
+ { "cacheflush", __PNR_cacheflush },
+ { "capget", 183 },
+ { "capset", 184 },
+ { "chdir", 12 },
+ { "chmod", 15 },
+ { "chown", 181 },
+ { "chown32", __PNR_chown32 },
+ { "chroot", 61 },
+ { "clock_adjtime", 347 },
+ { "clock_getres", 247 },
+ { "clock_gettime", 246 },
+ { "clock_nanosleep", 248 },
+ { "clock_settime", 245 },
+ { "clone", 120 },
+ { "close", 6 },
+ { "connect", 328 },
+ { "creat", 8 },
+ { "create_module", 127 },
+ { "delete_module", 129 },
+ { "dup", 41 },
+ { "dup2", 63 },
+ { "dup3", 316 },
+ { "epoll_create", 236 },
+ { "epoll_create1", 315 },
+ { "epoll_ctl", 237 },
+ { "epoll_ctl_old", __PNR_epoll_ctl_old },
+ { "epoll_pwait", 303 },
+ { "epoll_wait", 238 },
+ { "epoll_wait_old", __PNR_epoll_wait_old },
+ { "eventfd", 307 },
+ { "eventfd2", 314 },
+ { "execve", 11 },
+ { "execveat", 362 },
+ { "exit", 1 },
+ { "exit_group", 234 },
+ { "faccessat", 298 },
+ { "fadvise64", 233 },
+ { "fadvise64_64", 254 },
+ { "fallocate", 309 },
+ { "fanotify_init", 323 },
+ { "fanotify_mark", 324 },
+ { "fchdir", 133 },
+ { "fchmod", 94 },
+ { "fchmodat", 297 },
+ { "fchown", 95 },
+ { "fchown32", __PNR_fchown32 },
+ { "fchownat", 289 },
+ { "fcntl", 55 },
+ { "fcntl64", 204 },
+ { "fdatasync", 148 },
+ { "fgetxattr", 214 },
+ { "finit_module", 353 },
+ { "flistxattr", 217 },
+ { "flock", 143 },
+ { "fork", 2 },
+ { "fremovexattr", 220 },
+ { "fsetxattr", 211 },
+ { "fstat", 108 },
+ { "fstat64", 197 },
+ { "fstatat64", 291 },
+ { "fstatfs", 100 },
+ { "fstatfs64", 253 },
+ { "fsync", 118 },
+ { "ftime", 35 },
+ { "ftruncate", 93 },
+ { "ftruncate64", 194 },
+ { "futex", 221 },
+ { "futimesat", 290 },
+ { "get_kernel_syms", 130 },
+ { "get_mempolicy", 260 },
+ { "get_robust_list", 299 },
+ { "get_thread_area", __PNR_get_thread_area },
+ { "getcpu", 302 },
+ { "getcwd", 182 },
+ { "getdents", 141 },
+ { "getdents64", 202 },
+ { "getegid", 50 },
+ { "getegid32", __PNR_getegid32 },
+ { "geteuid", 49 },
+ { "geteuid32", __PNR_geteuid32 },
+ { "getgid", 47 },
+ { "getgid32", __PNR_getgid32 },
+ { "getgroups", 80 },
+ { "getgroups32", __PNR_getgroups32 },
+ { "getitimer", 105 },
+ { "getpeername", 332 },
+ { "getpgid", 132 },
+ { "getpgrp", 65 },
+ { "getpid", 20 },
+ { "getpmsg", 187 },
+ { "getppid", 64 },
+ { "getpriority", 96 },
+ { "getrandom", 359 },
+ { "getresgid", 170 },
+ { "getresgid32", __PNR_getresgid32 },
+ { "getresuid", 165 },
+ { "getresuid32", __PNR_getresuid32 },
+ { "getrlimit", 76 },
+ { "getrusage", 77 },
+ { "getsid", 147 },
+ { "getsockname", 331 },
+ { "getsockopt", 340 },
+ { "gettid", 207 },
+ { "gettimeofday", 78 },
+ { "getuid", 24 },
+ { "getuid32", __PNR_getuid32 },
+ { "getxattr", 212 },
+ { "gtty", 32 },
+ { "idle", 112 },
+ { "init_module", 128 },
+ { "inotify_add_watch", 276 },
+ { "inotify_init", 275 },
+ { "inotify_init1", 318 },
+ { "inotify_rm_watch", 277 },
+ { "io_cancel", 231 },
+ { "io_destroy", 228 },
+ { "io_getevents", 229 },
+ { "io_setup", 227 },
+ { "io_submit", 230 },
+ { "ioctl", 54 },
+ { "ioperm", 101 },
+ { "iopl", 110 },
+ { "ioprio_get", 274 },
+ { "ioprio_set", 273 },
+ { "ipc", 117 },
+ { "kcmp", 354 },
+ { "kexec_file_load", __PNR_kexec_file_load },
+ { "kexec_load", 268 },
+ { "keyctl", 271 },
+ { "kill", 37 },
+ { "lchown", 16 },
+ { "lchown32", __PNR_lchown32 },
+ { "lgetxattr", 213 },
+ { "link", 9 },
+ { "linkat", 294 },
+ { "listen", 329 },
+ { "listxattr", 215 },
+ { "llistxattr", 216 },
+ { "lock", 53 },
+ { "lookup_dcookie", 235 },
+ { "lremovexattr", 219 },
+ { "lseek", 19 },
+ { "lsetxattr", 210 },
+ { "lstat", 107 },
+ { "lstat64", 196 },
+ { "madvise", 205 },
+ { "mbind", 259 },
+ { "memfd_create", 360 },
+ { "migrate_pages", 258 },
+ { "mincore", 206 },
+ { "mkdir", 39 },
+ { "mkdirat", 287 },
+ { "mknod", 14 },
+ { "mknodat", 288 },
+ { "mlock", 150 },
+ { "mlockall", 152 },
+ { "mmap", 90 },
+ { "mmap2", 192 },
+ { "modify_ldt", 123 },
+ { "mount", 21 },
+ { "move_pages", 301 },
+ { "mprotect", 125 },
+ { "mpx", 56 },
+ { "mq_getsetattr", 267 },
+ { "mq_notify", 266 },
+ { "mq_open", 262 },
+ { "mq_timedreceive", 265 },
+ { "mq_timedsend", 264 },
+ { "mq_unlink", 263 },
+ { "mremap", 163 },
+ { "msgctl", __PNR_msgctl },
+ { "msgget", __PNR_msgget },
+ { "msgrcv", __PNR_msgrcv },
+ { "msgsnd", __PNR_msgsnd },
+ { "msync", 144 },
+ { "multiplexer", 201 },
+ { "munlock", 151 },
+ { "munlockall", 153 },
+ { "munmap", 91 },
+ { "name_to_handle_at", 345 },
+ { "nanosleep", 162 },
+ { "newfstatat", __PNR_newfstatat },
+ { "nfsservctl", 168 },
+ { "nice", 34 },
+ { "oldfstat", 28 },
+ { "oldlstat", 84 },
+ { "oldolduname", 59 },
+ { "oldstat", 18 },
+ { "olduname", 109 },
+ { "oldwait4", __PNR_oldwait4 },
+ { "open", 5 },
+ { "open_by_handle_at", 346 },
+ { "openat", 286 },
+ { "pause", 29 },
+ { "pciconfig_iobase", 200 },
+ { "pciconfig_read", 198 },
+ { "pciconfig_write", 199 },
+ { "perf_event_open", 319 },
+ { "personality", 136 },
+ { "pipe", 42 },
+ { "pipe2", 317 },
+ { "pivot_root", 203 },
+ { "poll", 167 },
+ { "ppoll", 281 },
+ { "prctl", 171 },
+ { "pread64", 179 },
+ { "preadv", 320 },
+ { "prlimit64", 325 },
+ { "process_vm_readv", 351 },
+ { "process_vm_writev", 352 },
+ { "prof", 44 },
+ { "profil", 98 },
+ { "pselect6", 280 },
+ { "ptrace", 26 },
+ { "putpmsg", 188 },
+ { "pwrite64", 180 },
+ { "pwritev", 321 },
+ { "query_module", 166 },
+ { "quotactl", 131 },
+ { "read", 3 },
+ { "readahead", 191 },
+ { "readdir", 89 },
+ { "readlink", 85 },
+ { "readlinkat", 296 },
+ { "readv", 145 },
+ { "reboot", 88 },
+ { "recv", 336 },
+ { "recvfrom", 337 },
+ { "recvmmsg", 343 },
+ { "recvmsg", 342 },
+ { "remap_file_pages", 239 },
+ { "removexattr", 218 },
+ { "rename", 38 },
+ { "renameat", 293 },
+ { "renameat2", 357 },
+ { "request_key", 270 },
+ { "restart_syscall", 0 },
+ { "rmdir", 40 },
+ { "rt_sigaction", 173 },
+ { "rt_sigpending", 175 },
+ { "rt_sigprocmask", 174 },
+ { "rt_sigqueueinfo", 177 },
+ { "rt_sigreturn", 172 },
+ { "rt_sigsuspend", 178 },
+ { "rt_sigtimedwait", 176 },
+ { "rt_tgsigqueueinfo", 322 },
+ { "rtas", 255 },
+ { "s390_runtime_instr", __PNR_s390_runtime_instr },
+ { "sched_get_priority_max", 159 },
+ { "sched_get_priority_min", 160 },
+ { "sched_getaffinity", 223 },
+ { "sched_getattr", 356 },
+ { "sched_getparam", 155 },
+ { "sched_getscheduler", 157 },
+ { "sched_rr_get_interval", 161 },
+ { "sched_setaffinity", 222 },
+ { "sched_setattr", 355 },
+ { "sched_setparam", 154 },
+ { "sched_setscheduler", 156 },
+ { "sched_yield", 158 },
+ { "seccomp", 358 },
+ { "security", __PNR_security },
+ { "select", 82 },
+ { "semctl", __PNR_semctl },
+ { "semget", __PNR_semget },
+ { "semop", __PNR_semop },
+ { "semtimedop", __PNR_semtimedop },
+ { "send", 334 },
+ { "sendfile", 186 },
+ { "sendfile64", 226 },
+ { "sendmmsg", 349 },
+ { "sendmsg", 341 },
+ { "sendto", 335 },
+ { "set_mempolicy", 261 },
+ { "set_robust_list", 300 },
+ { "set_thread_area", __PNR_set_thread_area },
+ { "set_tid_address", 232 },
+ { "set_tls", __PNR_set_tls },
+ { "setdomainname", 121 },
+ { "setfsgid", 139 },
+ { "setfsgid32", __PNR_setfsgid32 },
+ { "setfsuid", 138 },
+ { "setfsuid32", __PNR_setfsuid32 },
+ { "setgid", 46 },
+ { "setgid32", __PNR_setgid32 },
+ { "setgroups", 81 },
+ { "setgroups32", __PNR_setgroups32 },
+ { "sethostname", 74 },
+ { "setitimer", 104 },
+ { "setns", 350 },
+ { "setpgid", 57 },
+ { "setpriority", 97 },
+ { "setregid", 71 },
+ { "setregid32", __PNR_setregid32 },
+ { "setresgid", 169 },
+ { "setresgid32", __PNR_setresgid32 },
+ { "setresuid", 164 },
+ { "setresuid32", __PNR_setresuid32 },
+ { "setreuid", 70 },
+ { "setreuid32", __PNR_setreuid32 },
+ { "setrlimit", 75 },
+ { "setsid", 66 },
+ { "setsockopt", 339 },
+ { "settimeofday", 79 },
+ { "setuid", 23 },
+ { "setuid32", __PNR_setuid32 },
+ { "setxattr", 209 },
+ { "sgetmask", 68 },
+ { "shmat", __PNR_shmat },
+ { "shmctl", __PNR_shmctl },
+ { "shmdt", __PNR_shmdt },
+ { "shmget", __PNR_shmget },
+ { "shutdown", 338 },
+ { "sigaction", 67 },
+ { "sigaltstack", 185 },
+ { "signal", 48 },
+ { "signalfd", 305 },
+ { "signalfd4", 313 },
+ { "sigpending", 73 },
+ { "sigprocmask", 126 },
+ { "sigreturn", 119 },
+ { "sigsuspend", 72 },
+ { "socket", 326 },
+ { "socketcall", 102 },
+ { "socketpair", 333 },
+ { "splice", 283 },
+ { "spu_create", 279 },
+ { "spu_run", 278 },
+ { "ssetmask", 69 },
+ { "stat", 106 },
+ { "stat64", 195 },
+ { "statfs", 99 },
+ { "statfs64", 252 },
+ { "stime", 25 },
+ { "stty", 31 },
+ { "subpage_prot", 310 },
+ { "swapcontext", 249 },
+ { "swapoff", 115 },
+ { "swapon", 87 },
+ { "switch_endian", 363 },
+ { "symlink", 83 },
+ { "symlinkat", 295 },
+ { "sync", 36 },
+ { "sync_file_range", __PNR_sync_file_range },
+ { "sync_file_range2", 308 },
+ { "syncfs", 348 },
+ { "syscall", __PNR_syscall },
+ { "sys_debug_setcontext", 256 },
+ { "sysfs", 135 },
+ { "sysinfo", 116 },
+ { "syslog", 103 },
+ { "sysmips", __PNR_sysmips },
+ { "tee", 284 },
+ { "tgkill", 250 },
+ { "time", 13 },
+ { "timer_create", 240 },
+ { "timer_delete", 244 },
+ { "timer_getoverrun", 243 },
+ { "timer_gettime", 242 },
+ { "timer_settime", 241 },
+ { "timerfd", __PNR_timerfd },
+ { "timerfd_create", 306 },
+ { "timerfd_gettime", 312 },
+ { "timerfd_settime", 311 },
+ { "times", 43 },
+ { "tkill", 208 },
+ { "truncate", 92 },
+ { "truncate64", 193 },
+ { "tuxcall", 225 },
+ { "ugetrlimit", 190 },
+ { "ulimit", 58 },
+ { "umask", 60 },
+ { "umount", 22 },
+ { "umount2", 52 },
+ { "uname", 122 },
+ { "unlink", 10 },
+ { "unlinkat", 292 },
+ { "unshare", 282 },
+ { "uselib", 86 },
+ { "usr26", __PNR_usr26 },
+ { "usr32", __PNR_usr32 },
+ { "ustat", 62 },
+ { "utime", 30 },
+ { "utimensat", 304 },
+ { "utimes", 251 },
+ { "vfork", 189 },
+ { "vhangup", 111 },
+ { "vm86", 113 },
+ { "vm86old", __PNR_vm86old },
+ { "vmsplice", 285 },
+ { "vserver", __PNR_vserver },
+ { "wait4", 114 },
+ { "waitid", 272 },
+ { "waitpid", 7 },
+ { "write", 4 },
+ { "writev", 146 },
+ { NULL, __NR_SCMP_ERROR },
+};
+
+/**
+ * Resolve a syscall name to a number
+ * @param name the syscall name
+ *
+ * Resolve the given syscall name to the syscall number using the syscall table.
+ * Returns the syscall number on success, including negative pseudo syscall
+ * numbers; returns __NR_SCMP_ERROR on failure.
+ *
+ */
+int ppc_syscall_resolve_name(const char *name)
+{
+ unsigned int iter;
+ const struct arch_syscall_def *table = ppc_syscall_table;
+
+ /* XXX - plenty of room for future improvement here */
+ for (iter = 0; table[iter].name != NULL; iter++) {
+ if (strcmp(name, table[iter].name) == 0)
+ return table[iter].num;
+ }
+
+ return __NR_SCMP_ERROR;
+}
+
+/**
+ * Resolve a syscall number to a name
+ * @param num the syscall number
+ *
+ * Resolve the given syscall number to the syscall name using the syscall table.
+ * Returns a pointer to the syscall name string on success, including pseudo
+ * syscall names; returns NULL on failure.
+ *
+ */
+const char *ppc_syscall_resolve_num(int num)
+{
+ unsigned int iter;
+ const struct arch_syscall_def *table = ppc_syscall_table;
+
+ /* XXX - plenty of room for future improvement here */
+ for (iter = 0; table[iter].num != __NR_SCMP_ERROR; iter++) {
+ if (num == table[iter].num)
+ return table[iter].name;
+ }
+
+ return NULL;
+}
+
+/**
+ * Iterate through the syscall table and return the syscall name
+ * @param spot the offset into the syscall table
+ *
+ * Return the syscall name at position @spot or NULL on failure. This function
+ * should only ever be used internally by libseccomp.
+ *
+ */
+const char *ppc_syscall_iterate_name(unsigned int spot)
+{
+ /* XXX - no safety checks here */
+ return ppc_syscall_table[spot].name;
+}
diff --git a/src/arch-ppc.c b/src/arch-ppc.c
new file mode 100644
index 0000000..56dbdb4
--- /dev/null
+++ b/src/arch-ppc.c
@@ -0,0 +1,33 @@
+/**
+ * Enhanced Seccomp PPC Specific Code
+ *
+ * Copyright (c) 2015 Freescale <bogdan.purcareata@freescale.com>
+ * Author: Bogdan Purcareata <bogdan.purcareata@freescale.com>
+ *
+ */
+
+/*
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of version 2.1 of the GNU Lesser General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This library 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 this library; if not, see <http://www.gnu.org/licenses>.
+ */
+
+#include <linux/audit.h>
+
+#include "arch.h"
+#include "arch-ppc.h"
+
+const struct arch_def arch_def_ppc = {
+ .token = SCMP_ARCH_PPC,
+ .token_bpf = AUDIT_ARCH_PPC,
+ .size = ARCH_SIZE_32,
+ .endian = ARCH_ENDIAN_BIG,
+};
diff --git a/src/arch-ppc.h b/src/arch-ppc.h
new file mode 100644
index 0000000..627a168
--- /dev/null
+++ b/src/arch-ppc.h
@@ -0,0 +1,38 @@
+/**
+ * Enhanced Seccomp PPC Specific Code
+ *
+ * Copyright (c) 2015 Freescale <bogdan.purcareata@freescale.com>
+ * Author: Bogdan Purcareata <bogdan.purcareata@freescale.com>
+ *
+ */
+
+/*
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of version 2.1 of the GNU Lesser General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This library 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 this library; if not, see <http://www.gnu.org/licenses>.
+ */
+
+#ifndef _ARCH_PPC_H
+#define _ARCH_PPC_H
+
+#include <inttypes.h>
+
+#include "arch.h"
+#include "system.h"
+
+extern const struct arch_def arch_def_ppc;
+
+int ppc_syscall_resolve_name(const char *name);
+const char *ppc_syscall_resolve_num(int num);
+
+const char *ppc_syscall_iterate_name(unsigned int spot);
+
+#endif
diff --git a/src/arch-ppc64-syscalls.c b/src/arch-ppc64-syscalls.c
new file mode 100644
index 0000000..d9060f4
--- /dev/null
+++ b/src/arch-ppc64-syscalls.c
@@ -0,0 +1,510 @@
+/**
+ * Enhanced Seccomp PPC64 Specific Code
+ *
+ * Copyright (c) 2014 Red Hat <pmoore@redhat.com>
+ * Author: Paul Moore <pmoore@redhat.com>
+ *
+ */
+
+/*
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of version 2.1 of the GNU Lesser General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This library 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 this library; if not, see <http://www.gnu.org/licenses>.
+ */
+
+#include <string.h>
+
+#include <seccomp.h>
+
+#include "arch.h"
+#include "arch-ppc64.h"
+
+/* NOTE: based on Linux 4.2-rc5 */
+const struct arch_syscall_def ppc64_syscall_table[] = { \
+ { "_llseek", 140 },
+ { "_newselect", 142 },
+ { "_sysctl", 149 },
+ { "accept", 330 },
+ { "accept4", 344 },
+ { "access", 33 },
+ { "acct", 51 },
+ { "add_key", 269 },
+ { "adjtimex", 124 },
+ { "afs_syscall", 137 },
+ { "alarm", 27 },
+ { "arm_fadvise64_64", __PNR_arm_fadvise64_64 },
+ { "arm_sync_file_range", __PNR_arm_sync_file_range },
+ { "arch_prctl", __PNR_arch_prctl },
+ { "bdflush", 134 },
+ { "bind", 327 },
+ { "bpf", 361 },
+ { "break", 17 },
+ { "breakpoint", __PNR_breakpoint },
+ { "brk", 45 },
+ { "cachectl", __PNR_cachectl },
+ { "cacheflush", __PNR_cacheflush },
+ { "capget", 183 },
+ { "capset", 184 },
+ { "chdir", 12 },
+ { "chmod", 15 },
+ { "chown", 181 },
+ { "chown32", __PNR_chown32 },
+ { "chroot", 61 },
+ { "clock_adjtime", 347 },
+ { "clock_getres", 247 },
+ { "clock_gettime", 246 },
+ { "clock_nanosleep", 248 },
+ { "clock_settime", 245 },
+ { "clone", 120 },
+ { "close", 6 },
+ { "connect", 328 },
+ { "creat", 8 },
+ { "create_module", 127 },
+ { "delete_module", 129 },
+ { "dup", 41 },
+ { "dup2", 63 },
+ { "dup3", 316 },
+ { "epoll_create", 236 },
+ { "epoll_create1", 315 },
+ { "epoll_ctl", 237 },
+ { "epoll_ctl_old", __PNR_epoll_ctl_old },
+ { "epoll_pwait", 303 },
+ { "epoll_wait", 238 },
+ { "epoll_wait_old", __PNR_epoll_wait_old },
+ { "eventfd", 307 },
+ { "eventfd2", 314 },
+ { "execve", 11 },
+ { "execveat", 362 },
+ { "exit", 1 },
+ { "exit_group", 234 },
+ { "faccessat", 298 },
+ { "fadvise64", 233 },
+ { "fadvise64_64", __PNR_fadvise64_64 },
+ { "fallocate", 309 },
+ { "fanotify_init", 323 },
+ { "fanotify_mark", 324 },
+ { "fchdir", 133 },
+ { "fchmod", 94 },
+ { "fchmodat", 297 },
+ { "fchown", 95 },
+ { "fchown32", __PNR_fchown32 },
+ { "fchownat", 289 },
+ { "fcntl", 55 },
+ { "fcntl64", __PNR_fcntl64 },
+ { "fdatasync", 148 },
+ { "fgetxattr", 214 },
+ { "finit_module", 353 },
+ { "flistxattr", 217 },
+ { "flock", 143 },
+ { "fork", 2 },
+ { "fremovexattr", 220 },
+ { "fsetxattr", 211 },
+ { "fstat", 108 },
+ { "fstat64", __PNR_fstat64 },
+ { "fstatat64", __PNR_fstatat64 },
+ { "fstatfs", 100 },
+ { "fstatfs64", 253 },
+ { "fsync", 118 },
+ { "ftime", 35 },
+ { "ftruncate", 93 },
+ { "ftruncate64", __PNR_ftruncate64 },
+ { "futex", 221 },
+ { "futimesat", 290 },
+ { "get_kernel_syms", 130 },
+ { "get_mempolicy", 260 },
+ { "get_robust_list", 299 },
+ { "get_thread_area", __PNR_get_thread_area },
+ { "getcpu", 302 },
+ { "getcwd", 182 },
+ { "getdents", 141 },
+ { "getdents64", 202 },
+ { "getegid", 50 },
+ { "getegid32", __PNR_getegid32 },
+ { "geteuid", 49 },
+ { "geteuid32", __PNR_geteuid32 },
+ { "getgid", 47 },
+ { "getgid32", __PNR_getgid32 },
+ { "getgroups", 80 },
+ { "getgroups32", __PNR_getgroups32 },
+ { "getitimer", 105 },
+ { "getpeername", 332 },
+ { "getpgid", 132 },
+ { "getpgrp", 65 },
+ { "getpid", 20 },
+ { "getpmsg", 187 },
+ { "getppid", 64 },
+ { "getpriority", 96 },
+ { "getrandom", 359 },
+ { "getresgid", 170 },
+ { "getresgid32", __PNR_getresgid32 },
+ { "getresuid", 165 },
+ { "getresuid32", __PNR_getresuid32 },
+ { "getrlimit", 76 },
+ { "getrusage", 77 },
+ { "getsid", 147 },
+ { "getsockname", 331 },
+ { "getsockopt", 340 },
+ { "gettid", 207 },
+ { "gettimeofday", 78 },
+ { "getuid", 24 },
+ { "getuid32", __PNR_getuid32 },
+ { "getxattr", 212 },
+ { "gtty", 32 },
+ { "idle", 112 },
+ { "init_module", 128 },
+ { "inotify_add_watch", 276 },
+ { "inotify_init", 275 },
+ { "inotify_init1", 318 },
+ { "inotify_rm_watch", 277 },
+ { "io_cancel", 231 },
+ { "io_destroy", 228 },
+ { "io_getevents", 229 },
+ { "io_setup", 227 },
+ { "io_submit", 230 },
+ { "ioctl", 54 },
+ { "ioperm", 101 },
+ { "iopl", 110 },
+ { "ioprio_get", 274 },
+ { "ioprio_set", 273 },
+ { "ipc", 117 },
+ { "kcmp", 354 },
+ { "kexec_file_load", __PNR_kexec_file_load },
+ { "kexec_load", 268 },
+ { "keyctl", 271 },
+ { "kill", 37 },
+ { "lchown", 16 },
+ { "lchown32", __PNR_lchown32 },
+ { "lgetxattr", 213 },
+ { "link", 9 },
+ { "linkat", 294 },
+ { "listen", 329 },
+ { "listxattr", 215 },
+ { "llistxattr", 216 },
+ { "lock", 53 },
+ { "lookup_dcookie", 235 },
+ { "lremovexattr", 219 },
+ { "lseek", 19 },
+ { "lsetxattr", 210 },
+ { "lstat", 107 },
+ { "lstat64", __PNR_lstat64 },
+ { "madvise", 205 },
+ { "mbind", 259 },
+ { "memfd_create", 360 },
+ { "migrate_pages", 258 },
+ { "mincore", 206 },
+ { "mkdir", 39 },
+ { "mkdirat", 287 },
+ { "mknod", 14 },
+ { "mknodat", 288 },
+ { "mlock", 150 },
+ { "mlockall", 152 },
+ { "mmap", 90 },
+ { "mmap2", __PNR_mmap2 },
+ { "modify_ldt", 123 },
+ { "mount", 21 },
+ { "move_pages", 301 },
+ { "mprotect", 125 },
+ { "mpx", 56 },
+ { "mq_getsetattr", 267 },
+ { "mq_notify", 266 },
+ { "mq_open", 262 },
+ { "mq_timedreceive", 265 },
+ { "mq_timedsend", 264 },
+ { "mq_unlink", 263 },
+ { "mremap", 163 },
+ { "msgctl", __PNR_msgctl },
+ { "msgget", __PNR_msgget },
+ { "msgrcv", __PNR_msgrcv },
+ { "msgsnd", __PNR_msgsnd },
+ { "msync", 144 },
+ { "multiplexer", 201 },
+ { "munlock", 151 },
+ { "munlockall", 153 },
+ { "munmap", 91 },
+ { "name_to_handle_at", 345 },
+ { "nanosleep", 162 },
+ { "newfstatat", 291 },
+ { "nfsservctl", 168 },
+ { "nice", 34 },
+ { "oldfstat", 28 },
+ { "oldlstat", 84 },
+ { "oldolduname", 59 },
+ { "oldstat", 18 },
+ { "olduname", 109 },
+ { "oldwait4", __PNR_oldwait4 },
+ { "open", 5 },
+ { "open_by_handle_at", 346 },
+ { "openat", 286 },
+ { "pause", 29 },
+ { "pciconfig_iobase", 200 },
+ { "pciconfig_read", 198 },
+ { "pciconfig_write", 199 },
+ { "perf_event_open", 319 },
+ { "personality", 136 },
+ { "pipe", 42 },
+ { "pipe2", 317 },
+ { "pivot_root", 203 },
+ { "poll", 167 },
+ { "ppoll", 281 },
+ { "prctl", 171 },
+ { "pread64", 179 },
+ { "preadv", 320 },
+ { "prlimit64", 325 },
+ { "process_vm_readv", 351 },
+ { "process_vm_writev", 352 },
+ { "prof", 44 },
+ { "profil", 98 },
+ { "pselect6", 280 },
+ { "ptrace", 26 },
+ { "putpmsg", 188 },
+ { "pwrite64", 180 },
+ { "pwritev", 321 },
+ { "query_module", 166 },
+ { "quotactl", 131 },
+ { "read", 3 },
+ { "readahead", 191 },
+ { "readdir", 89 },
+ { "readlink", 85 },
+ { "readlinkat", 296 },
+ { "readv", 145 },
+ { "reboot", 88 },
+ { "recv", 336 },
+ { "recvfrom", 337 },
+ { "recvmmsg", 343 },
+ { "recvmsg", 342 },
+ { "remap_file_pages", 239 },
+ { "removexattr", 218 },
+ { "rename", 38 },
+ { "renameat", 293 },
+ { "renameat2", 357 },
+ { "request_key", 270 },
+ { "restart_syscall", 0 },
+ { "rmdir", 40 },
+ { "rt_sigaction", 173 },
+ { "rt_sigpending", 175 },
+ { "rt_sigprocmask", 174 },
+ { "rt_sigqueueinfo", 177 },
+ { "rt_sigreturn", 172 },
+ { "rt_sigsuspend", 178 },
+ { "rt_sigtimedwait", 176 },
+ { "rt_tgsigqueueinfo", 322 },
+ { "rtas", 255 },
+ { "s390_runtime_instr", __PNR_s390_runtime_instr },
+ { "sched_get_priority_max", 159 },
+ { "sched_get_priority_min", 160 },
+ { "sched_getaffinity", 223 },
+ { "sched_getattr", 356 },
+ { "sched_getparam", 155 },
+ { "sched_getscheduler", 157 },
+ { "sched_rr_get_interval", 161 },
+ { "sched_setaffinity", 222 },
+ { "sched_setattr", 355 },
+ { "sched_setparam", 154 },
+ { "sched_setscheduler", 156 },
+ { "sched_yield", 158 },
+ { "seccomp", 358 },
+ { "security", __PNR_security },
+ { "select", 82 },
+ { "semctl", __PNR_semctl },
+ { "semget", __PNR_semget },
+ { "semop", __PNR_semop },
+ { "semtimedop", __PNR_semtimedop },
+ { "send", 334 },
+ { "sendfile", 186 },
+ { "sendfile64", __PNR_sendfile64 },
+ { "sendmmsg", 349 },
+ { "sendmsg", 341 },
+ { "sendto", 335 },
+ { "set_mempolicy", 261 },
+ { "set_robust_list", 300 },
+ { "set_thread_area", __PNR_set_thread_area },
+ { "set_tid_address", 232 },
+ { "set_tls", __PNR_set_tls },
+ { "setdomainname", 121 },
+ { "setfsgid", 139 },
+ { "setfsgid32", __PNR_setfsgid32 },
+ { "setfsuid", 138 },
+ { "setfsuid32", __PNR_setfsuid32 },
+ { "setgid", 46 },
+ { "setgid32", __PNR_setgid32 },
+ { "setgroups", 81 },
+ { "setgroups32", __PNR_setgroups32 },
+ { "sethostname", 74 },
+ { "setitimer", 104 },
+ { "setns", 350 },
+ { "setpgid", 57 },
+ { "setpriority", 97 },
+ { "setregid", 71 },
+ { "setregid32", __PNR_setregid32 },
+ { "setresgid", 169 },
+ { "setresgid32", __PNR_setresgid32 },
+ { "setresuid", 164 },
+ { "setresuid32", __PNR_setresuid32 },
+ { "setreuid", 70 },
+ { "setreuid32", __PNR_setreuid32 },
+ { "setrlimit", 75 },
+ { "setsid", 66 },
+ { "setsockopt", 339 },
+ { "settimeofday", 79 },
+ { "setuid", 23 },
+ { "setuid32", __PNR_setuid32 },
+ { "setxattr", 209 },
+ { "sgetmask", 68 },
+ { "shmat", __PNR_shmat },
+ { "shmctl", __PNR_shmctl },
+ { "shmdt", __PNR_shmdt },
+ { "shmget", __PNR_shmget },
+ { "shutdown", 338 },
+ { "sigaction", 67 },
+ { "sigaltstack", 185 },
+ { "signal", 48 },
+ { "signalfd", 305 },
+ { "signalfd4", 313 },
+ { "sigpending", 73 },
+ { "sigprocmask", 126 },
+ { "sigreturn", 119 },
+ { "sigsuspend", 72 },
+ { "socket", 326 },
+ { "socketcall", 102 },
+ { "socketpair", 333 },
+ { "splice", 283 },
+ { "spu_create", 279 },
+ { "spu_run", 278 },
+ { "ssetmask", 69 },
+ { "stat", 106 },
+ { "stat64", __PNR_stat64 },
+ { "statfs", 99 },
+ { "statfs64", 252 },
+ { "stime", 25 },
+ { "stty", 31 },
+ { "subpage_prot", 310 },
+ { "swapcontext", 249 },
+ { "swapoff", 115 },
+ { "swapon", 87 },
+ { "switch_endian", __PNR_switch_endian },
+ { "symlink", 83 },
+ { "symlinkat", 295 },
+ { "sync", 36 },
+ { "sync_file_range", __PNR_sync_file_range },
+ { "sync_file_range2", 308 },
+ { "syncfs", 348 },
+ { "syscall", __PNR_syscall },
+ { "sys_debug_setcontext", 256 },
+ { "sysfs", 135 },
+ { "sysinfo", 116 },
+ { "syslog", 103 },
+ { "sysmips", __PNR_sysmips },
+ { "tee", 284 },
+ { "tgkill", 250 },
+ { "time", 13 },
+ { "timer_create", 240 },
+ { "timer_delete", 244 },
+ { "timer_getoverrun", 243 },
+ { "timer_gettime", 242 },
+ { "timer_settime", 241 },
+ { "timerfd", __PNR_timerfd },
+ { "timerfd_create", 306 },
+ { "timerfd_gettime", 312 },
+ { "timerfd_settime", 311 },
+ { "times", 43 },
+ { "tkill", 208 },
+ { "truncate", 92 },
+ { "truncate64", __PNR_truncate64 },
+ { "tuxcall", 225 },
+ { "ugetrlimit", 190 },
+ { "ulimit", 58 },
+ { "umask", 60 },
+ { "umount", 22 },
+ { "umount2", 52 },
+ { "uname", 122 },
+ { "unlink", 10 },
+ { "unlinkat", 292 },
+ { "unshare", 282 },
+ { "uselib", 86 },
+ { "usr26", __PNR_usr26 },
+ { "usr32", __PNR_usr32 },
+ { "ustat", 62 },
+ { "utime", 30 },
+ { "utimensat", 304 },
+ { "utimes", 251 },
+ { "vfork", 189 },
+ { "vhangup", 111 },
+ { "vm86", 113 },
+ { "vm86old", __PNR_vm86old },
+ { "vmsplice", 285 },
+ { "vserver", __PNR_vserver },
+ { "wait4", 114 },
+ { "waitid", 272 },
+ { "waitpid", 7 },
+ { "write", 4 },
+ { "writev", 146 },
+ { NULL, __NR_SCMP_ERROR },
+};
+
+/**
+ * Resolve a syscall name to a number
+ * @param name the syscall name
+ *
+ * Resolve the given syscall name to the syscall number using the syscall table.
+ * Returns the syscall number on success, including negative pseudo syscall
+ * numbers; returns __NR_SCMP_ERROR on failure.
+ *
+ */
+int ppc64_syscall_resolve_name(const char *name)
+{
+ unsigned int iter;
+ const struct arch_syscall_def *table = ppc64_syscall_table;
+
+ /* XXX - plenty of room for future improvement here */
+ for (iter = 0; table[iter].name != NULL; iter++) {
+ if (strcmp(name, table[iter].name) == 0)
+ return table[iter].num;
+ }
+
+ return __NR_SCMP_ERROR;
+}
+
+/**
+ * Resolve a syscall number to a name
+ * @param num the syscall number
+ *
+ * Resolve the given syscall number to the syscall name using the syscall table.
+ * Returns a pointer to the syscall name string on success, including pseudo
+ * syscall names; returns NULL on failure.
+ *
+ */
+const char *ppc64_syscall_resolve_num(int num)
+{
+ unsigned int iter;
+ const struct arch_syscall_def *table = ppc64_syscall_table;
+
+ /* XXX - plenty of room for future improvement here */
+ for (iter = 0; table[iter].num != __NR_SCMP_ERROR; iter++) {
+ if (num == table[iter].num)
+ return table[iter].name;
+ }
+
+ return NULL;
+}
+
+/**
+ * Iterate through the syscall table and return the syscall name
+ * @param spot the offset into the syscall table
+ *
+ * Return the syscall name at position @spot or NULL on failure. This function
+ * should only ever be used internally by libseccomp.
+ *
+ */
+const char *ppc64_syscall_iterate_name(unsigned int spot)
+{
+ /* XXX - no safety checks here */
+ return ppc64_syscall_table[spot].name;
+}
diff --git a/src/arch-ppc64.c b/src/arch-ppc64.c
new file mode 100644
index 0000000..5f461cb
--- /dev/null
+++ b/src/arch-ppc64.c
@@ -0,0 +1,40 @@
+/**
+ * Enhanced Seccomp PPC64 Specific Code
+ *
+ * Copyright (c) 2014 Red Hat <pmoore@redhat.com>
+ * Author: Paul Moore <pmoore@redhat.com>
+ *
+ */
+
+/*
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of version 2.1 of the GNU Lesser General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This library 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 this library; if not, see <http://www.gnu.org/licenses>.
+ */
+
+#include <linux/audit.h>
+
+#include "arch.h"
+#include "arch-ppc64.h"
+
+const struct arch_def arch_def_ppc64 = {
+ .token = SCMP_ARCH_PPC64,
+ .token_bpf = AUDIT_ARCH_PPC64,
+ .size = ARCH_SIZE_64,
+ .endian = ARCH_ENDIAN_BIG,
+};
+
+const struct arch_def arch_def_ppc64le = {
+ .token = SCMP_ARCH_PPC64LE,
+ .token_bpf = AUDIT_ARCH_PPC64LE,
+ .size = ARCH_SIZE_64,
+ .endian = ARCH_ENDIAN_LITTLE,
+};
diff --git a/src/arch-ppc64.h b/src/arch-ppc64.h
new file mode 100644
index 0000000..1aec743
--- /dev/null
+++ b/src/arch-ppc64.h
@@ -0,0 +1,39 @@
+/**
+ * Enhanced Seccomp PPC64 Specific Code
+ *
+ * Copyright (c) 2014 Red Hat <pmoore@redhat.com>
+ * Author: Paul Moore <pmoore@redhat.com>
+ *
+ */
+
+/*
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of version 2.1 of the GNU Lesser General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This library 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 this library; if not, see <http://www.gnu.org/licenses>.
+ */
+
+#ifndef _ARCH_PPC64_H
+#define _ARCH_PPC64_H
+
+#include <inttypes.h>
+
+#include "arch.h"
+#include "system.h"
+
+extern const struct arch_def arch_def_ppc64;
+extern const struct arch_def arch_def_ppc64le;
+
+int ppc64_syscall_resolve_name(const char *name);
+const char *ppc64_syscall_resolve_num(int num);
+
+const char *ppc64_syscall_iterate_name(unsigned int spot);
+
+#endif
diff --git a/src/arch-s390-syscalls.c b/src/arch-s390-syscalls.c
index a219d22..4da63ed 100644
--- a/src/arch-s390-syscalls.c
+++ b/src/arch-s390-syscalls.c
@@ -10,7 +10,7 @@
#include "arch.h"
#include "arch-s390.h"
-/* NOTE: based on Linux 3.17 */
+/* NOTE: based on Linux 4.2-rc5 */
const struct arch_syscall_def s390_syscall_table[] = { \
{ "_llseek", 140 },
{ "_newselect", 142 },
@@ -208,6 +208,7 @@ const struct arch_syscall_def s390_syscall_table[] = { \
{ "msgrcv", __PNR_msgrcv },
{ "msgsnd", __PNR_msgsnd },
{ "msync", 144 },
+ { "multiplexer", __PNR_multiplexer },
{ "munlock", 151 },
{ "munlockall", 153 },
{ "munmap", 91 },
@@ -278,6 +279,7 @@ const struct arch_syscall_def s390_syscall_table[] = { \
{ "rt_sigsuspend", 179 },
{ "rt_sigtimedwait", 177 },
{ "rt_tgsigqueueinfo", 330 },
+ { "rtas", __PNR_rtas },
{ "s390_runtime_instr", 342 },
{ "sched_get_priority_max", 159 },
{ "sched_get_priority_min", 160 },
@@ -357,6 +359,8 @@ const struct arch_syscall_def s390_syscall_table[] = { \
{ "socketcall", 102 },
{ "socketpair", __PNR_socketpair },
{ "splice", 306 },
+ { "spu_create", __PNR_spu_create },
+ { "spu_run", __PNR_spu_run },
{ "ssetmask", __PNR_ssetmask },
{ "stat", 106 },
{ "stat64", 195 },
@@ -364,8 +368,11 @@ const struct arch_syscall_def s390_syscall_table[] = { \
{ "statfs64", 265 },
{ "stime", 25 },
{ "stty", __PNR_stty },
+ { "subpage_prot", __PNR_subpage_prot },
+ { "swapcontext", __PNR_swapcontext },
{ "swapoff", 115 },
{ "swapon", 87 },
+ { "switch_endian", __PNR_switch_endian },
{ "symlink", 83 },
{ "symlinkat", 297 },
{ "sync", 36 },
@@ -373,6 +380,7 @@ const struct arch_syscall_def s390_syscall_table[] = { \
{ "sync_file_range2", __PNR_sync_file_range2 },
{ "syncfs", 338 },
{ "syscall", __PNR_syscall },
+ { "sys_debug_setcontext", __PNR_sys_debug_setcontext },
{ "sysfs", 135 },
{ "sysinfo", 116 },
{ "syslog", 103 },
diff --git a/src/arch-s390x-syscalls.c b/src/arch-s390x-syscalls.c
index 0a6f3f8..50596cb 100644
--- a/src/arch-s390x-syscalls.c
+++ b/src/arch-s390x-syscalls.c
@@ -10,7 +10,7 @@
#include "arch.h"
#include "arch-s390x.h"
-/* NOTE: based on Linux 3.17 */
+/* NOTE: based on Linux 4.2-rc5 */
const struct arch_syscall_def s390x_syscall_table[] = { \
{ "_llseek", __PNR__llseek },
{ "_newselect", __PNR__newselect },
@@ -208,6 +208,7 @@ const struct arch_syscall_def s390x_syscall_table[] = { \
{ "msgrcv", __PNR_msgrcv },
{ "msgsnd", __PNR_msgsnd },
{ "msync", 144 },
+ { "multiplexer", __PNR_multiplexer },
{ "munlock", 151 },
{ "munlockall", 153 },
{ "munmap", 91 },
@@ -278,6 +279,7 @@ const struct arch_syscall_def s390x_syscall_table[] = { \
{ "rt_sigsuspend", 179 },
{ "rt_sigtimedwait", 177 },
{ "rt_tgsigqueueinfo", 330 },
+ { "rtas", __PNR_rtas },
{ "s390_runtime_instr", 342 },
{ "sched_get_priority_max", 159 },
{ "sched_get_priority_min", 160 },
@@ -357,6 +359,8 @@ const struct arch_syscall_def s390x_syscall_table[] = { \
{ "socketcall", 102 },
{ "socketpair", __PNR_socketpair },
{ "splice", 306 },
+ { "spu_create", __PNR_spu_create },
+ { "spu_run", __PNR_spu_run },
{ "ssetmask", __PNR_ssetmask },
{ "stat", 106 },
{ "stat64", __PNR_stat64 },
@@ -364,8 +368,11 @@ const struct arch_syscall_def s390x_syscall_table[] = { \
{ "statfs64", 265 },
{ "stime", __PNR_stime },
{ "stty", __PNR_stty },
+ { "subpage_prot", __PNR_subpage_prot },
+ { "swapcontext", __PNR_swapcontext },
{ "swapoff", 115 },
{ "swapon", 87 },
+ { "switch_endian", __PNR_switch_endian },
{ "symlink", 83 },
{ "symlinkat", 297 },
{ "sync", 36 },
@@ -373,6 +380,7 @@ const struct arch_syscall_def s390x_syscall_table[] = { \
{ "sync_file_range2", __PNR_sync_file_range2 },
{ "syncfs", 338 },
{ "syscall", __PNR_syscall },
+ { "sys_debug_setcontext", __PNR_sys_debug_setcontext },
{ "sysfs", 135 },
{ "sysinfo", 116 },
{ "syslog", 103 },
diff --git a/src/arch-syscall-check.c b/src/arch-syscall-check.c
index a91892c..9668aec 100644
--- a/src/arch-syscall-check.c
+++ b/src/arch-syscall-check.c
@@ -33,6 +33,8 @@
#include "arch-mips.h"
#include "arch-mips64.h"
#include "arch-mips64n32.h"
+#include "arch-ppc.h"
+#include "arch-ppc64.h"
#include "arch-s390.h"
#include "arch-s390x.h"
@@ -69,8 +71,10 @@ int main(int argc, char *argv[])
int i_mips = 0;
int i_mips64 = 0;
int i_mips64n32 = 0;
- int i_s390x = 0;
+ int i_ppc = 0;
+ int i_ppc64 = 0;
int i_s390 = 0;
+ int i_s390x = 0;
const char *sys_name;
char str_miss[256];
@@ -97,6 +101,10 @@ int main(int argc, char *argv[])
mips64_syscall_iterate_name(i_mips64));
syscall_check(str_miss, sys_name, "mips64n32",
mips64n32_syscall_iterate_name(i_mips64n32));
+ syscall_check(str_miss, sys_name, "ppc",
+ ppc_syscall_iterate_name(i_ppc));
+ syscall_check(str_miss, sys_name, "ppc64",
+ ppc64_syscall_iterate_name(i_ppc64));
syscall_check(str_miss, sys_name, "s390",
s390_syscall_iterate_name(i_s390));
syscall_check(str_miss, sys_name, "s390x",
@@ -119,14 +127,18 @@ int main(int argc, char *argv[])
i_x32 = -1;
if (!arm_syscall_iterate_name(++i_arm))
i_arm = -1;
+ if (!aarch64_syscall_iterate_name(++i_aarch64))
+ i_aarch64 = -1;
if (!mips_syscall_iterate_name(++i_mips))
i_mips = -1;
if (!mips64_syscall_iterate_name(++i_mips64))
i_mips64 = -1;
if (!mips64n32_syscall_iterate_name(++i_mips64n32))
i_mips64n32 = -1;
- if (!aarch64_syscall_iterate_name(++i_aarch64))
- i_aarch64 = -1;
+ if (!ppc_syscall_iterate_name(++i_ppc))
+ i_ppc = -1;
+ if (!ppc64_syscall_iterate_name(++i_ppc64))
+ i_ppc64 = -1;
if (!s390_syscall_iterate_name(++i_s390))
i_s390 = -1;
if (!s390x_syscall_iterate_name(++i_s390x))
@@ -134,6 +146,7 @@ int main(int argc, char *argv[])
} while (i_x86_64 >= 0 && i_x32 >= 0 &&
i_arm >= 0 && i_aarch64 >= 0 &&
i_mips >= 0 && i_mips64 >= 0 && i_mips64n32 >= 0 &&
+ i_ppc >= 0 && i_ppc64 >= 0 &&
i_s390 >= 0 && i_s390x >= 0);
/* check for any leftovers */
@@ -177,6 +190,15 @@ int main(int argc, char *argv[])
mips64n32_syscall_iterate_name(i_mips64n32));
return 1;
}
+ if (i_ppc >= 0) {
+ printf("%s: ERROR, ppc has additional syscalls\n",
+ ppc_syscall_iterate_name(i_ppc));
+ }
+ if (i_ppc64 >= 0) {
+ printf("%s: ERROR, ppc64 has additional syscalls\n",
+ ppc64_syscall_iterate_name(i_ppc64));
+ return 1;
+ }
if (i_s390 >= 0) {
printf("%s: ERROR, s390 has additional syscalls\n",
s390_syscall_iterate_name(i_s390));
diff --git a/src/arch-syscall-dump.c b/src/arch-syscall-dump.c
index 0bf938c..4534aec 100644
--- a/src/arch-syscall-dump.c
+++ b/src/arch-syscall-dump.c
@@ -38,6 +38,8 @@
#include "arch-mips64.h"
#include "arch-mips64n32.h"
#include "arch-aarch64.h"
+#include "arch-ppc.h"
+#include "arch-ppc64.h"
#include "arch-s390.h"
#include "arch-s390x.h"
@@ -99,6 +101,9 @@ int main(int argc, char *argv[])
case SCMP_ARCH_ARM:
sys_name = arm_syscall_iterate_name(iter);
break;
+ case SCMP_ARCH_AARCH64:
+ sys_name = aarch64_syscall_iterate_name(iter);
+ break;
case SCMP_ARCH_MIPS:
case SCMP_ARCH_MIPSEL:
sys_name = mips_syscall_iterate_name(iter);
@@ -111,8 +116,12 @@ int main(int argc, char *argv[])
case SCMP_ARCH_MIPSEL64N32:
sys_name = mips64n32_syscall_iterate_name(iter);
break;
- case SCMP_ARCH_AARCH64:
- sys_name = aarch64_syscall_iterate_name(iter);
+ case SCMP_ARCH_PPC:
+ sys_name = ppc_syscall_iterate_name(iter);
+ break;
+ case SCMP_ARCH_PPC64:
+ case SCMP_ARCH_PPC64LE:
+ sys_name = ppc64_syscall_iterate_name(iter);
break;
case SCMP_ARCH_S390:
sys_name = s390_syscall_iterate_name(iter);
diff --git a/src/arch-syscall-validate b/src/arch-syscall-validate
index 6264de0..89cce3a 100755
--- a/src/arch-syscall-validate
+++ b/src/arch-syscall-validate
@@ -319,12 +319,49 @@ function dump_lib_mips64n32() {
}
#
-# Dump the s390 library syscall table
+# Dump the ppc system syscall table
+#
+# Arguments:
+# 1 path to the kernel source
+#
+# Dump the architecture's syscall table to stdout.
+#
+function dump_sys_ppc() {
+ gcc -E -dM $1/arch/powerpc/include/uapi/asm/unistd.h | \
+ grep "^#define __NR_" | sort | \
+ sed -e 's/#define[ \t]\+__NR_\([a-z0-9_]\+\)[ \t]\+\([0-9]\+\)/\1\t\2/'
+}
+
+#
+# Dump the ppc library syscall table
#
# Dump the library's syscall table to stdout.
#
-function dump_lib_s390() {
- $LIB_SYS_DUMP -a s390 | grep -v - | sort
+function dump_lib_ppc() {
+ $LIB_SYS_DUMP -a ppc | sed -e '/[^\t]\+\t-[0-9]\+/d'
+}
+
+#
+# Dump the ppc64 system syscall table
+#
+# Arguments:
+# 1 path to the kernel source
+#
+# Dump the architecture's syscall table to stdout.
+#
+function dump_sys_ppc64() {
+ gcc -E -dM -D__powerpc64__ $1/arch/powerpc/include/uapi/asm/unistd.h | \
+ grep "^#define __NR_" | sort | \
+ sed -e 's/#define[ \t]\+__NR_\([a-z0-9_]\+\)[ \t]\+\([0-9]\+\)/\1\t\2/'
+}
+
+#
+# Dump the ppc64 library syscall table
+#
+# Dump the library's syscall table to stdout.
+#
+function dump_lib_ppc64() {
+ $LIB_SYS_DUMP -a ppc64 | sed -e '/[^\t]\+\t-[0-9]\+/d'
}
#
@@ -341,12 +378,12 @@ function dump_sys_s390() {
}
#
-# Dump the s390x library syscall table
+# Dump the s390 library syscall table
#
# Dump the library's syscall table to stdout.
#
-function dump_lib_s390x() {
- $LIB_SYS_DUMP -a s390x | grep -v - | sort
+function dump_lib_s390() {
+ $LIB_SYS_DUMP -a s390 | grep -v - | sort
}
#
@@ -363,6 +400,15 @@ function dump_sys_s390x() {
}
#
+# Dump the s390x library syscall table
+#
+# Dump the library's syscall table to stdout.
+#
+function dump_lib_s390x() {
+ $LIB_SYS_DUMP -a s390x | grep -v - | sort
+}
+
+#
# Dump the system syscall table
#
# Arguments:
@@ -397,6 +443,12 @@ function dump_sys() {
mips64n32)
dump_sys_mips64n32 "$2"
;;
+ ppc)
+ dump_sys_ppc "$2"
+ ;;
+ ppc64)
+ dump_sys_ppc64 "$2"
+ ;;
s390)
dump_sys_s390 "$2"
;;
@@ -443,6 +495,12 @@ function dump_lib() {
mips64n32)
dump_lib_mips64n32
;;
+ ppc)
+ dump_lib_ppc "$2"
+ ;;
+ ppc64)
+ dump_lib_ppc64 "$2"
+ ;;
s390)
dump_lib_s390 "$2"
;;
@@ -495,7 +553,12 @@ shift $(($OPTIND - 1))
# defaults
if [[ $opt_arches == "" ]]; then
- opt_arches="x86 x86_64 x32 arm aarch64 mips mips64 mips64n32 s390 s390x"
+ opt_arches=" \
+ x86 x86_64 x32 \
+ arm aarch64 \
+ mips mips64 mips64n32 \
+ ppc pcc64 \
+ s390 s390x"
fi
# sanity checks
diff --git a/src/arch-x32-syscalls.c b/src/arch-x32-syscalls.c
index 3478a3a..d6ea9d4 100644
--- a/src/arch-x32-syscalls.c
+++ b/src/arch-x32-syscalls.c
@@ -26,7 +26,7 @@
#include "arch.h"
#include "arch-x32.h"
-/* NOTE: based on Linux 3.19 */
+/* NOTE: based on Linux 4.2-rc5 */
const struct arch_syscall_def x32_syscall_table[] = { \
{ "_llseek", __PNR__llseek },
{ "_newselect", __PNR__newselect },
@@ -224,6 +224,7 @@ const struct arch_syscall_def x32_syscall_table[] = { \
{ "msgrcv", (X32_SYSCALL_BIT + 70) },
{ "msgsnd", (X32_SYSCALL_BIT + 69) },
{ "msync", (X32_SYSCALL_BIT + 26) },
+ { "multiplexer", __PNR_multiplexer },
{ "munlock", (X32_SYSCALL_BIT + 150) },
{ "munlockall", (X32_SYSCALL_BIT + 152) },
{ "munmap", (X32_SYSCALL_BIT + 11) },
@@ -294,6 +295,7 @@ const struct arch_syscall_def x32_syscall_table[] = { \
{ "rt_sigsuspend", (X32_SYSCALL_BIT + 130) },
{ "rt_sigtimedwait", (X32_SYSCALL_BIT + 523) },
{ "rt_tgsigqueueinfo", (X32_SYSCALL_BIT + 536) },
+ { "rtas", __PNR_rtas },
{ "s390_runtime_instr", __PNR_s390_runtime_instr },
{ "sched_get_priority_max", (X32_SYSCALL_BIT + 146) },
{ "sched_get_priority_min", (X32_SYSCALL_BIT + 147) },
@@ -373,6 +375,8 @@ const struct arch_syscall_def x32_syscall_table[] = { \
{ "socketcall", __PNR_socketcall },
{ "socketpair", (X32_SYSCALL_BIT + 53) },
{ "splice", (X32_SYSCALL_BIT + 275) },
+ { "spu_create", __PNR_spu_create },
+ { "spu_run", __PNR_spu_run },
{ "ssetmask", __PNR_ssetmask },
{ "stat", (X32_SYSCALL_BIT + 4) },
{ "stat64", __PNR_stat64 },
@@ -380,8 +384,11 @@ const struct arch_syscall_def x32_syscall_table[] = { \
{ "statfs64", __PNR_statfs64 },
{ "stime", __PNR_stime },
{ "stty", __PNR_stty },
+ { "subpage_prot", __PNR_subpage_prot },
+ { "swapcontext", __PNR_swapcontext },
{ "swapoff", (X32_SYSCALL_BIT + 168) },
{ "swapon", (X32_SYSCALL_BIT + 167) },
+ { "switch_endian", __PNR_switch_endian },
{ "symlink", (X32_SYSCALL_BIT + 88) },
{ "symlinkat", (X32_SYSCALL_BIT + 266) },
{ "sync", (X32_SYSCALL_BIT + 162) },
@@ -389,6 +396,7 @@ const struct arch_syscall_def x32_syscall_table[] = { \
{ "sync_file_range2", __PNR_sync_file_range2 },
{ "syncfs", (X32_SYSCALL_BIT + 306) },
{ "syscall", __PNR_syscall },
+ { "sys_debug_setcontext", __PNR_sys_debug_setcontext },
{ "sysfs", (X32_SYSCALL_BIT + 139) },
{ "sysinfo", (X32_SYSCALL_BIT + 99) },
{ "syslog", (X32_SYSCALL_BIT + 103) },
diff --git a/src/arch-x86-syscalls.c b/src/arch-x86-syscalls.c
index b5c7028..b6665aa 100644
--- a/src/arch-x86-syscalls.c
+++ b/src/arch-x86-syscalls.c
@@ -26,7 +26,7 @@
#include "arch.h"
#include "arch-x86.h"
-/* NOTE: based on Linux 3.19 */
+/* NOTE: based on Linux 4.2-rc5 */
const struct arch_syscall_def x86_syscall_table[] = { \
{ "_llseek", 140 },
{ "_newselect", 142 },
@@ -224,6 +224,7 @@ const struct arch_syscall_def x86_syscall_table[] = { \
{ "msgrcv", __PNR_msgrcv },
{ "msgsnd", __PNR_msgsnd },
{ "msync", 144 },
+ { "multiplexer", __PNR_multiplexer },
{ "munlock", 151 },
{ "munlockall", 153 },
{ "munmap", 91 },
@@ -294,6 +295,7 @@ const struct arch_syscall_def x86_syscall_table[] = { \
{ "rt_sigsuspend", 179 },
{ "rt_sigtimedwait", 177 },
{ "rt_tgsigqueueinfo", 335 },
+ { "rtas", __PNR_rtas },
{ "s390_runtime_instr", __PNR_s390_runtime_instr },
{ "sched_get_priority_max", 159 },
{ "sched_get_priority_min", 160 },
@@ -373,6 +375,8 @@ const struct arch_syscall_def x86_syscall_table[] = { \
{ "socketcall", 102 },
{ "socketpair", __PNR_socketpair },
{ "splice", 313 },
+ { "spu_create", __PNR_spu_create },
+ { "spu_run", __PNR_spu_run },
{ "ssetmask", 69 },
{ "stat", 106 },
{ "stat64", 195 },
@@ -380,8 +384,11 @@ const struct arch_syscall_def x86_syscall_table[] = { \
{ "statfs64", 268 },
{ "stime", 25 },
{ "stty", 31 },
+ { "subpage_prot", __PNR_subpage_prot },
+ { "swapcontext", __PNR_swapcontext },
{ "swapoff", 115 },
{ "swapon", 87 },
+ { "switch_endian", __PNR_switch_endian },
{ "symlink", 83 },
{ "symlinkat", 304 },
{ "sync", 36 },
@@ -389,6 +396,7 @@ const struct arch_syscall_def x86_syscall_table[] = { \
{ "sync_file_range2", __PNR_sync_file_range2 },
{ "syncfs", 344 },
{ "syscall", __PNR_syscall },
+ { "sys_debug_setcontext", __PNR_sys_debug_setcontext },
{ "sysfs", 135 },
{ "sysinfo", 116 },
{ "syslog", 103 },
diff --git a/src/arch-x86.c b/src/arch-x86.c
index 1b4f2a9..a08ffdf 100644
--- a/src/arch-x86.c
+++ b/src/arch-x86.c
@@ -40,24 +40,22 @@ const struct arch_def arch_def_x86 = {
/**
* Rewrite a syscall value to match the architecture
* @param arch the architecture definition
- * @param strict strict flag
* @param syscall the syscall number
*
* Syscalls can vary across different architectures so this function rewrites
- * the syscall into the correct value for the specified architecture. If
- * @strict is true then the function will fail if the syscall can not be
- * preservered, however, if @strict is false the function will do a "best
- * effort" rewrite and not fail. Returns zero on success, negative values on
- * failure.
+ * the syscall into the correct value for the specified architecture. Returns
+ * zero on success, negative values on failure.
*
*/
-int x86_syscall_rewrite(const struct arch_def *arch, bool strict, int *syscall)
+int x86_syscall_rewrite(const struct arch_def *arch, int *syscall)
{
- if ((*syscall) <= -100 && (*syscall) >= -117)
+ int sys = *syscall;
+
+ if (sys <= -100 && sys >= -117)
*syscall = __x86_NR_socketcall;
- else if ((*syscall) <= -200 && (*syscall) >= -211)
+ else if (sys <= -200 && sys >= -211)
*syscall = __x86_NR_ipc;
- else if (((*syscall) < 0) && (strict))
+ else if (sys < 0)
return -EDOM;
return 0;
@@ -81,6 +79,7 @@ int x86_syscall_rewrite(const struct arch_def *arch, bool strict, int *syscall)
int x86_filter_rewrite(const struct arch_def *arch, bool strict,
int *syscall, struct db_api_arg *chain)
{
+ int sys = *syscall;
unsigned int iter;
int arg_max;
@@ -88,7 +87,7 @@ int x86_filter_rewrite(const struct arch_def *arch, bool strict,
if (arg_max < 0)
return arg_max;
- if ((*syscall) <= -100 && (*syscall) >= -117) {
+ if (sys <= -100 && sys >= -117) {
for (iter = 0; iter < arg_max; iter++) {
if ((chain[iter].valid != 0) && (strict))
return -EINVAL;
@@ -96,10 +95,10 @@ int x86_filter_rewrite(const struct arch_def *arch, bool strict,
chain[0].arg = 0;
chain[0].op = SCMP_CMP_EQ;
chain[0].mask = DATUM_MAX;
- chain[0].datum = abs(*syscall) % 100;
+ chain[0].datum = abs(sys) % 100;
chain[0].valid = 1;
*syscall = __x86_NR_socketcall;
- } else if ((*syscall) <= -200 && (*syscall) >= -211) {
+ } else if (sys <= -200 && sys >= -211) {
for (iter = 0; iter < arg_max; iter++) {
if ((chain[iter].valid != 0) && (strict))
return -EINVAL;
@@ -107,10 +106,10 @@ int x86_filter_rewrite(const struct arch_def *arch, bool strict,
chain[0].arg = 0;
chain[0].op = SCMP_CMP_EQ;
chain[0].mask = DATUM_MAX;
- chain[0].datum = abs(*syscall) % 200;
+ chain[0].datum = abs(sys) % 200;
chain[0].valid = 1;
*syscall = __x86_NR_ipc;
- } else if (((*syscall) < 0) && (strict))
+ } else if (sys < 0)
return -EDOM;
return 0;
diff --git a/src/arch-x86.h b/src/arch-x86.h
index 163d0ed..6190519 100644
--- a/src/arch-x86.h
+++ b/src/arch-x86.h
@@ -35,7 +35,7 @@ const char *x86_syscall_resolve_num(int num);
const char *x86_syscall_iterate_name(unsigned int spot);
-int x86_syscall_rewrite(const struct arch_def *arch, bool strict, int *syscall);
+int x86_syscall_rewrite(const struct arch_def *arch, int *syscall);
int x86_filter_rewrite(const struct arch_def *arch, bool strict,
int *syscall, struct db_api_arg *chain);
diff --git a/src/arch-x86_64-syscalls.c b/src/arch-x86_64-syscalls.c
index d3cff14..90cc21f 100644
--- a/src/arch-x86_64-syscalls.c
+++ b/src/arch-x86_64-syscalls.c
@@ -26,7 +26,7 @@
#include "arch.h"
#include "arch-x86_64.h"
-/* NOTE: based on Linux 3.19 */
+/* NOTE: based on Linux 4.2-rc5 */
const struct arch_syscall_def x86_64_syscall_table[] = { \
{ "_llseek", __PNR__llseek },
{ "_newselect", __PNR__newselect },
@@ -224,6 +224,7 @@ const struct arch_syscall_def x86_64_syscall_table[] = { \
{ "msgrcv", 70 },
{ "msgsnd", 69 },
{ "msync", 26 },
+ { "multiplexer", __PNR_multiplexer },
{ "munlock", 150 },
{ "munlockall", 152 },
{ "munmap", 11 },
@@ -294,6 +295,7 @@ const struct arch_syscall_def x86_64_syscall_table[] = { \
{ "rt_sigsuspend", 130 },
{ "rt_sigtimedwait", 128 },
{ "rt_tgsigqueueinfo", 297 },
+ { "rtas", __PNR_rtas },
{ "s390_runtime_instr", __PNR_s390_runtime_instr },
{ "sched_get_priority_max", 146 },
{ "sched_get_priority_min", 147 },
@@ -373,6 +375,8 @@ const struct arch_syscall_def x86_64_syscall_table[] = { \
{ "socketcall", __PNR_socketcall },
{ "socketpair", 53 },
{ "splice", 275 },
+ { "spu_create", __PNR_spu_create },
+ { "spu_run", __PNR_spu_run },
{ "ssetmask", __PNR_ssetmask },
{ "stat", 4 },
{ "stat64", __PNR_stat64 },
@@ -380,8 +384,11 @@ const struct arch_syscall_def x86_64_syscall_table[] = { \
{ "statfs64", __PNR_statfs64 },
{ "stime", __PNR_stime },
{ "stty", __PNR_stty },
+ { "subpage_prot", __PNR_subpage_prot },
+ { "swapcontext", __PNR_swapcontext },
{ "swapoff", 168 },
{ "swapon", 167 },
+ { "switch_endian", __PNR_switch_endian },
{ "symlink", 88 },
{ "symlinkat", 266 },
{ "sync", 162 },
@@ -389,6 +396,7 @@ const struct arch_syscall_def x86_64_syscall_table[] = { \
{ "sync_file_range2", __PNR_sync_file_range2 },
{ "syncfs", 306 },
{ "syscall", __PNR_syscall },
+ { "sys_debug_setcontext", __PNR_sys_debug_setcontext },
{ "sysfs", 139 },
{ "sysinfo", 99 },
{ "syslog", 103 },
diff --git a/src/arch.c b/src/arch.c
index 63bbe90..33f35a7 100644
--- a/src/arch.c
+++ b/src/arch.c
@@ -38,6 +38,8 @@
#include "arch-mips.h"
#include "arch-mips64.h"
#include "arch-mips64n32.h"
+#include "arch-ppc.h"
+#include "arch-ppc64.h"
#include "arch-s390.h"
#include "arch-s390x.h"
#include "system.h"
@@ -76,6 +78,14 @@ const struct arch_def *arch_def_native = &arch_def_mips64n32;
#elif __MIPSEL__
const struct arch_def *arch_def_native = &arch_def_mipsel64n32;
#endif /* _MIPS_SIM_NABI32 */
+#elif __PPC64__
+#ifdef __BIG_ENDIAN__
+const struct arch_def *arch_def_native = &arch_def_ppc64;
+#else
+const struct arch_def *arch_def_native = &arch_def_ppc64le;
+#endif
+#elif __PPC__
+const struct arch_def *arch_def_native = &arch_def_ppc;
#elif __s390x__ /* s390x must be checked before s390 */
const struct arch_def *arch_def_native = &arch_def_s390x;
#elif __s390__
@@ -128,6 +138,12 @@ const struct arch_def *arch_def_lookup(uint32_t token)
return &arch_def_mips64n32;
case SCMP_ARCH_MIPSEL64N32:
return &arch_def_mipsel64n32;
+ case SCMP_ARCH_PPC:
+ return &arch_def_ppc;
+ case SCMP_ARCH_PPC64:
+ return &arch_def_ppc64;
+ case SCMP_ARCH_PPC64LE:
+ return &arch_def_ppc64le;
case SCMP_ARCH_S390:
return &arch_def_s390;
case SCMP_ARCH_S390X:
@@ -168,6 +184,12 @@ const struct arch_def *arch_def_lookup_name(const char *arch_name)
return &arch_def_mips64n32;
else if (strcmp(arch_name, "mipsel64n32") == 0)
return &arch_def_mipsel64n32;
+ else if (strcmp(arch_name, "ppc") == 0)
+ return &arch_def_ppc;
+ else if (strcmp(arch_name, "ppc64") == 0)
+ return &arch_def_ppc64;
+ else if (strcmp(arch_name, "ppc64le") == 0)
+ return &arch_def_ppc64le;
else if (strcmp(arch_name, "s390") == 0)
return &arch_def_s390;
else if (strcmp(arch_name, "s390x") == 0)
@@ -290,6 +312,11 @@ int arch_syscall_resolve_name(const struct arch_def *arch, const char *name)
case SCMP_ARCH_MIPS64N32:
case SCMP_ARCH_MIPSEL64N32:
return mips64n32_syscall_resolve_name(name);
+ case SCMP_ARCH_PPC:
+ return ppc_syscall_resolve_name(name);
+ case SCMP_ARCH_PPC64:
+ case SCMP_ARCH_PPC64LE:
+ return ppc64_syscall_resolve_name(name);
case SCMP_ARCH_S390:
return s390_syscall_resolve_name(name);
case SCMP_ARCH_S390X:
@@ -331,6 +358,11 @@ const char *arch_syscall_resolve_num(const struct arch_def *arch, int num)
case SCMP_ARCH_MIPS64N32:
case SCMP_ARCH_MIPSEL64N32:
return mips64n32_syscall_resolve_num(num);
+ case SCMP_ARCH_PPC:
+ return ppc_syscall_resolve_num(num);
+ case SCMP_ARCH_PPC64:
+ case SCMP_ARCH_PPC64LE:
+ return ppc64_syscall_resolve_num(num);
case SCMP_ARCH_S390:
return s390_syscall_resolve_num(num);
case SCMP_ARCH_S390X:
@@ -373,18 +405,15 @@ int arch_syscall_translate(const struct arch_def *arch, int *syscall)
/**
* Rewrite a syscall value to match the architecture
* @param arch the architecture definition
- * @param strict strict flag
* @param syscall the syscall number
*
* Syscalls can vary across different architectures so this function rewrites
- * the syscall into the correct value for the specified architecture. If
- * @strict is true then the function will fail if the syscall can not be
- * preservered, however, if @strict is false the function will do a "best
- * effort" rewrite and not fail. Returns zero on success, negative values on
- * failure.
+ * the syscall into the correct value for the specified architecture. Returns
+ * zero on success, -EDOM if the syscall is not defined for @arch, and negative
+ * values on failure.
*
*/
-int arch_syscall_rewrite(const struct arch_def *arch, bool strict, int *syscall)
+int arch_syscall_rewrite(const struct arch_def *arch, int *syscall)
{
int sys = *syscall;
@@ -398,14 +427,12 @@ int arch_syscall_rewrite(const struct arch_def *arch, bool strict, int *syscall)
/* rewritable syscalls */
switch (arch->token) {
case SCMP_ARCH_X86:
- return x86_syscall_rewrite(arch, strict, syscall);
+ x86_syscall_rewrite(arch, syscall);
}
- /* NOTE: we fall through to the default handling (strict?) if
- * we don't support any rewriting for the architecture */
}
/* syscalls not defined on this architecture */
- if (strict)
+ if ((*syscall) < 0)
return -EDOM;
return 0;
}
@@ -422,12 +449,14 @@ int arch_syscall_rewrite(const struct arch_def *arch, bool strict, int *syscall)
* regardless of the rule or architecture. If @strict is true then the
* function will fail if the entire filter can not be preservered, however,
* if @strict is false the function will do a "best effort" rewrite and not
- * fail. Returns zero on success, negative values on failure.
+ * fail. Returns zero on success, -EDOM if the syscall is not defined for
+ * @arch, and negative values on failure.
*
*/
int arch_filter_rewrite(const struct arch_def *arch,
bool strict, int *syscall, struct db_api_arg *chain)
{
+ int rc;
int sys = *syscall;
if (sys >= 0) {
@@ -440,14 +469,15 @@ int arch_filter_rewrite(const struct arch_def *arch,
/* rewritable syscalls */
switch (arch->token) {
case SCMP_ARCH_X86:
- return x86_filter_rewrite(arch, strict, syscall, chain);
+ rc = x86_filter_rewrite(arch, strict, syscall, chain);
+ /* we still want to catch invalid rewrites */
+ if (rc == -EINVAL)
+ return -EINVAL;
}
- /* NOTE: we fall through to the default handling (strict?) if
- * we don't support any rewriting for the architecture */
}
/* syscalls not defined on this architecture */
- if (strict)
+ if ((*syscall) < 0)
return -EDOM;
return 0;
}
diff --git a/src/arch.h b/src/arch.h
index aa3158c..84e54e5 100644
--- a/src/arch.h
+++ b/src/arch.h
@@ -90,8 +90,7 @@ int arch_syscall_resolve_name(const struct arch_def *arch, const char *name);
const char *arch_syscall_resolve_num(const struct arch_def *arch, int num);
int arch_syscall_translate(const struct arch_def *arch, int *syscall);
-int arch_syscall_rewrite(const struct arch_def *arch, bool strict,
- int *syscall);
+int arch_syscall_rewrite(const struct arch_def *arch, int *syscall);
int arch_filter_rewrite(const struct arch_def *arch,
bool strict, int *syscall, struct db_api_arg *chain);
diff --git a/src/db.c b/src/db.c
index 604d058..37b334a 100644
--- a/src/db.c
+++ b/src/db.c
@@ -780,8 +780,7 @@ void db_release(struct db_filter *db)
* negative values on failure.
*
*/
-int db_syscall_priority(struct db_filter *db,
- unsigned int syscall, uint8_t priority)
+int db_syscall_priority(struct db_filter *db, int syscall, uint8_t priority)
{
unsigned int sys_pri = _DB_PRI_USER(priority);
struct db_sys_list *s_new, *s_iter, *s_prev = NULL;
@@ -1128,7 +1127,7 @@ gen_32_failure:
* filter DB. Returns zero on success, negative values on failure.
*
*/
-int db_rule_add(struct db_filter *db, uint32_t action, unsigned int syscall,
+int db_rule_add(struct db_filter *db, uint32_t action, int syscall,
struct db_api_arg *chain)
{
int rc = -ENOMEM;
diff --git a/src/db.h b/src/db.h
index 376cbc3..bfd9333 100644
--- a/src/db.h
+++ b/src/db.h
@@ -188,10 +188,9 @@ struct db_filter *db_init(const struct arch_def *arch);
void db_reset(struct db_filter *db);
void db_release(struct db_filter *db);
-int db_syscall_priority(struct db_filter *db,
- unsigned int syscall, uint8_t priority);
+int db_syscall_priority(struct db_filter *db, int syscall, uint8_t priority);
-int db_rule_add(struct db_filter *db, uint32_t action, unsigned int syscall,
+int db_rule_add(struct db_filter *db, uint32_t action, int syscall,
struct db_api_arg *chain);
#endif
diff --git a/src/gen_bpf.c b/src/gen_bpf.c
index 8d1b1b5..ba55c57 100644
--- a/src/gen_bpf.c
+++ b/src/gen_bpf.c
@@ -880,7 +880,6 @@ static struct bpf_blk *_gen_bpf_node(struct bpf_state *state,
case SCMP_CMP_NE:
case SCMP_CMP_LT:
case SCMP_CMP_LE:
- /* if we hit here it means the filter db isn't correct */
default:
/* fatal error, we should never get here */
goto node_failure;
diff --git a/src/python/libseccomp.pxd b/src/python/libseccomp.pxd
index ec8d53c..1f29c5f 100644
--- a/src/python/libseccomp.pxd
+++ b/src/python/libseccomp.pxd
@@ -38,6 +38,9 @@ cdef extern from "seccomp.h":
SCMP_ARCH_MIPSEL
SCMP_ARCH_MIPSEL64
SCMP_ARCH_MIPSEL64N32
+ SCMP_ARCH_PPC
+ SCMP_ARCH_PPC64
+ SCMP_ARCH_PPC64LE
SCMP_ARCH_S390
SCMP_ARCH_S390X
diff --git a/src/python/seccomp.pyx b/src/python/seccomp.pyx
index 823e50a..2d753a9 100644
--- a/src/python/seccomp.pyx
+++ b/src/python/seccomp.pyx
@@ -147,6 +147,8 @@ cdef class Arch:
MIPSEL - MIPS little endian O32 ABI
MIPSEL64 - MIPS little endian 64-bit ABI
MIPSEL64N32 - MIPS little endian N32 ABI
+ PPC64 - 64-bit PowerPC
+ PPC - 32-bit PowerPC
"""
cdef int _token
@@ -163,6 +165,9 @@ cdef class Arch:
MIPSEL = libseccomp.SCMP_ARCH_MIPSEL
MIPSEL64 = libseccomp.SCMP_ARCH_MIPSEL64
MIPSEL64N32 = libseccomp.SCMP_ARCH_MIPSEL64N32
+ PPC = libseccomp.SCMP_ARCH_PPC
+ PPC64 = libseccomp.SCMP_ARCH_PPC64
+ PPC64LE = libseccomp.SCMP_ARCH_PPC64LE
S390 = libseccomp.SCMP_ARCH_S390
S390X = libseccomp.SCMP_ARCH_S390X
@@ -200,6 +205,12 @@ cdef class Arch:
self._token = libseccomp.SCMP_ARCH_MIPSEL64
elif arch == libseccomp.SCMP_ARCH_MIPSEL64N32:
self._token = libseccomp.SCMP_ARCH_MIPSEL64N32
+ elif arch == libseccomp.SCMP_ARCH_PPC:
+ self._token = libseccomp.SCMP_ARCH_PPC
+ elif arch == libseccomp.SCMP_ARCH_PPC64:
+ self._token = libseccomp.SCMP_ARCH_PPC64
+ elif arch == libseccomp.SCMP_ARCH_PPC64LE:
+ self._token = libseccomp.SCMP_ARCH_PPC64LE
elif arch == libseccomp.SCMP_ARCH_S390:
self._token = libseccomp.SCMP_ARCH_S390
elif arch == libseccomp.SCMP_ARCH_S390X:
diff --git a/tests/.gitignore b/tests/.gitignore
index 43ba0c1..e0297ea 100644
--- a/tests/.gitignore
+++ b/tests/.gitignore
@@ -1,6 +1,7 @@
*.bpf
*.bpfd
*.pfc
+miniseq
util.pyc
00-test.c
00-test
@@ -32,3 +33,4 @@ util.pyc
26-sim-arch_all_be_basic
27-sim-bpf_blk_state
28-sim-arch_x86
+29-sim-pseudo_syscall
diff --git a/tests/12-sim-basic_masked_ops.tests b/tests/12-sim-basic_masked_ops.tests
index 9c86490..5f1327f 100644
--- a/tests/12-sim-basic_masked_ops.tests
+++ b/tests/12-sim-basic_masked_ops.tests
@@ -7,38 +7,35 @@
test type: bpf-sim
-# Testname Arch Syscall Arg0 Arg1 Arg2 Arg3 Arg4 Arg5 Result
-12-sim-basic_masked_ops all 1000 0 1 2 N N N ALLOW
-12-sim-basic_masked_ops all 1000 0 0x01 2 N N N ALLOW
-12-sim-basic_masked_ops all 1000 0 0x02-0x0A 2 N N N KILL
-12-sim-basic_masked_ops all 1000 0 0x101 2 N N N ALLOW
-12-sim-basic_masked_ops all 1000 0 11 2 N N N ALLOW
-12-sim-basic_masked_ops all 1000 0 0x0B 2 N N N ALLOW
-12-sim-basic_masked_ops all 1000 0 0x0C-0x6E 2 N N N KILL
-12-sim-basic_masked_ops all 1000 0 0x1000B 2 N N N ALLOW
-12-sim-basic_masked_ops all 1000 0 111 2 N N N ALLOW
-12-sim-basic_masked_ops all 1000 0 0x6F 2 N N N ALLOW
-12-sim-basic_masked_ops all 1000 0 0x70-0x100 2 N N N KILL
-12-sim-basic_masked_ops all 1000 0 0x102-0x200 2 N N N KILL
-12-sim-basic_masked_ops all 1000 0 0x10002-0x1000A 2 N N N KILL
-12-sim-basic_masked_ops all 1000 0 0x1000C-0x1006E 2 N N N KILL
-12-sim-basic_masked_ops all 1000 0 0x1006F 2 N N N ALLOW
-12-sim-basic_masked_ops all 1000 0 1000 2 N N N ALLOW
-12-sim-basic_masked_ops all 1000 0 0x3E8 2 N N N ALLOW
-12-sim-basic_masked_ops all 1000 0 0x2FF 2 N N N KILL
-12-sim-basic_masked_ops all 1000 0 0x300-0x3FF 2 N N N ALLOW
-12-sim-basic_masked_ops all 1000 0 0x400 2 N N N KILL
-12-sim-basic_masked_ops all 1000 0 0x402-0x4FF 2 N N N KILL
-12-sim-basic_masked_ops all 1000 0 0x10300-0x103FF 2 N N N ALLOW
-12-sim-basic_masked_ops all 1000 0 0x00000000F00003E8 2 N N N ALLOW
-12-sim-basic_masked_ops all 1000 0 0x00000000800003E8 2 N N N ALLOW
-12-sim-basic_masked_ops all 1000 0 0x00000001800003E8 2 N N N ALLOW
-12-sim-basic_masked_ops all 1000 0 0x00000001000003E8 2 N N N ALLOW
-12-sim-basic_masked_ops all 1000 0 0x0000000F000003E8 2 N N N ALLOW
-# NOTE: disabling the test below due to problems on 32-bit ARM relating to the
-# shell utilities, see the thread below
-# -> https://groups.google.com/forum/#!topic/libseccomp/VtrClkXxLGA
-#12-sim-basic_masked_ops all 1000 0 0xFFFFFFFFFFFF03E8 2 N N N ALLOW
+# Testname Arch Syscall Arg0 Arg1 Arg2 Arg3 Arg4 Arg5 Result
+12-sim-basic_masked_ops all 1000 0 1 2 N N N ALLOW
+12-sim-basic_masked_ops all 1000 0 0x01 2 N N N ALLOW
+12-sim-basic_masked_ops all 1000 0 0x02-0x0A 2 N N N KILL
+12-sim-basic_masked_ops all 1000 0 0x101 2 N N N ALLOW
+12-sim-basic_masked_ops all 1000 0 11 2 N N N ALLOW
+12-sim-basic_masked_ops all 1000 0 0x0B 2 N N N ALLOW
+12-sim-basic_masked_ops all 1000 0 0x0C-0x6E 2 N N N KILL
+12-sim-basic_masked_ops all 1000 0 0x1000B 2 N N N ALLOW
+12-sim-basic_masked_ops all 1000 0 111 2 N N N ALLOW
+12-sim-basic_masked_ops all 1000 0 0x6F 2 N N N ALLOW
+12-sim-basic_masked_ops all 1000 0 0x70-0x100 2 N N N KILL
+12-sim-basic_masked_ops all 1000 0 0x102-0x200 2 N N N KILL
+12-sim-basic_masked_ops all 1000 0 0x10002-0x1000A 2 N N N KILL
+12-sim-basic_masked_ops all 1000 0 0x1000C-0x1006E 2 N N N KILL
+12-sim-basic_masked_ops all 1000 0 0x1006F 2 N N N ALLOW
+12-sim-basic_masked_ops all 1000 0 1000 2 N N N ALLOW
+12-sim-basic_masked_ops all 1000 0 0x3E8 2 N N N ALLOW
+12-sim-basic_masked_ops all 1000 0 0x2FF 2 N N N KILL
+12-sim-basic_masked_ops all 1000 0 0x300-0x3FF 2 N N N ALLOW
+12-sim-basic_masked_ops all 1000 0 0x400 2 N N N KILL
+12-sim-basic_masked_ops all 1000 0 0x402-0x4FF 2 N N N KILL
+12-sim-basic_masked_ops all 1000 0 0x10300-0x103FF 2 N N N ALLOW
+12-sim-basic_masked_ops all 1000 0 0x00000000F00003E8 2 N N N ALLOW
+12-sim-basic_masked_ops all 1000 0 0x00000000800003E8 2 N N N ALLOW
+12-sim-basic_masked_ops all 1000 0 0x00000001800003E8 2 N N N ALLOW
+12-sim-basic_masked_ops all 1000 0 0x00000001000003E8 2 N N N ALLOW
+12-sim-basic_masked_ops all 1000 0 0x0000000F000003E8 2 N N N ALLOW
+12-sim-basic_masked_ops all 1000 0 0xFFFFFFFFFFFF03E8 2 N N N ALLOW
test type: bpf-sim-fuzz
diff --git a/tests/16-sim-arch_basic.c b/tests/16-sim-arch_basic.c
index 9771913..09df44b 100644
--- a/tests/16-sim-arch_basic.c
+++ b/tests/16-sim-arch_basic.c
@@ -68,6 +68,9 @@ int main(int argc, char *argv[])
rc = seccomp_arch_add(ctx, SCMP_ARCH_MIPSEL64N32);
if (rc != 0)
goto out;
+ rc = seccomp_arch_add(ctx, SCMP_ARCH_PPC64LE);
+ if (rc != 0)
+ goto out;
rc = seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(read), 1,
SCMP_A0(SCMP_CMP_EQ, STDIN_FILENO));
diff --git a/tests/16-sim-arch_basic.py b/tests/16-sim-arch_basic.py
index 57a5ac3..d9e1939 100755
--- a/tests/16-sim-arch_basic.py
+++ b/tests/16-sim-arch_basic.py
@@ -39,6 +39,7 @@ def test(args):
f.add_arch(Arch("mipsel"))
f.add_arch(Arch("mipsel64"))
f.add_arch(Arch("mipsel64n32"))
+ f.add_arch(Arch("ppc64le"))
f.add_rule(ALLOW, "read", Arg(0, EQ, sys.stdin.fileno()))
f.add_rule(ALLOW, "write", Arg(0, EQ, sys.stdout.fileno()))
f.add_rule(ALLOW, "write", Arg(0, EQ, sys.stderr.fileno()))
diff --git a/tests/23-sim-arch_all_le_basic.c b/tests/23-sim-arch_all_le_basic.c
index eeb8556..9f67ed6 100644
--- a/tests/23-sim-arch_all_le_basic.c
+++ b/tests/23-sim-arch_all_le_basic.c
@@ -68,6 +68,9 @@ int main(int argc, char *argv[])
rc = seccomp_arch_add(ctx, seccomp_arch_resolve_name("mipsel64n32"));
if (rc != 0)
goto out;
+ rc = seccomp_arch_add(ctx, seccomp_arch_resolve_name("ppc64le"));
+ if (rc != 0)
+ goto out;
rc = seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(read), 1,
SCMP_A0(SCMP_CMP_EQ, STDIN_FILENO));
diff --git a/tests/23-sim-arch_all_le_basic.py b/tests/23-sim-arch_all_le_basic.py
index 36ab139..212ff50 100755
--- a/tests/23-sim-arch_all_le_basic.py
+++ b/tests/23-sim-arch_all_le_basic.py
@@ -39,6 +39,7 @@ def test(args):
f.add_arch(Arch("mipsel"))
f.add_arch(Arch("mipsel64"))
f.add_arch(Arch("mipsel64n32"))
+ f.add_arch(Arch("ppc64le"))
f.add_rule(ALLOW, "read", Arg(0, EQ, sys.stdin.fileno()))
f.add_rule(ALLOW, "write", Arg(0, EQ, sys.stdout.fileno()))
f.add_rule(ALLOW, "write", Arg(0, EQ, sys.stderr.fileno()))
diff --git a/tests/26-sim-arch_all_be_basic.c b/tests/26-sim-arch_all_be_basic.c
index 6805a40..d2c191c 100644
--- a/tests/26-sim-arch_all_be_basic.c
+++ b/tests/26-sim-arch_all_be_basic.c
@@ -52,6 +52,12 @@ int main(int argc, char *argv[])
rc = seccomp_arch_add(ctx, seccomp_arch_resolve_name("mips64n32"));
if (rc != 0)
goto out;
+ rc = seccomp_arch_add(ctx, seccomp_arch_resolve_name("ppc"));
+ if (rc != 0)
+ goto out;
+ rc = seccomp_arch_add(ctx, seccomp_arch_resolve_name("ppc64"));
+ if (rc != 0)
+ goto out;
rc = seccomp_arch_add(ctx, seccomp_arch_resolve_name("s390"));
if (rc != 0)
goto out;
diff --git a/tests/26-sim-arch_all_be_basic.py b/tests/26-sim-arch_all_be_basic.py
index 3da63f0..b0b660a 100755
--- a/tests/26-sim-arch_all_be_basic.py
+++ b/tests/26-sim-arch_all_be_basic.py
@@ -33,6 +33,8 @@ def test(args):
f.add_arch(Arch("mips"))
f.add_arch(Arch("mips64"))
f.add_arch(Arch("mips64n32"))
+ f.add_arch(Arch("ppc"))
+ f.add_arch(Arch("ppc64"))
f.add_arch(Arch("s390"))
f.add_arch(Arch("s390x"))
f.add_rule(ALLOW, "read", Arg(0, EQ, sys.stdin.fileno()))
diff --git a/tests/29-sim-pseudo_syscall.c b/tests/29-sim-pseudo_syscall.c
new file mode 100644
index 0000000..d909fd8
--- /dev/null
+++ b/tests/29-sim-pseudo_syscall.c
@@ -0,0 +1,71 @@
+/**
+ * Seccomp Library test program
+ *
+ * Copyright (c) 2015 Red Hat <pmoore@redhat.com>
+ * Author: Paul Moore <pmoore@redhat.com>
+ */
+
+/*
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of version 2.1 of the GNU Lesser General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This library 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 this library; if not, see <http://www.gnu.org/licenses>.
+ */
+
+#include <errno.h>
+#include <unistd.h>
+
+#include <seccomp.h>
+
+#include "util.h"
+
+int main(int argc, char *argv[])
+{
+ int rc;
+ struct util_options opts;
+ scmp_filter_ctx ctx = NULL;
+
+ rc = util_getopt(argc, argv, &opts);
+ if (rc < 0)
+ goto out;
+
+ ctx = seccomp_init(SCMP_ACT_ALLOW);
+ if (ctx == NULL)
+ return ENOMEM;
+
+ /* NOTE: we have to be careful here because some ABIs use syscall
+ * offsets which could interfere with our test, x86 is safe */
+ rc = seccomp_arch_remove(ctx, SCMP_ARCH_NATIVE);
+ if (rc < 0)
+ goto out;
+ rc = seccomp_arch_add(ctx, SCMP_ARCH_X86);
+ if (rc < 0)
+ goto out;
+
+ /* SCMP_SYS(sysmips) == 4294957190 (unsigned) */
+ rc = seccomp_rule_add(ctx, SCMP_ACT_KILL, SCMP_SYS(sysmips), 0);
+ if (rc < 0)
+ goto out;
+ rc = seccomp_rule_add_exact(ctx, SCMP_ACT_KILL, SCMP_SYS(sysmips), 0);
+ if (rc == 0)
+ goto out;
+ /* -10001 == 4294957295 (unsigned) */
+ rc = seccomp_rule_add_exact(ctx, SCMP_ACT_KILL, -11001, 0);
+ if (rc == 0)
+ goto out;
+
+ rc = util_filter_output(&opts, ctx);
+ if (rc)
+ goto out;
+
+out:
+ seccomp_release(ctx);
+ return (rc < 0 ? -rc : rc);
+}
diff --git a/tests/29-sim-pseudo_syscall.py b/tests/29-sim-pseudo_syscall.py
new file mode 100644
index 0000000..3d39eaf
--- /dev/null
+++ b/tests/29-sim-pseudo_syscall.py
@@ -0,0 +1,51 @@
+#!/usr/bin/env python
+
+#
+# Seccomp Library test program
+#
+# Copyright (c) 2015 Red Hat <pmoore@redhat.com>
+# Author: Paul Moore <pmoore@redhat.com>
+#
+
+#
+# This library is free software; you can redistribute it and/or modify it
+# under the terms of version 2.1 of the GNU Lesser General Public License as
+# published by the Free Software Foundation.
+#
+# This library 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 this library; if not, see <http://www.gnu.org/licenses>.
+#
+
+import argparse
+import sys
+
+import util
+
+from seccomp import *
+
+def test(args):
+ f = SyscallFilter(ALLOW)
+ f.remove_arch(Arch())
+ f.add_arch(Arch("x86"))
+ f.add_rule(KILL, "sysmips")
+ try:
+ f.add_rule_exactly(KILL, "sysmips")
+ except RuntimeError:
+ pass
+ try:
+ f.add_rule_exactly(KILL, -10001)
+ except RuntimeError:
+ pass
+ return f
+
+args = util.get_opt()
+ctx = test(args)
+util.filter_output(args, ctx)
+
+# kate: syntax python;
+# kate: indent-mode python; space-indent on; indent-width 4; mixedindent off;
diff --git a/tests/29-sim-pseudo_syscall.tests b/tests/29-sim-pseudo_syscall.tests
new file mode 100644
index 0000000..028b858
--- /dev/null
+++ b/tests/29-sim-pseudo_syscall.tests
@@ -0,0 +1,23 @@
+#
+# libseccomp regression test automation data
+#
+# Copyright (c) 2015 Red Hat <pmoore@redhat.com>
+# Author: Paul Moore <pmoore@redhat.com
+#
+
+test type: bpf-sim
+
+# Testname Arch Syscall Arg0 Arg1 Arg2 Arg3 Arg4 Arg5 Result
+29-sim-pseudo_syscall +x86 0-10 N N N N N N ALLOW
+29-sim-pseudo_syscall +x86 4294957190 N N N N N N ALLOW
+29-sim-pseudo_syscall +x86 4294957295 N N N N N N ALLOW
+
+test type: bpf-sim-fuzz
+
+# Testname StressCount
+29-sim-pseudo_syscall 50
+
+test type: bpf-valgrind
+
+# Testname
+29-sim-pseudo_syscall
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 25cef75..71e18ec 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -23,9 +23,12 @@ check_LTLIBRARIES = util.la
util_la_SOURCES = util.c util.h
util_la_LDFLAGS = -module
+miniseq_LDADD =
+
TESTS = regression
check_PROGRAMS = \
+ miniseq \
01-sim-allow \
02-sim-basic \
03-sim-basic_chains \
@@ -53,7 +56,8 @@ check_PROGRAMS = \
25-sim-multilevel_chains_adv \
26-sim-arch_all_be_basic \
27-sim-bpf_blk_state \
- 28-sim-arch_x86
+ 28-sim-arch_x86 \
+ 29-sim-pseudo_syscall
EXTRA_DIST_TESTPYTHON = \
util.py \
@@ -84,7 +88,8 @@ EXTRA_DIST_TESTPYTHON = \
25-sim-multilevel_chains_adv.py \
26-sim-arch_all_be_basic.py \
27-sim-bpf_blk_state.py \
- 28-sim-arch_x86.py
+ 28-sim-arch_x86.py \
+ 29-sim-pseudo_syscall.py
EXTRA_DIST_TESTCFGS = \
01-sim-allow.tests \
@@ -114,7 +119,8 @@ EXTRA_DIST_TESTCFGS = \
25-sim-multilevel_chains_adv.tests \
26-sim-arch_all_be_basic.tests \
27-sim-bpf_blk_state.tests \
- 28-sim-arch_x86.tests
+ 28-sim-arch_x86.tests \
+ 29-sim-pseudo_syscall.tests
EXTRA_DIST_TESTSCRIPTS = regression testdiff testgen
diff --git a/tests/miniseq.c b/tests/miniseq.c
new file mode 100644
index 0000000..7addc70
--- /dev/null
+++ b/tests/miniseq.c
@@ -0,0 +1,57 @@
+/**
+ * Seccomp Library test support program
+ *
+ * Copyright (c) 2015 Mathias Krause <minipli@googlemail.com>
+ */
+
+/*
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of version 2.1 of the GNU Lesser General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This library 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 this library; if not, see <http://www.gnu.org/licenses>.
+ */
+
+#include <inttypes.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <errno.h>
+
+static int get_number(char *str, uint64_t *res)
+{
+ char *end = str;
+
+ errno = 0;
+ *res = strtoull(str, &end, 0);
+ if (errno || *end != '\0') {
+ fprintf(stderr, "error: failed to convert '%s'\n", str);
+ return -1;
+ }
+
+ return 0;
+}
+
+int main(int argc, char *argv[])
+{
+ uint64_t first, last, cur;
+
+ if (argc != 3) {
+ fprintf(stderr, "usage: %s FIRST LAST\n", argv[0]);
+ return 1;
+ }
+
+ if (get_number(argv[1], &first) || get_number(argv[2], &last))
+ return 1;
+
+ for (cur = first; cur <= last; cur++)
+ printf("%" PRIu64 "\n", cur);
+
+ return 0;
+}
diff --git a/tests/regression b/tests/regression
index b56dd58..53d26b2 100755
--- a/tests/regression
+++ b/tests/regression
@@ -21,8 +21,15 @@
# along with this library; if not, see <http://www.gnu.org/licenses>.
#
-GLBL_ARCH_LE_SUPPORT="x86 x86_64 x32 arm aarch64 mipsel mipsel64 mipsel64n32"
-GLBL_ARCH_BE_SUPPORT="mips mips64 mips64n32 s390 s390x"
+GLBL_ARCH_LE_SUPPORT=" \
+ x86 x86_64 x32 \
+ arm aarch64 \
+ mipsel mipsel64 mipsel64n32 \
+ ppc64le"
+GLBL_ARCH_BE_SUPPORT=" \
+ mips mips64 mips64n32 \
+ ppc ppc64 \
+ s390 s390x"
GLBL_SYS_ARCH="../tools/scmp_arch_detect"
GLBL_SYS_RESOLVER="../tools/scmp_sys_resolver"
@@ -164,6 +171,33 @@ function get_range() {
}
#
+# Get the number sequence for a given range with increments of 1, i.e.
+# implement a specialized seq(1).
+#
+# We use our own implementation based on miniseq in favour to the standard seq
+# tool as, at least, seq of coreutils v8.23 and v8.24 has problems on 32 bit
+# ARM for large numbers (see the mailing thread at
+# https://groups.google.com/forum/#!topic/libseccomp/VtrClkXxLGA).
+#
+# Arguments:
+# 1 starting value
+# 2 last value
+#
+function get_seq() {
+ # NOTE: this whole thing is a bit hacky, but we need to search around
+ # for miniseq to fix 'make distcheck', someday we should fix this
+ if [[ -x ./miniseq ]]; then
+ ./miniseq "$1" "$2"
+ elif [[ -x $basedir/miniseq ]]; then
+ $basedir/miniseq "$1" "$2"
+ else
+ # we're often run from a subshell, so we can't simply exit
+ echo "error: unable to find miniseq" >&2
+ kill $pid
+ fi
+}
+
+#
# Run the specified test command (with valgrind if requested)
#
# Arguments:
@@ -245,7 +279,7 @@ function run_test_bpf_sim_fuzz() {
local testname=${line[0]}
local stress_count=${line[1]}
- for i in $(seq 1 $stress_count); do
+ for i in $(get_seq 1 $stress_count); do
local sys=$(generate_random_data)
local -a arg=($(generate_random_data) $(generate_random_data) \
$(generate_random_data) $(generate_random_data) \
@@ -462,13 +496,13 @@ function run_test_bpf_sim() {
# and arg ranges and generate/run every combination of requested
# tests; if no ranges were specifed, then the single test is
# run
- for sys in $(seq -f "%1.0f" $low_syscall $high_syscall); do
- for arg0 in $(seq -f "%1.0f" ${low_arg[0]} ${high_arg[0]}); do
- for arg1 in $(seq -f "%1.0f" ${low_arg[1]} ${high_arg[1]}); do
- for arg2 in $(seq -f "%1.0f" ${low_arg[2]} ${high_arg[2]}); do
- for arg3 in $(seq -f "%1.0f" ${low_arg[3]} ${high_arg[3]}); do
- for arg4 in $(seq -f "%1.0f" ${low_arg[4]} ${high_arg[4]}); do
- for arg5 in $(seq -f "%1.0f" ${low_arg[5]} ${high_arg[5]}); do
+ for sys in $(get_seq $low_syscall $high_syscall); do
+ for arg0 in $(get_seq ${low_arg[0]} ${high_arg[0]}); do
+ for arg1 in $(get_seq ${low_arg[1]} ${high_arg[1]}); do
+ for arg2 in $(get_seq ${low_arg[2]} ${high_arg[2]}); do
+ for arg3 in $(get_seq ${low_arg[3]} ${high_arg[3]}); do
+ for arg4 in $(get_seq ${low_arg[4]} ${high_arg[4]}); do
+ for arg5 in $(get_seq ${low_arg[5]} ${high_arg[5]}); do
local -a arg=($arg0 $arg1 $arg2 $arg3 $arg4 $arg5)
# Get the generated sub-test num string
@@ -667,7 +701,7 @@ function run_test_live() {
# setup the arch specific return values
case "$arch" in
- x86|x86_64|x32|arm|aarch64|s390x|s390)
+ x86|x86_64|x32|arm|aarch64|ppc|ppc64|ppc64le|ppc|s390|s390x)
rc_kill=159
rc_allow=160
rc_trap=161
@@ -827,7 +861,6 @@ function run_tests() {
verify_deps head
verify_deps sed
verify_deps awk
-verify_deps seq
verify_deps tr
# global variables
@@ -853,6 +886,9 @@ stats_error=0
# set the test root directory
basedir=$(dirname $0)
+# set the test harness pid
+pid=$$
+
# parse the command line
while getopts "ab:gl:m:s:t:T:vh" opt; do
case $opt in
diff --git a/tools/scmp_arch_detect.c b/tools/scmp_arch_detect.c
index adf624f..51c45c9 100644
--- a/tools/scmp_arch_detect.c
+++ b/tools/scmp_arch_detect.c
@@ -99,6 +99,15 @@ int main(int argc, char *argv[])
case SCMP_ARCH_MIPSEL64N32:
printf("mipsel64n32\n");
break;
+ case SCMP_ARCH_PPC:
+ printf("ppc\n");
+ break;
+ case SCMP_ARCH_PPC64:
+ printf("ppc64\n");
+ break;
+ case SCMP_ARCH_PPC64LE:
+ printf("ppc64le\n");
+ break;
case SCMP_ARCH_S390:
printf("s390\n");
break;
diff --git a/tools/scmp_bpf_disasm.c b/tools/scmp_bpf_disasm.c
index 349b8a8..d0fb16d 100644
--- a/tools/scmp_bpf_disasm.c
+++ b/tools/scmp_bpf_disasm.c
@@ -24,6 +24,7 @@
#include <inttypes.h>
#include <limits.h>
#include <stdlib.h>
+#include <stdbool.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
@@ -37,13 +38,26 @@
#define _OP_FMT "%-3s"
/**
+ * Print the usage information to stderr and exit
+ * @param program the name of the current program being invoked
+ *
+ * Print the usage information and exit with EINVAL.
+ *
+ */
+static void exit_usage(const char *program)
+{
+ fprintf(stderr, "usage: %s -a <arch> [-d] [-h]\n", program);
+ exit(EINVAL);
+}
+
+/**
* Decode the BPF operand
* @param bpf the BPF instruction
*
* Decode the BPF operand and print it to stdout.
*
*/
-static void bpf_decode_op(const bpf_instr_raw *bpf)
+static const char *bpf_decode_op(const bpf_instr_raw *bpf)
{
switch (bpf->code) {
case BPF_LD+BPF_W+BPF_IMM:
@@ -52,24 +66,21 @@ static void bpf_decode_op(const bpf_instr_raw *bpf)
case BPF_LD+BPF_W+BPF_MEM:
case BPF_LD+BPF_W+BPF_LEN:
case BPF_LD+BPF_W+BPF_MSH:
- printf(_OP_FMT, "ld");
- break;
+ return "ld";
case BPF_LD+BPF_H+BPF_IMM:
case BPF_LD+BPF_H+BPF_ABS:
case BPF_LD+BPF_H+BPF_IND:
case BPF_LD+BPF_H+BPF_MEM:
case BPF_LD+BPF_H+BPF_LEN:
case BPF_LD+BPF_H+BPF_MSH:
- printf(_OP_FMT, "ldh");
- break;
+ return "ldh";
case BPF_LD+BPF_B+BPF_IMM:
case BPF_LD+BPF_B+BPF_ABS:
case BPF_LD+BPF_B+BPF_IND:
case BPF_LD+BPF_B+BPF_MEM:
case BPF_LD+BPF_B+BPF_LEN:
case BPF_LD+BPF_B+BPF_MSH:
- printf(_OP_FMT, "ldb");
- break;
+ return "ldb";
case BPF_LDX+BPF_W+BPF_IMM:
case BPF_LDX+BPF_W+BPF_ABS:
case BPF_LDX+BPF_W+BPF_IND:
@@ -88,83 +99,95 @@ static void bpf_decode_op(const bpf_instr_raw *bpf)
case BPF_LDX+BPF_B+BPF_MEM:
case BPF_LDX+BPF_B+BPF_LEN:
case BPF_LDX+BPF_B+BPF_MSH:
- printf(_OP_FMT, "ldx");
- break;
+ return "ldx";
case BPF_ST:
- printf(_OP_FMT, "st");
- break;
+ return "st";
case BPF_STX:
- printf(_OP_FMT, "stx");
- break;
+ return "stx";
case BPF_ALU+BPF_ADD+BPF_K:
case BPF_ALU+BPF_ADD+BPF_X:
- printf(_OP_FMT, "add");
- break;
+ return "add";
case BPF_ALU+BPF_SUB+BPF_K:
case BPF_ALU+BPF_SUB+BPF_X:
- printf(_OP_FMT, "sub");
- break;
+ return "sub";
case BPF_ALU+BPF_MUL+BPF_K:
case BPF_ALU+BPF_MUL+BPF_X:
- printf(_OP_FMT, "mul");
- break;
+ return "mul";
case BPF_ALU+BPF_DIV+BPF_K:
case BPF_ALU+BPF_DIV+BPF_X:
- printf(_OP_FMT, "div");
- break;
+ return "div";
case BPF_ALU+BPF_OR+BPF_K:
case BPF_ALU+BPF_OR+BPF_X:
- printf(_OP_FMT, "or");
- break;
+ return "or";
case BPF_ALU+BPF_AND+BPF_K:
case BPF_ALU+BPF_AND+BPF_X:
- printf(_OP_FMT, "and");
- break;
+ return "and";
case BPF_ALU+BPF_LSH+BPF_K:
case BPF_ALU+BPF_LSH+BPF_X:
- printf(_OP_FMT, "lsh");
- break;
+ return "lsh";
case BPF_ALU+BPF_RSH+BPF_K:
case BPF_ALU+BPF_RSH+BPF_X:
- printf(_OP_FMT, "rsh");
- break;
+ return "rsh";
case BPF_ALU+BPF_NEG+BPF_K:
case BPF_ALU+BPF_NEG+BPF_X:
- printf(_OP_FMT, "neg");
- break;
+ return "neg";
case BPF_JMP+BPF_JA+BPF_K:
case BPF_JMP+BPF_JA+BPF_X:
- printf(_OP_FMT, "jmp");
- break;
+ return "jmp";
case BPF_JMP+BPF_JEQ+BPF_K:
case BPF_JMP+BPF_JEQ+BPF_X:
- printf(_OP_FMT, "jeq");
- break;
+ return "jeq";
case BPF_JMP+BPF_JGT+BPF_K:
case BPF_JMP+BPF_JGT+BPF_X:
- printf(_OP_FMT, "jgt");
- break;
+ return "jgt";
case BPF_JMP+BPF_JGE+BPF_K:
case BPF_JMP+BPF_JGE+BPF_X:
- printf(_OP_FMT, "jge");
- break;
+ return "jge";
case BPF_JMP+BPF_JSET+BPF_K:
case BPF_JMP+BPF_JSET+BPF_X:
- printf(_OP_FMT, "jset");
- break;
+ return "jset";
case BPF_RET+BPF_K:
case BPF_RET+BPF_X:
case BPF_RET+BPF_A:
- printf(_OP_FMT, "ret");
- break;
+ return "ret";
case BPF_MISC+BPF_TAX:
- printf(_OP_FMT, "tax");
- break;
+ return "tax";
case BPF_MISC+BPF_TXA:
- printf(_OP_FMT, "txa");
+ return "txa";
+ }
+ return "???";
+}
+
+/**
+ * Decode a RET action
+ * @param k the return action
+ *
+ * Decode the action and print it to stdout.
+ *
+ */
+static void bpf_decode_action(uint32_t k)
+{
+ uint32_t act = k & SECCOMP_RET_ACTION;
+ uint32_t data = k & SECCOMP_RET_DATA;
+
+ switch (act) {
+ case SECCOMP_RET_KILL:
+ printf("KILL");
+ break;
+ case SECCOMP_RET_TRAP:
+ printf("TRAP");
+ break;
+ case SECCOMP_RET_ERRNO:
+ printf("ERRNO(%u)", data);
+ break;
+ case SECCOMP_RET_TRACE:
+ printf("TRACE(%u)", data);
+ break;
+ case SECCOMP_RET_ALLOW:
+ printf("ALLOW");
break;
default:
- printf(_OP_FMT, "???");
+ printf("0x%.8x", k);
}
}
@@ -189,6 +212,18 @@ static void bpf_decode_args(const bpf_instr_raw *bpf, unsigned int line)
case BPF_MEM:
printf("$temp[%u]", bpf->k);
break;
+ case BPF_IMM:
+ printf("%u", bpf->k);
+ break;
+ case BPF_IND:
+ printf("$data[X + %u]", bpf->k);
+ break;
+ case BPF_LEN:
+ printf("len($data)");
+ break;
+ case BPF_MSH:
+ printf("4 * $data[%u] & 0x0f", bpf->k);
+ break;
}
break;
case BPF_ST:
@@ -223,28 +258,7 @@ static void bpf_decode_args(const bpf_instr_raw *bpf, unsigned int line)
/* XXX - accumulator? */
printf("$acc");
} else if (BPF_SRC(bpf->code) == BPF_K) {
- uint32_t act = bpf->k & SECCOMP_RET_ACTION;
- uint32_t data = bpf->k & SECCOMP_RET_DATA;
-
- switch (act) {
- case SECCOMP_RET_KILL:
- printf("KILL");
- break;
- case SECCOMP_RET_TRAP:
- printf("TRAP");
- break;
- case SECCOMP_RET_ERRNO:
- printf("ERRNO(%u)", data);
- break;
- case SECCOMP_RET_TRACE:
- printf("TRACE(%u)", data);
- break;
- case SECCOMP_RET_ALLOW:
- printf("ALLOW");
- break;
- default:
- printf("0x%.8x", bpf->k);
- }
+ bpf_decode_action(bpf->k);
} else if (BPF_SRC(bpf->code) == BPF_X) {
/* XXX - any idea? */
printf("???");
@@ -286,7 +300,7 @@ static int bpf_decode(FILE *file)
/* display the assembler statements */
printf(" ");
- bpf_decode_op(&bpf);
+ printf(_OP_FMT, bpf_decode_op(&bpf));
printf(" ");
bpf_decode_args(&bpf, line);
printf("\n");
@@ -300,16 +314,154 @@ static int bpf_decode(FILE *file)
}
/**
+ * Decode the BPF arguments (JT, JF, and K)
+ * @param bpf the BPF instruction
+ * @param line the current line number
+ *
+ * Decode the BPF arguments (JT, JF, and K) and print the relevant information
+ * to stdout based on the operand.
+ *
+ */
+static void bpf_dot_decode_args(const bpf_instr_raw *bpf, unsigned int line)
+{
+ const char *op = bpf_decode_op(bpf);
+
+ printf("\tline%d[label=\"%s", line, op);
+ switch (BPF_CLASS(bpf->code)) {
+ case BPF_LD:
+ case BPF_LDX:
+ switch (BPF_MODE(bpf->code)) {
+ case BPF_ABS:
+ printf(" $data[%u]\",shape=parallelogram]\n", bpf->k);
+ break;
+ case BPF_MEM:
+ printf(" $temp[%u]\",shape=parallelogram]\n", bpf->k);
+ break;
+ case BPF_IMM:
+ printf(" %u\",shape=parallelogram]\n", bpf->k);
+ break;
+ case BPF_IND:
+ printf(" $data[X + %u]\",shape=parallelogram]\n", bpf->k);
+ break;
+ case BPF_LEN:
+ printf(" len($data)\",shape=parallelogram]\n");
+ break;
+ case BPF_MSH:
+ printf(" 4 * $data[%u] & 0x0f\",shape=parallelogram]\n", bpf->k);
+ break;
+ }
+ break;
+ case BPF_ST:
+ case BPF_STX:
+ printf(" $temp[%u]\",shape=parallelogram]\n",
+ bpf->k);
+ break;
+ case BPF_ALU:
+ if (BPF_SRC(bpf->code) == BPF_K) {
+ switch (BPF_OP(bpf->code)) {
+ case BPF_OR:
+ case BPF_AND:
+ printf(" 0x%.8x\",shape=rectangle]\n", bpf->k);
+ break;
+ default:
+ printf(" %u\",shape=rectangle]\n", bpf->k);
+ }
+ } else
+ printf(" %u\",shape=rectangle]\n", bpf->k);
+ break;
+ case BPF_JMP:
+ if (BPF_OP(bpf->code) == BPF_JA) {
+ printf("\",shape=hexagon]\n");
+ printf("\tline%d -> line%d\n",
+ line, (line + 1) + bpf->k);
+ } else {
+ printf(" %-4u", bpf->k);
+ /* Heuristic: if k > 256, also emit hex version */
+ if (bpf->k > 256)
+ printf("\\n(0x%.8x)", bpf->k);
+ printf("\",shape=diamond]\n");
+ printf("\tline%d -> line%d [label=\"true\"]\n",
+ line, (line + 1) + bpf->jt);
+ printf("\tline%d -> line%d [label=\"false\"]\n",
+ line, (line + 1) + bpf->jf);
+ }
+ break;
+ case BPF_RET:
+ if (BPF_RVAL(bpf->code) == BPF_A) {
+ /* XXX - accumulator? */
+ printf(" $acc\", shape=\"box\", style=rounded]\n");
+ } else if (BPF_SRC(bpf->code) == BPF_K) {
+ printf(" ");
+ bpf_decode_action(bpf->k);
+ printf("\", shape=\"box\", style=rounded]\n");
+ } else if (BPF_SRC(bpf->code) == BPF_X) {
+ /* XXX - any idea? */
+ printf(" ???\", shape=\"box\", style=rounded]\n");
+ }
+ break;
+ case BPF_MISC:
+ printf("\"]\n");
+ break;
+ default:
+ printf(" ???\"]\n");
+ }
+}
+
+/**
+ * Perform a simple decoding of the BPF program to a dot graph
+ * @param file the BPF program
+ *
+ * Read the BPF program and display the instructions. Returns zero on success,
+ * negative values on failure.
+ *
+ */
+static int bpf_dot_decode(FILE *file)
+{
+ unsigned int line = 0;
+ size_t len;
+ bpf_instr_raw bpf;
+ int prev_class = 0;
+
+ /* header */
+ printf("digraph {\n");
+ printf("\tstart[shape=\"box\", style=rounded];\n");
+
+ while ((len = fread(&bpf, sizeof(bpf), 1, file))) {
+ /* convert the bpf statement */
+ bpf.code = ttoh16(arch, bpf.code);
+ bpf.k = ttoh32(arch, bpf.k);
+
+ /* display the statement */
+ bpf_dot_decode_args(&bpf, line);
+
+ /* if previous line wasn't RET/JMP, link it to this line */
+ if (line == 0)
+ printf("\tstart -> line%d\n", line);
+ else if ((prev_class != BPF_JMP) && (prev_class != BPF_RET))
+ printf("\tline%d -> line%d\n", line - 1, line);
+ prev_class = BPF_CLASS(bpf.code);
+
+ line++;
+ }
+ printf("}\n");
+
+ if (ferror(file))
+ return errno;
+ return 0;
+}
+
+/**
* main
*/
int main(int argc, char *argv[])
{
int rc;
int opt;
+ bool dot_out = false;
FILE *file;
/* parse the command line */
- while ((opt = getopt(argc, argv, "a:h")) > 0) {
+ while ((opt = getopt(argc, argv, "a:dh")) > 0) {
switch (opt) {
case 'a':
if (strcmp(optarg, "x86") == 0)
@@ -334,9 +486,18 @@ int main(int argc, char *argv[])
arch = AUDIT_ARCH_MIPS64N32;
else if (strcmp(optarg, "mipsel64n32") == 0)
arch = AUDIT_ARCH_MIPSEL64N32;
+ else if (strcmp(optarg, "ppc64") == 0)
+ arch = AUDIT_ARCH_PPC64;
+ else if (strcmp(optarg, "ppc64le") == 0)
+ arch = AUDIT_ARCH_PPC64LE;
+ else if (strcmp(optarg, "ppc") == 0)
+ arch = AUDIT_ARCH_PPC;
else
exit_usage(argv[0]);
break;
+ case 'd':
+ dot_out = true;
+ break;
default:
/* usage information */
exit_usage(argv[0]);
@@ -354,7 +515,10 @@ int main(int argc, char *argv[])
} else
file = stdin;
- rc = bpf_decode(file);
+ if (dot_out)
+ rc = bpf_dot_decode(file);
+ else
+ rc = bpf_decode(file);
fclose(file);
return rc;
diff --git a/tools/scmp_bpf_sim.c b/tools/scmp_bpf_sim.c
index c4334b1..ddd216c 100644
--- a/tools/scmp_bpf_sim.c
+++ b/tools/scmp_bpf_sim.c
@@ -52,6 +52,22 @@ struct bpf_program {
static unsigned int opt_verbose = 0;
/**
+ * Print the usage information to stderr and exit
+ * @param program the name of the current program being invoked
+ *
+ * Print the usage information and exit with EINVAL.
+ *
+ */
+static void exit_usage(const char *program)
+{
+ fprintf(stderr,
+ "usage: %s -f <bpf_file> [-v] [-h]"
+ " -a <arch> -s <syscall_num> [-0 <a0>] ... [-5 <a5>]\n",
+ program);
+ exit(EINVAL);
+}
+
+/**
* Handle a simulator fault
* @param rc the error or return code
*
@@ -224,7 +240,7 @@ int main(int argc, char *argv[])
memset(&sys_data, 0, sizeof(sys_data));
/* parse the command line */
- while ((opt = getopt(argc, argv, "a:f:h:s:v0:1:2:3:4:5:")) > 0) {
+ while ((opt = getopt(argc, argv, "a:f:hs:v0:1:2:3:4:5:")) > 0) {
switch (opt) {
case 'a':
if (strcmp(optarg, "x86") == 0)
@@ -249,6 +265,12 @@ int main(int argc, char *argv[])
arch = AUDIT_ARCH_MIPS64N32;
else if (strcmp(optarg, "mipsel64n32") == 0)
arch = AUDIT_ARCH_MIPSEL64N32;
+ else if (strcmp(optarg, "ppc") == 0)
+ arch = AUDIT_ARCH_PPC;
+ else if (strcmp(optarg, "ppc64") == 0)
+ arch = AUDIT_ARCH_PPC64;
+ else if (strcmp(optarg, "ppc64le") == 0)
+ arch = AUDIT_ARCH_PPC64LE;
else if (strcmp(optarg, "s390") == 0)
arch = AUDIT_ARCH_S390;
else if (strcmp(optarg, "s390x") == 0)
diff --git a/tools/util.c b/tools/util.c
index 6c44d35..5b21559 100644
--- a/tools/util.c
+++ b/tools/util.c
@@ -62,6 +62,14 @@
#elif __MIPSEL__
#define ARCH_NATIVE AUDIT_ARCH_MIPSEL64N32
#endif /* _MIPS_SIM_NABI32 */
+#elif __PPC64__
+#ifdef __BIG_ENDIAN__
+#define ARCH_NATIVE AUDIT_ARCH_PPC64
+#else
+#define ARCH_NATIVE AUDIT_ARCH_PPC64LE
+#endif
+#elif __PPC__
+#define ARCH_NATIVE AUDIT_ARCH_PPC
#elif __s390x__ /* s390x must be checked before s390 */
#define ARCH_NATIVE AUDIT_ARCH_S390X
#elif __s390__
@@ -74,22 +82,6 @@
uint32_t arch = ARCH_NATIVE;
/**
- * Print the usage information to stderr and exit
- * @param program the name of the current program being invoked
- *
- * Print the usage information and exit with EINVAL.
- *
- */
-void exit_usage(const char *program)
-{
- fprintf(stderr,
- "usage: %s -f <bpf_file> [-v]"
- " -a <arch> -s <syscall_num> [-0 <a0>] ... [-5 <a5>]\n",
- program);
- exit(EINVAL);
-}
-
-/**
* Convert a 16-bit target integer into the host's endianess
* @param arch the architecture token
* @param val the 16-bit integer
diff --git a/tools/util.h b/tools/util.h
index 4ec3f91..92bff91 100644
--- a/tools/util.h
+++ b/tools/util.h
@@ -63,9 +63,16 @@
__AUDIT_ARCH_CONVENTION_MIPS64_N32)
#endif
-extern uint32_t arch;
+#ifndef AUDIT_ARCH_AARCH64
+/* AArch64 support for audit was merged in 3.17-rc1 */
+#define AUDIT_ARCH_AARCH64 (EM_AARCH64|__AUDIT_ARCH_64BIT|__AUDIT_ARCH_LE)
+#endif
+
+#ifndef AUDIT_ARCH_PPC64LE
+#define AUDIT_ARCH_PPC64LE (EM_PPC64|__AUDIT_ARCH_64BIT|__AUDIT_ARCH_LE)
+#endif
-void exit_usage(const char *program);
+extern uint32_t arch;
uint16_t ttoh16(uint32_t arch, uint16_t val);
uint32_t ttoh32(uint32_t arch, uint32_t val);