summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CHANGELOG23
-rw-r--r--CREDITS4
-rw-r--r--README21
-rw-r--r--include/seccomp.h.in88
-rw-r--r--src/Makefile.am1
-rw-r--r--src/api.c2
-rw-r--r--src/arch-aarch64-syscalls.c4
-rw-r--r--src/arch-arm-syscalls.c29
-rw-r--r--src/arch-mips-syscalls.c4
-rw-r--r--src/arch-mips64-syscalls.c4
-rw-r--r--src/arch-mips64n32-syscalls.c4
-rwxr-xr-xsrc/arch-syscall-validate109
-rw-r--r--src/arch-x32-syscalls.c4
-rw-r--r--src/arch-x86-syscalls.c4
-rw-r--r--src/arch-x86_64-syscalls.c4
-rw-r--r--src/arch.c2
-rw-r--r--src/db.c61
-rw-r--r--src/db.h2
-rw-r--r--src/gen_bpf.c214
-rw-r--r--src/gen_pfc.c5
-rw-r--r--src/hash.c6
-rw-r--r--src/python/seccomp.pyx2
-rw-r--r--tests/.gitignore4
-rwxr-xr-xtests/02-sim-basic.py8
-rwxr-xr-xtests/03-sim-basic_chains.py10
-rwxr-xr-xtests/04-sim-multilevel_chains.py14
-rw-r--r--tests/12-sim-basic_masked_ops.tests6
-rw-r--r--tests/15-basic-resolver.c31
-rwxr-xr-xtests/18-sim-basic_whitelist.py10
-rwxr-xr-xtests/22-sim-basic_chains_array.py10
-rwxr-xr-xtests/25-sim-multilevel_chains_adv.py4
-rw-r--r--tests/27-sim-bpf_blk_state.c103
-rwxr-xr-xtests/27-sim-bpf_blk_state.py53
-rw-r--r--tests/27-sim-bpf_blk_state.tests24
-rw-r--r--tests/28-sim-arch_x86.c71
-rw-r--r--tests/28-sim-arch_x86.py47
-rw-r--r--tests/28-sim-arch_x86.tests27
-rw-r--r--tests/Makefile.am15
-rw-r--r--tests/miniseq.c57
-rwxr-xr-xtests/regression34
-rw-r--r--tools/Makefile.am2
-rwxr-xr-xtools/check-syntax64
-rw-r--r--tools/util.h30
43 files changed, 1027 insertions, 194 deletions
diff --git a/CHANGELOG b/CHANGELOG
index 4442bf0..b53c172 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -2,6 +2,21 @@ libseccomp: Releases
===============================================================================
https://github.com/seccomp/libseccomp
+* Version 2.2.3 - July 8, 2015
+- Fix a problem with 'make check' on 32-bit ARM systems
+
+* Version 2.2.2 - July 6, 2015
+- Fix a problem with the masked equality operator
+- Fix a problem on x86_64/x32 involving invalid architectures
+- Fix a problem with the ARM specific syscalls
+- Fix a build problem when the source and build directories differ
+
+* Version 2.2.1 - May 13, 2015
+- Fix a problem with syscall argument filtering on 64-bit systems
+- Fix some problems with the 32-bit ARM syscall table
+- Fix build problems on very old systems
+- Update the README file with the GitHub and Google Groups information
+
* Version 2.2.0 - February 12, 2015
- Migrated the build system to autotools
- Added support for the aarch64 architecture
@@ -12,12 +27,12 @@ https://github.com/seccomp/libseccomp
- Added Python bindings
- Updated the internal syscall tables to Linux v3.19
- Added documentation to help contributors wishing to submit patches
-- Migrated to Github for git hosting and Google Groups for the mailing list
+- Migrated to GitHub for git hosting and Google Groups for the mailing list
- Numerous minor bug fixes
* Version 2.1.1 - October 31, 2013
- Build system improvements
-- Automated test improvments, including a "check" target for use by
+- Automated test improvements, including a "check" target for use by
packagers to verify the build
- Numerous bug fixes related to the filter's internal rule database which
affect those creating rules with syscall arguments
@@ -34,8 +49,8 @@ https://github.com/seccomp/libseccomp
* Version 2.0.0 - January 28, 2013
- Fixes for the x86 multiplexed syscalls
-- Additions to the API to better support non-native architecures
-- Additions to the API to support multiple architecures in one filter
+- Additions to the API to better support non-native architectures
+- Additions to the API to support multiple architectures in one filter
- Additions to the API to resolve syscall name/number mappings
- Assorted minor bug fixes
- Improved build messages regardless of build verbosity
diff --git a/CREDITS b/CREDITS
index 327186c..370b12a 100644
--- a/CREDITS
+++ b/CREDITS
@@ -2,8 +2,10 @@ libseccomp: Contributors
===============================================================================
https://github.com/seccomp/libseccomp
+Andrew Jones <drjones@redhat.com>
Andy Lutomirski <luto@amacapital.net>
Ashley Lai <adlai@us.ibm.com>
+Colin Walters <walters@verbum.org>
Corey Bryant <coreyb@linux.vnet.ibm.com>
Eduardo Otubo <otubo@linux.vnet.ibm.com>
Eric Paris <eparis@redhat.com>
@@ -14,7 +16,9 @@ Kees Cook <keescook@chromium.org>
Marcin Juszkiewicz <mjuszkiewicz@redhat.com>
Marcus Meissner <meissner@suse.de>
Markos Chandras <markos.chandras@imgtec.com>
+Mathias Krause <minipli@googlemail.com>
Michael Forney <mforney@mforney.org>
+Mike Strosaker <strosake@linux.vnet.ibm.com>
Paul Moore <pmoore@redhat.com>
Serge Hallyn <serge.hallyn@ubuntu.com>
Thiago Marcos P. Santos <thiago.santos@intel.com>
diff --git a/README b/README
index 9dfa309..a469e96 100644
--- a/README
+++ b/README
@@ -8,6 +8,18 @@ designed to abstract away the underlying BPF based syscall filter language and
present a more conventional function-call based filtering interface that should
be familiar to, and easily adopted by, application developers.
+* Online Resources
+
+The library source repository currently lives on GitHub at the following URL:
+
+ -> https://github.com/seccomp/libseccomp
+
+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
+
* Documentation
The "doc/" directory contains all of the currently available documentation,
@@ -20,14 +32,17 @@ read the SUBMITTING_PATCHES in the top level directory.
* Building and Installing the Library
-In order to build the library you should follow the familiar three step
-process used by most autotools based applications:
+If you are building the libseccomp library from an official release tarball,
+you should follow the familiar three step process used by most autotools based
+applications:
# ./configure
# make [V=0|1]
# make install
-As usual, running "./configure -h" will display a list of build-time
+However, if you are building the library from sources retrieved from the source
+repository you may need to run the autogen.sh script before running configure.
+In both cases, running "./configure -h" will display a list of build-time
configuration options.
* Testing the Library
diff --git a/include/seccomp.h.in b/include/seccomp.h.in
index 3af4c2b..d100dc8 100644
--- a/include/seccomp.h.in
+++ b/include/seccomp.h.in
@@ -121,10 +121,13 @@ struct scmp_arg_cmp {
* The ARM architecture tokens
*/
#define SCMP_ARCH_ARM AUDIT_ARCH_ARM
-#ifndef AUDIT_ARCH_AARCH64
/* AArch64 support for audit was merged in 3.17-rc1 */
+#ifndef AUDIT_ARCH_AARCH64
+#ifndef EM_AARCH64
+#define EM_AARCH64 183
+#endif /* EM_AARCH64 */
#define AUDIT_ARCH_AARCH64 (EM_AARCH64|__AUDIT_ARCH_64BIT|__AUDIT_ARCH_LE)
-#endif
+#endif /* AUDIT_ARCH_AARCH64 */
#define SCMP_ARCH_AARCH64 AUDIT_ARCH_AARCH64
/**
@@ -133,21 +136,30 @@ struct scmp_arg_cmp {
#ifndef __AUDIT_ARCH_CONVENTION_MIPS64_N32
#define __AUDIT_ARCH_CONVENTION_MIPS64_N32 0x20000000
#endif
-#define SCMP_ARCH_MIPS AUDIT_ARCH_MIPS
-#define SCMP_ARCH_MIPS64 AUDIT_ARCH_MIPS64
-#ifndef AUDIT_ARCH_MIPS64N32
+#ifndef EM_MIPS
+#define EM_MIPS 8
+#endif
+#ifndef AUDIT_ARCH_MIPS
+#define AUDIT_ARCH_MIPS (EM_MIPS)
+#endif
+#ifndef AUDIT_ARCH_MIPS64
+#define AUDIT_ARCH_MIPS64 (EM_MIPS|__AUDIT_ARCH_64BIT)
+#endif
/* MIPS64N32 support was merged in 3.15 */
+#ifndef AUDIT_ARCH_MIPS64N32
#define AUDIT_ARCH_MIPS64N32 (EM_MIPS|__AUDIT_ARCH_64BIT|\
__AUDIT_ARCH_CONVENTION_MIPS64_N32)
#endif
-#define SCMP_ARCH_MIPS64N32 AUDIT_ARCH_MIPS64N32
-#define SCMP_ARCH_MIPSEL AUDIT_ARCH_MIPSEL
-#define SCMP_ARCH_MIPSEL64 AUDIT_ARCH_MIPSEL64
-#ifndef AUDIT_ARCH_MIPSEL64N32
/* MIPSEL64N32 support was merged in 3.15 */
+#ifndef AUDIT_ARCH_MIPSEL64N32
#define AUDIT_ARCH_MIPSEL64N32 (EM_MIPS|__AUDIT_ARCH_64BIT|__AUDIT_ARCH_LE|\
__AUDIT_ARCH_CONVENTION_MIPS64_N32)
#endif
+#define SCMP_ARCH_MIPS AUDIT_ARCH_MIPS
+#define SCMP_ARCH_MIPS64 AUDIT_ARCH_MIPS64
+#define SCMP_ARCH_MIPS64N32 AUDIT_ARCH_MIPS64N32
+#define SCMP_ARCH_MIPSEL AUDIT_ARCH_MIPSEL
+#define SCMP_ARCH_MIPSEL64 AUDIT_ARCH_MIPSEL64
#define SCMP_ARCH_MIPSEL64N32 AUDIT_ARCH_MIPSEL64N32
/**
@@ -1225,9 +1237,11 @@ int seccomp_export_bpf(const scmp_filter_ctx ctx, int fd);
#endif /* __NR_cachectl */
#define __PNR_cacheflush -10104
-#ifndef __NR_cacheflush
+#ifdef __ARM_NR_cacheflush
+#define __NR_cacheflush __ARM_NR_cacheflush
+#else
#define __NR_cacheflush __PNR_cacheflush
-#endif /* __NR_cacheflush */
+#endif /* __ARM_NR_cacheflush */
#define __PNR_sysmips -10106
#ifndef __NR_sysmips
@@ -1434,37 +1448,75 @@ int seccomp_export_bpf(const scmp_filter_ctx ctx, int fd);
#define __NR_utimes __PNR_utimes
#endif /* __NR_utimes */
-#define __PNR_multiplexer -10180
+#define __PNR_getrlimit -10180
+#ifndef __NR_getrlimit
+#define __NR_getrlimit __PNR_getrlimit
+#endif /* __NR_utimes */
+
+#define __PNR_mmap -10181
+#ifndef __NR_mmap
+#define __NR_mmap __PNR_mmap
+#endif /* __NR_utimes */
+
+#define __PNR_breakpoint -10182
+#ifdef __ARM_NR_breakpoint
+#define __NR_breakpoint __ARM_NR_breakpoint
+#else
+#define __NR_breakpoint __PNR_breakpoint
+#endif /* __ARM_NR_breakpoint */
+
+#define __PNR_set_tls -10183
+#ifdef __ARM_NR_set_tls
+#define __NR_set_tls __ARM_NR_set_tls
+#else
+#define __NR_set_tls __PNR_set_tls
+#endif /* __ARM_NR_set_tls */
+
+#define __PNR_usr26 -10184
+#ifdef __ARM_NR_usr26
+#define __NR_usr26 __ARM_NR_usr26
+#else
+#define __NR_usr26 __PNR_usr26
+#endif /* __ARM_NR_usr26 */
+
+#define __PNR_usr32 -10185
+#ifdef __ARM_NR_usr32
+#define __NR_usr32 __ARM_NR_usr32
+#else
+#define __NR_usr32 __PNR_usr32
+#endif /* __ARM_NR_usr32 */
+
+#define __PNR_multiplexer -10186
#ifndef __NR_multiplexer
#define __NR_multiplexer __PNR_multiplexer
#endif /* __NR_multiplexer */
-#define __PNR_rtas -10181
+#define __PNR_rtas -10187
#ifndef __NR_rtas
#define __NR_rtas __PNR_rtas
#endif /* __NR_rtas */
-#define __PNR_spu_create -10182
+#define __PNR_spu_create -10188
#ifndef __NR_spu_create
#define __NR_spu_create __PNR_spu_create
#endif /* __NR_spu_create */
-#define __PNR_spu_run -10183
+#define __PNR_spu_run -10189
#ifndef __NR_spu_run
#define __NR_spu_run __PNR_spu_run
#endif /* __NR_spu_run */
-#define __PNR_subpage_prot -10184
+#define __PNR_subpage_prot -10189
#ifndef __NR_subpage_prot
#define __NR_subpage_prot __PNR_subpage_prot
#endif /* __NR_subpage_prot */
-#define __PNR_swapcontext -10185
+#define __PNR_swapcontext -10190
#ifndef __NR_swapcontext
#define __NR_swapcontext __PNR_swapcontext
#endif /* __NR_swapcontext */
-#define __PNR_sys_debug_setcontext -10186
+#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 */
diff --git a/src/Makefile.am b/src/Makefile.am
index 54f8478..23d9a91 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -53,6 +53,7 @@ arch_syscall_dump_SOURCES = arch-syscall-dump.c ${SOURCES_ARCH}
arch_syscall_check_SOURCES = arch-syscall-check.c ${SOURCES_ARCH}
libseccomp_la_SOURCES = ${SOURCES_GEN} ${SOURCES_ARCH}
+libseccomp_la_CPPFLAGS = ${AM_CPPFLAGS} -I$(top_builddir)/include
libseccomp_la_CFLAGS = ${AM_CFLAGS} ${CFLAGS} -fPIC -DPIC -fvisibility=hidden
libseccomp_la_LDFLAGS = ${AM_LDFLAGS} ${LDFLAGS} \
-version-number ${VERSION_MAJOR}:${VERSION_MINOR}:${VERSION_MICRO}
diff --git a/src/api.c b/src/api.c
index 684c0e7..182b896 100644
--- a/src/api.c
+++ b/src/api.c
@@ -380,7 +380,7 @@ syscall_priority_failure:
* @param action the filter action
* @param syscall the syscall number
* @param arg_cnt the number of argument filters in the argument filter chain
- * @param arg_list the argument filter chain, (uint, enum scmp_compare, ulong)
+ * @param arg_array the argument filter chain, (uint, enum scmp_compare, ulong)
*
* This function adds a new argument/comparison/value to the seccomp filter for
* a syscall; multiple arguments can be specified and they will be chained
diff --git a/src/arch-aarch64-syscalls.c b/src/arch-aarch64-syscalls.c
index c76dae7..315be10 100644
--- a/src/arch-aarch64-syscalls.c
+++ b/src/arch-aarch64-syscalls.c
@@ -46,6 +46,7 @@ const struct arch_syscall_def aarch64_syscall_table[] = { \
{ "bind", 200 },
{ "bpf", 280 },
{ "break", __PNR_break },
+ { "breakpoint", __PNR_breakpoint },
{ "brk", 214 },
{ "cachectl", __PNR_cachectl },
{ "cacheflush", __PNR_cacheflush },
@@ -324,6 +325,7 @@ const struct arch_syscall_def aarch64_syscall_table[] = { \
{ "set_robust_list", 99 },
{ "set_thread_area", __PNR_set_thread_area },
{ "set_tid_address", 96 },
+ { "set_tls", __PNR_set_tls },
{ "setdomainname", 162 },
{ "setfsgid", 152 },
{ "setfsgid32", __PNR_setfsgid32 },
@@ -424,6 +426,8 @@ const struct arch_syscall_def aarch64_syscall_table[] = { \
{ "unlinkat", 35 },
{ "unshare", 97 },
{ "uselib", __PNR_uselib },
+ { "usr26", __PNR_usr26 },
+ { "usr32", __PNR_usr32 },
{ "ustat", __PNR_ustat },
{ "utime", __PNR_utime },
{ "utimensat", 88 },
diff --git a/src/arch-arm-syscalls.c b/src/arch-arm-syscalls.c
index b9400a3..3d75062 100644
--- a/src/arch-arm-syscalls.c
+++ b/src/arch-arm-syscalls.c
@@ -27,6 +27,7 @@
#include "arch-arm.h"
#define __NR_OABI_SYSCALL_BASE 0x900000
+#define __ARM_NR_BASE 0x0f0000
/* NOTE: we currently only support the ARM EABI, more info at the URL below:
* -> http://wiki.embeddedarm.com/wiki/EABI_vs_OABI */
@@ -49,7 +50,7 @@ const struct arch_syscall_def arm_syscall_table[] = { \
{ "add_key", (__NR_SYSCALL_BASE + 309) },
{ "adjtimex", (__NR_SYSCALL_BASE + 124) },
{ "afs_syscall", __PNR_afs_syscall },
- { "alarm", (__NR_SYSCALL_BASE + 27) },
+ { "alarm", __PNR_alarm },
{ "arm_fadvise64_64", (__NR_SYSCALL_BASE + 270) },
{ "arm_sync_file_range", (__NR_SYSCALL_BASE + 341) },
{ "arch_prctl", __PNR_arch_prctl },
@@ -57,9 +58,10 @@ const struct arch_syscall_def arm_syscall_table[] = { \
{ "bind", (__NR_SYSCALL_BASE + 282) },
{ "bpf", (__NR_SYSCALL_BASE + 386) },
{ "break", __PNR_break },
+ { "breakpoint", (__NR_SYSCALL_BASE + (__ARM_NR_BASE + 1)) },
{ "brk", (__NR_SYSCALL_BASE + 45) },
{ "cachectl", __PNR_cachectl },
- { "cacheflush", __PNR_cacheflush },
+ { "cacheflush", (__NR_SYSCALL_BASE + (__ARM_NR_BASE + 2)) },
{ "capget", (__NR_SYSCALL_BASE + 184) },
{ "capset", (__NR_SYSCALL_BASE + 185) },
{ "chdir", (__NR_SYSCALL_BASE + 12) },
@@ -156,7 +158,7 @@ const struct arch_syscall_def arm_syscall_table[] = { \
{ "getresgid32", (__NR_SYSCALL_BASE + 211) },
{ "getresuid", (__NR_SYSCALL_BASE + 165) },
{ "getresuid32", (__NR_SYSCALL_BASE + 209) },
- { "getrlimit", (__NR_SYSCALL_BASE + 76) },
+ { "getrlimit", __PNR_getrlimit },
{ "getrusage", (__NR_SYSCALL_BASE + 77) },
{ "getsid", (__NR_SYSCALL_BASE + 147) },
{ "getsockname", (__NR_SYSCALL_BASE + 286) },
@@ -183,7 +185,7 @@ const struct arch_syscall_def arm_syscall_table[] = { \
{ "iopl", __PNR_iopl },
{ "ioprio_get", (__NR_SYSCALL_BASE + 315) },
{ "ioprio_set", (__NR_SYSCALL_BASE + 314) },
- { "ipc", (__NR_SYSCALL_BASE + 117) },
+ { "ipc", __PNR_ipc },
{ "kcmp", (__NR_SYSCALL_BASE + 378) },
{ "kexec_file_load", __PNR_kexec_file_load },
{ "kexec_load", (__NR_SYSCALL_BASE + 347) },
@@ -215,7 +217,7 @@ const struct arch_syscall_def arm_syscall_table[] = { \
{ "mknodat", (__NR_SYSCALL_BASE + 324) },
{ "mlock", (__NR_SYSCALL_BASE + 150) },
{ "mlockall", (__NR_SYSCALL_BASE + 152) },
- { "mmap", (__NR_SYSCALL_BASE + 90) },
+ { "mmap", __PNR_mmap },
{ "mmap2", (__NR_SYSCALL_BASE + 192) },
{ "modify_ldt", __PNR_modify_ldt },
{ "mount", (__NR_SYSCALL_BASE + 21) },
@@ -280,7 +282,7 @@ const struct arch_syscall_def arm_syscall_table[] = { \
{ "quotactl", (__NR_SYSCALL_BASE + 131) },
{ "read", (__NR_SYSCALL_BASE + 3) },
{ "readahead", (__NR_SYSCALL_BASE + 225) },
- { "readdir", (__NR_SYSCALL_BASE + 89) },
+ { "readdir", __PNR_readdir },
{ "readlink", (__NR_SYSCALL_BASE + 85) },
{ "readlinkat", (__NR_SYSCALL_BASE + 332) },
{ "readv", (__NR_SYSCALL_BASE + 145) },
@@ -320,7 +322,7 @@ const struct arch_syscall_def arm_syscall_table[] = { \
{ "sched_yield", (__NR_SYSCALL_BASE + 158) },
{ "seccomp", (__NR_SYSCALL_BASE + 383) },
{ "security", __PNR_security },
- { "select", (__NR_SYSCALL_BASE + 82) },
+ { "select", __PNR_select },
{ "semctl", (__NR_SYSCALL_BASE + 300) },
{ "semget", (__NR_SYSCALL_BASE + 299) },
{ "semop", (__NR_SYSCALL_BASE + 298) },
@@ -335,6 +337,7 @@ const struct arch_syscall_def arm_syscall_table[] = { \
{ "set_robust_list", (__NR_SYSCALL_BASE + 338) },
{ "set_thread_area", __PNR_set_thread_area },
{ "set_tid_address", (__NR_SYSCALL_BASE + 256) },
+ { "set_tls", (__NR_SYSCALL_BASE + (__ARM_NR_BASE + 5)) },
{ "setdomainname", (__NR_SYSCALL_BASE + 121) },
{ "setfsgid", (__NR_SYSCALL_BASE + 139) },
{ "setfsgid32", (__NR_SYSCALL_BASE + 216) },
@@ -380,7 +383,7 @@ const struct arch_syscall_def arm_syscall_table[] = { \
{ "sigreturn", (__NR_SYSCALL_BASE + 119) },
{ "sigsuspend", (__NR_SYSCALL_BASE + 72) },
{ "socket", (__NR_SYSCALL_BASE + 281) },
- { "socketcall", (__NR_SYSCALL_BASE + 102) },
+ { "socketcall", __PNR_socketcall },
{ "socketpair", (__NR_SYSCALL_BASE + 288) },
{ "splice", (__NR_SYSCALL_BASE + 340) },
{ "spu_create", __PNR_spu_create },
@@ -390,7 +393,7 @@ const struct arch_syscall_def arm_syscall_table[] = { \
{ "stat64", (__NR_SYSCALL_BASE + 195) },
{ "statfs", (__NR_SYSCALL_BASE + 99) },
{ "statfs64", (__NR_SYSCALL_BASE + 266) },
- { "stime", (__NR_SYSCALL_BASE + 25) },
+ { "stime", __PNR_stime },
{ "stty", __PNR_stty },
{ "subpage_prot", __PNR_subpage_prot },
{ "swapcontext", __PNR_swapcontext },
@@ -410,7 +413,7 @@ const struct arch_syscall_def arm_syscall_table[] = { \
{ "sysmips", __PNR_sysmips },
{ "tee", (__NR_SYSCALL_BASE + 342) },
{ "tgkill", (__NR_SYSCALL_BASE + 268) },
- { "time", (__NR_SYSCALL_BASE + 13) },
+ { "time", __PNR_time },
{ "timer_create", (__NR_SYSCALL_BASE + 257) },
{ "timer_delete", (__NR_SYSCALL_BASE + 261) },
{ "timer_getoverrun", (__NR_SYSCALL_BASE + 260) },
@@ -428,15 +431,17 @@ const struct arch_syscall_def arm_syscall_table[] = { \
{ "ugetrlimit", (__NR_SYSCALL_BASE + 191) },
{ "ulimit", __PNR_ulimit },
{ "umask", (__NR_SYSCALL_BASE + 60) },
- { "umount", (__NR_SYSCALL_BASE + 22) },
+ { "umount", __PNR_umount },
{ "umount2", (__NR_SYSCALL_BASE + 52) },
{ "uname", (__NR_SYSCALL_BASE + 122) },
{ "unlink", (__NR_SYSCALL_BASE + 10) },
{ "unlinkat", (__NR_SYSCALL_BASE + 328) },
{ "unshare", (__NR_SYSCALL_BASE + 337) },
{ "uselib", (__NR_SYSCALL_BASE + 86) },
+ { "usr26", (__NR_SYSCALL_BASE + (__ARM_NR_BASE + 3)) },
+ { "usr32", (__NR_SYSCALL_BASE + (__ARM_NR_BASE + 4)) },
{ "ustat", (__NR_SYSCALL_BASE + 62) },
- { "utime", (__NR_SYSCALL_BASE + 30) },
+ { "utime", __PNR_utime },
{ "utimensat", (__NR_SYSCALL_BASE + 348) },
{ "utimes", (__NR_SYSCALL_BASE + 269) },
{ "vfork", (__NR_SYSCALL_BASE + 190) },
diff --git a/src/arch-mips-syscalls.c b/src/arch-mips-syscalls.c
index c318aa0..f02988e 100644
--- a/src/arch-mips-syscalls.c
+++ b/src/arch-mips-syscalls.c
@@ -50,6 +50,7 @@ const struct arch_syscall_def mips_syscall_table[] = { \
{ "bind", (__NR_SYSCALL_BASE + 169) },
{ "bpf", (__NR_SYSCALL_BASE + 355) },
{ "break", __NR_SYSCALL_BASE + 17 },
+ { "breakpoint", __PNR_breakpoint },
{ "brk", (__NR_SYSCALL_BASE + 45) },
{ "cachectl", (__NR_SYSCALL_BASE + 148) },
{ "cacheflush", (__NR_SYSCALL_BASE + 147) },
@@ -328,6 +329,7 @@ const struct arch_syscall_def mips_syscall_table[] = { \
{ "set_robust_list", (__NR_SYSCALL_BASE + 309) },
{ "set_thread_area", (__NR_SYSCALL_BASE + 283) },
{ "set_tid_address", (__NR_SYSCALL_BASE + 252) },
+ { "set_tls", __PNR_set_tls },
{ "setdomainname", (__NR_SYSCALL_BASE + 121) },
{ "setfsgid", (__NR_SYSCALL_BASE + 139) },
{ "setfsgid32", __PNR_setfsgid32 },
@@ -428,6 +430,8 @@ const struct arch_syscall_def mips_syscall_table[] = { \
{ "unlinkat", (__NR_SYSCALL_BASE + 294) },
{ "unshare", (__NR_SYSCALL_BASE + 303) },
{ "uselib", (__NR_SYSCALL_BASE + 86) },
+ { "usr26", __PNR_usr26 },
+ { "usr32", __PNR_usr32 },
{ "ustat", (__NR_SYSCALL_BASE + 62) },
{ "utime", (__NR_SYSCALL_BASE + 30) },
{ "utimensat", (__NR_SYSCALL_BASE + 316) },
diff --git a/src/arch-mips64-syscalls.c b/src/arch-mips64-syscalls.c
index 007a472..7faea23 100644
--- a/src/arch-mips64-syscalls.c
+++ b/src/arch-mips64-syscalls.c
@@ -50,6 +50,7 @@ const struct arch_syscall_def mips64_syscall_table[] = { \
{ "bind", (__NR_SYSCALL_BASE + 48) },
{ "bpf", (__NR_SYSCALL_BASE + 315) },
{ "break", __PNR_break },
+ { "breakpoint", __PNR_breakpoint },
{ "brk", (__NR_SYSCALL_BASE + 12) },
{ "cachectl", (__NR_SYSCALL_BASE + 198) },
{ "cacheflush", (__NR_SYSCALL_BASE + 197) },
@@ -328,6 +329,7 @@ const struct arch_syscall_def mips64_syscall_table[] = { \
{ "set_robust_list", (__NR_SYSCALL_BASE + 268) },
{ "set_thread_area", (__NR_SYSCALL_BASE + 242) },
{ "set_tid_address", (__NR_SYSCALL_BASE + 212) },
+ { "set_tls", __PNR_set_tls },
{ "setdomainname", (__NR_SYSCALL_BASE + 166) },
{ "setfsgid", (__NR_SYSCALL_BASE + 121) },
{ "setfsgid32", __PNR_setfsgid32 },
@@ -428,6 +430,8 @@ const struct arch_syscall_def mips64_syscall_table[] = { \
{ "unlinkat", (__NR_SYSCALL_BASE + 253) },
{ "unshare", (__NR_SYSCALL_BASE + 262) },
{ "uselib", __PNR_uselib },
+ { "usr26", __PNR_usr26 },
+ { "usr32", __PNR_usr32 },
{ "ustat", (__NR_SYSCALL_BASE + 133) },
{ "utime", (__NR_SYSCALL_BASE + 130) },
{ "utimensat", (__NR_SYSCALL_BASE + 275) },
diff --git a/src/arch-mips64n32-syscalls.c b/src/arch-mips64n32-syscalls.c
index ae1c9b8..18ee476 100644
--- a/src/arch-mips64n32-syscalls.c
+++ b/src/arch-mips64n32-syscalls.c
@@ -50,6 +50,7 @@ const struct arch_syscall_def mips64n32_syscall_table[] = { \
{ "bind", (__NR_SYSCALL_BASE + 48) },
{ "bpf", (__NR_SYSCALL_BASE + 319) },
{ "break", __PNR_break },
+ { "breakpoint", __PNR_breakpoint },
{ "brk", (__NR_SYSCALL_BASE + 12) },
{ "cachectl", (__NR_SYSCALL_BASE + 198) },
{ "cacheflush", (__NR_SYSCALL_BASE + 197) },
@@ -328,6 +329,7 @@ const struct arch_syscall_def mips64n32_syscall_table[] = { \
{ "set_robust_list", (__NR_SYSCALL_BASE + 272) },
{ "set_thread_area", (__NR_SYSCALL_BASE + 246) },
{ "set_tid_address", (__NR_SYSCALL_BASE + 213) },
+ { "set_tls", __PNR_set_tls },
{ "setdomainname", (__NR_SYSCALL_BASE + 166) },
{ "setfsgid", (__NR_SYSCALL_BASE + 121) },
{ "setfsgid32", __PNR_setfsgid32 },
@@ -428,6 +430,8 @@ const struct arch_syscall_def mips64n32_syscall_table[] = { \
{ "unlinkat", (__NR_SYSCALL_BASE + 257) },
{ "unshare", (__NR_SYSCALL_BASE + 266) },
{ "uselib", __PNR_uselib },
+ { "usr26", __PNR_usr26 },
+ { "usr32", __PNR_usr32 },
{ "ustat", (__NR_SYSCALL_BASE + 133) },
{ "utime", (__NR_SYSCALL_BASE + 130) },
{ "utimensat", (__NR_SYSCALL_BASE + 279) },
diff --git a/src/arch-syscall-validate b/src/arch-syscall-validate
index 595dfef..ba5cd89 100755
--- a/src/arch-syscall-validate
+++ b/src/arch-syscall-validate
@@ -63,6 +63,8 @@ libseccomp syscall validation script
optional arguments:
-h show this help message and exit
-a architecture
+ -l output the library's syscall definitions
+ -s output the system's syscall definitions
EOF
}
@@ -75,7 +77,7 @@ EOF
# Dump the architecture's syscall table to stdout.
#
function dump_sys_x86() {
- cat $1/arch/x86/syscalls/syscall_32.tbl | \
+ cat $1/arch/x86/entry/syscalls/syscall_32.tbl | \
grep -v "^#" | awk '{ print $3"\t"$1 }' | sed '/^[ \t]*$/d' | \
sort
}
@@ -98,7 +100,7 @@ function dump_lib_x86() {
# Dump the architecture's syscall table to stdout.
#
function dump_sys_x86_64() {
- cat $1/arch/x86/syscalls/syscall_64.tbl | \
+ cat $1/arch/x86/entry/syscalls/syscall_64.tbl | \
grep -v "^#" | awk '{ print $2,$3,$1 }' | sed -e '/^x32/d' | \
awk '{ print $2"\t"$3 }' | sed '/^[ \t]*$/d' | sort
}
@@ -121,7 +123,7 @@ function dump_lib_x86_64() {
# Dump the architecture's syscall table to stdout.
#
function dump_sys_x32() {
- cat $1/arch/x86/syscalls/syscall_64.tbl | \
+ cat $1/arch/x86/entry/syscalls/syscall_64.tbl | \
grep -v "^#" | awk '{ print $2,$3,$1 }' | sed -e '/^64/d' | \
awk '{ print $2"\t"$3 }' | sed '/^[ \t]*$/d' | sort
}
@@ -146,12 +148,22 @@ function dump_lib_x32() {
#
function dump_sys_arm() {
# NOTE: arm_sync_file_range() and sync_file_range2() share values
- cat $1/arch/arm/include/uapi/asm/unistd.h | \
- grep "^#define __NR_" | sort | \
+ gcc -E -dM -D__ARM_EABI__ $1/arch/arm/include/uapi/asm/unistd.h | \
+ grep "^#define __\(ARM_\)*NR_" | \
grep -v "^#define __NR_OABI_SYSCALL_BASE" | \
grep -v "^#define __NR_SYSCALL_BASE" | \
- sed -e 's/#define[ \t]\+__NR_\([^ \t]\+\)[ \t]\+(__NR_SYSCALL_BASE[ \t]*+[ \t]*\([0-9]\+\)).*/\1\t\2/' | \
- sed -e '/#define __NR_sync_file_range2[ \t]\+__NR_arm_sync_file_range/d'
+ grep -v "^#define __ARM_NR_BASE" | \
+ sed -e 's/#define[ \t]\+__NR_\([^ \t]\+\)[ \t]\+(__NR_SYSCALL_BASE[ \t]*+[ \t]*\([0-9]\+\)).*/\1\t\2/;s/#define[ \t]\+__ARM_NR_\([^ \t]\+\)[ \t]\+(__ARM_NR_BASE[ \t]*+[ \t]*\([0-9]\+\)).*/\1\t983040 + \2/' | \
+ while read line; do \
+ if echo "$line" | grep -q "+"; then \
+ echo "$line" | awk '{ print $1"\t"$2+$4 }'; \
+ else \
+ echo "$line"; \
+ fi; \
+ done | \
+ cat - | \
+ sed -e '/#define __NR_sync_file_range2[ \t]\+__NR_arm_sync_file_range/d' | \
+ sort
}
#
@@ -175,7 +187,7 @@ function dump_lib_arm() {
#
function dump_sys_aarch64() {
gcc -E -dM -I$1/include/uapi -D__BITS_PER_LONG=64 $1/include/uapi/asm-generic/unistd.h | \
- grep "^#define __NR_" | sort | \
+ grep "^#define __NR_" | \
sed -e '/__NR_syscalls/d' | \
sed -e '/__NR_arch_specific_syscall/d' | \
sed -e 's/#define[ \t]\+__NR_\([^ \t]\+\)[ \t]\+\(.*\)/\1\t\2/' | \
@@ -191,7 +203,8 @@ function dump_sys_aarch64() {
sed -e 's/__NR3264_mmap/222/' | \
sed -e 's/__NR3264_fstat/80/' | \
sed -e 's/__NR3264_lstat/1039/' | \
- sed -e 's/__NR3264_stat/1038/'
+ sed -e 's/__NR3264_stat/1038/' | \
+ sort
}
#
@@ -217,14 +230,15 @@ function dump_sys_mips() {
# _MIPS_SIM_NABI32 == 2
# _MIPS_SIM_ABI64 == 3
gcc -E -dM -I$1/arch/mips/include/uapi -D_MIPS_SIM=1 $1/arch/mips/include/uapi/asm/unistd.h | \
- grep "^#define __NR_" | sort | \
+ grep "^#define __NR_" | \
grep -v "^#define __NR_O32_" | \
grep -v "^#define __NR_N32_" | \
grep -v "^#define __NR_64_" | \
grep -v "^#define __NR_Linux" | \
grep -v "^#define __NR_unused" | \
grep -v "^#define __NR_reserved" | \
- sed -e 's/#define[ \t]\+__NR_\([^ \t]\+\)[ \t]\+(__NR_Linux[ \t]*+[ \t]*\([0-9]\+\)).*/\1\t\2/'
+ sed -e 's/#define[ \t]\+__NR_\([^ \t]\+\)[ \t]\+(__NR_Linux[ \t]*+[ \t]*\([0-9]\+\)).*/\1\t\2/' | \
+ sort
}
#
@@ -250,14 +264,15 @@ function dump_sys_mips64() {
# _MIPS_SIM_NABI32 == 2
# _MIPS_SIM_ABI64 == 3
gcc -E -dM -I$1/arch/mips/include/uapi -D_MIPS_SIM=3 $1/arch/mips/include/uapi/asm/unistd.h | \
- grep "^#define __NR_" | sort | \
+ grep "^#define __NR_" | \
grep -v "^#define __NR_O32_" | \
grep -v "^#define __NR_N32_" | \
grep -v "^#define __NR_64_" | \
grep -v "^#define __NR_Linux" | \
grep -v "^#define __NR_unused" | \
grep -v "^#define __NR_reserved" | \
- sed -e 's/#define[ \t]\+__NR_\([^ \t]\+\)[ \t]\+(__NR_Linux[ \t]*+[ \t]*\([0-9]\+\)).*/\1\t\2/'
+ sed -e 's/#define[ \t]\+__NR_\([^ \t]\+\)[ \t]\+(__NR_Linux[ \t]*+[ \t]*\([0-9]\+\)).*/\1\t\2/' | \
+ sort
}
#
@@ -283,14 +298,15 @@ function dump_sys_mips64n32() {
# _MIPS_SIM_NABI32 == 2
# _MIPS_SIM_ABI64 == 3
gcc -E -dM -I$1/arch/mips/include/uapi -D_MIPS_SIM=2 $1/arch/mips/include/uapi/asm/unistd.h | \
- grep "^#define __NR_" | sort | \
+ grep "^#define __NR_" | \
grep -v "^#define __NR_O32_" | \
grep -v "^#define __NR_N32_" | \
grep -v "^#define __NR_64_" | \
grep -v "^#define __NR_Linux" | \
grep -v "^#define __NR_unused" | \
grep -v "^#define __NR_reserved" | \
- sed -e 's/#define[ \t]\+__NR_\([^ \t]\+\)[ \t]\+(__NR_Linux[ \t]*+[ \t]*\([0-9]\+\)).*/\1\t\2/'
+ sed -e 's/#define[ \t]\+__NR_\([^ \t]\+\)[ \t]\+(__NR_Linux[ \t]*+[ \t]*\([0-9]\+\)).*/\1\t\2/' | \
+ sort
}
#
@@ -406,28 +422,28 @@ function dump_sys() {
function dump_lib() {
case $1 in
x86)
- dump_lib_x86 "$2"
+ dump_lib_x86
;;
x86_64)
- dump_lib_x86_64 "$2"
+ dump_lib_x86_64
;;
x32)
- dump_lib_x32 "$2"
+ dump_lib_x32
;;
arm)
- dump_lib_arm "$2"
+ dump_lib_arm
;;
aarch64)
- dump_lib_aarch64 "$2"
+ dump_lib_aarch64
;;
mips)
- dump_lib_mips "$2"
+ dump_lib_mips
;;
mips64)
- dump_lib_mips64 "$2"
+ dump_lib_mips64
;;
mips64n32)
- dump_lib_mips64n32 "$2"
+ dump_lib_mips64n32
;;
ppc64)
dump_lib_ppc64 "$2"
@@ -454,12 +470,22 @@ if [[ ! -x $LIB_SYS_DUMP ]]; then
exit 1
fi
-arches=""
+opt_arches=""
+opt_sys=""
+opt_lib=""
-while getopts "a:h" opt; do
+while getopts "a:slh" opt; do
case $opt in
a)
- arches+="$OPTARG "
+ opt_arches+="$OPTARG "
+ ;;
+ s)
+ opt_sys=1
+ opt_lib=0
+ ;;
+ l)
+ opt_sys=0
+ opt_lib=1
;;
h|*)
usage
@@ -470,8 +496,8 @@ done
shift $(($OPTIND - 1))
# defaults
-if [[ $arches == "" ]]; then
- arches="x86 x86_64 x32 arm aarch64 mips mips64 mips64n32 ppc64 ppc"
+if [[ $opt_arches == "" ]]; then
+ opt_arches="x86 x86_64 x32 arm aarch64 mips mips64 mips64n32 ppc pcc64"
fi
# sanity checks
@@ -486,20 +512,27 @@ if [[ ! -d $kernel_dir ]]; then
fi
# generate some temp files
-tmp_orig=$(mktemp -t syscall_validate_XXXXXX)
-tmp_new=$(mktemp -t syscall_validate_XXXXXX)
+tmp_lib=$(mktemp -t syscall_validate_XXXXXX)
+tmp_sys=$(mktemp -t syscall_validate_XXXXXX)
-# loop through the architectures
-for i in $arches; do
+# loop through the architectures and compare
+for i in $opt_arches; do
# dump the syscall tables
- dump_lib $i > $tmp_orig
- dump_sys $i "$kernel_dir" > $tmp_new
-
- # do the comparison
- diff -u --label="$i [library]" $tmp_orig --label "$i [system]" $tmp_new
+ dump_lib $i > $tmp_lib
+ dump_sys $i "$kernel_dir" > $tmp_sys
+
+ if [[ $opt_lib -eq 1 ]]; then
+ cat $tmp_lib
+ elif [[ $opt_sys -eq 1 ]]; then
+ cat $tmp_sys
+ else
+ # compare the lib and sys output
+ diff -u --label="$i [library]" $tmp_lib \
+ --label "$i [system]" $tmp_sys
+ fi
done
# cleanup and exit
-rm -f $tmp_orig $tmp_new
+rm -f $tmp_lib $tmp_sys
exit 0
diff --git a/src/arch-x32-syscalls.c b/src/arch-x32-syscalls.c
index 578d534..a0b4247 100644
--- a/src/arch-x32-syscalls.c
+++ b/src/arch-x32-syscalls.c
@@ -46,6 +46,7 @@ const struct arch_syscall_def x32_syscall_table[] = { \
{ "bind", (X32_SYSCALL_BIT + 49) },
{ "bpf", (X32_SYSCALL_BIT + 321) },
{ "break", __PNR_break },
+ { "breakpoint", __PNR_breakpoint },
{ "brk", (X32_SYSCALL_BIT + 12) },
{ "cachectl", __PNR_cachectl },
{ "cacheflush", __PNR_cacheflush },
@@ -324,6 +325,7 @@ const struct arch_syscall_def x32_syscall_table[] = { \
{ "set_robust_list", (X32_SYSCALL_BIT + 530) },
{ "set_thread_area", __PNR_set_thread_area },
{ "set_tid_address", (X32_SYSCALL_BIT + 218) },
+ { "set_tls", __PNR_set_tls },
{ "setdomainname", (X32_SYSCALL_BIT + 171) },
{ "setfsgid", (X32_SYSCALL_BIT + 123) },
{ "setfsgid32", __PNR_setfsgid32 },
@@ -424,6 +426,8 @@ const struct arch_syscall_def x32_syscall_table[] = { \
{ "unlinkat", (X32_SYSCALL_BIT + 263) },
{ "unshare", (X32_SYSCALL_BIT + 272) },
{ "uselib", __PNR_uselib },
+ { "usr26", __PNR_usr26 },
+ { "usr32", __PNR_usr32 },
{ "ustat", (X32_SYSCALL_BIT + 136) },
{ "utime", (X32_SYSCALL_BIT + 132) },
{ "utimensat", (X32_SYSCALL_BIT + 280) },
diff --git a/src/arch-x86-syscalls.c b/src/arch-x86-syscalls.c
index 92343f0..d27a4d1 100644
--- a/src/arch-x86-syscalls.c
+++ b/src/arch-x86-syscalls.c
@@ -46,6 +46,7 @@ const struct arch_syscall_def x86_syscall_table[] = { \
{ "bind", __PNR_bind },
{ "bpf", 357 },
{ "break", 17 },
+ { "breakpoint", __PNR_breakpoint },
{ "brk", 45 },
{ "cachectl", __PNR_cachectl },
{ "cacheflush", __PNR_cacheflush },
@@ -324,6 +325,7 @@ const struct arch_syscall_def x86_syscall_table[] = { \
{ "set_robust_list", 311 },
{ "set_thread_area", 243 },
{ "set_tid_address", 258 },
+ { "set_tls", __PNR_set_tls },
{ "setdomainname", 121 },
{ "setfsgid", 139 },
{ "setfsgid32", 216 },
@@ -424,6 +426,8 @@ const struct arch_syscall_def x86_syscall_table[] = { \
{ "unlinkat", 301 },
{ "unshare", 310 },
{ "uselib", 86 },
+ { "usr26", __PNR_usr26 },
+ { "usr32", __PNR_usr32 },
{ "ustat", 62 },
{ "utime", 30 },
{ "utimensat", 320 },
diff --git a/src/arch-x86_64-syscalls.c b/src/arch-x86_64-syscalls.c
index d0d4241..cd9eb6d 100644
--- a/src/arch-x86_64-syscalls.c
+++ b/src/arch-x86_64-syscalls.c
@@ -46,6 +46,7 @@ const struct arch_syscall_def x86_64_syscall_table[] = { \
{ "bind", 49 },
{ "bpf", 321 },
{ "break", __PNR_break },
+ { "breakpoint", __PNR_breakpoint },
{ "brk", 12 },
{ "cachectl", __PNR_cachectl },
{ "cacheflush", __PNR_cacheflush },
@@ -324,6 +325,7 @@ const struct arch_syscall_def x86_64_syscall_table[] = { \
{ "set_robust_list", 273 },
{ "set_thread_area", 205 },
{ "set_tid_address", 218 },
+ { "set_tls", __PNR_set_tls },
{ "setdomainname", 171 },
{ "setfsgid", 123 },
{ "setfsgid32", __PNR_setfsgid32 },
@@ -424,6 +426,8 @@ const struct arch_syscall_def x86_64_syscall_table[] = { \
{ "unlinkat", 263 },
{ "unshare", 272 },
{ "uselib", 134 },
+ { "usr26", __PNR_usr26 },
+ { "usr32", __PNR_usr32 },
{ "ustat", 136 },
{ "utime", 132 },
{ "utimensat", 280 },
diff --git a/src/arch.c b/src/arch.c
index f73db6b..25d1ff6 100644
--- a/src/arch.c
+++ b/src/arch.c
@@ -145,7 +145,7 @@ const struct arch_def *arch_def_lookup(uint32_t token)
/**
* Lookup the architecture definition by name
- * @param arch the architecure name
+ * @param arch_name the architecure name
*
* Return the matching architecture definition, returns NULL on failure.
*
diff --git a/src/db.c b/src/db.c
index 9923442..604d058 100644
--- a/src/db.c
+++ b/src/db.c
@@ -72,10 +72,9 @@ static unsigned int __db_tree_free(struct db_arg_chain_tree *tree)
/**
* Free a syscall filter argument chain tree
- * @param list the argument chain list
+ * @param tree the argument chain list
*
- * This function frees a syscall argument chain list and returns the number of
- * nodes freed.
+ * This function frees a tree and returns the number of nodes freed.
*
*/
static unsigned int _db_tree_free(struct db_arg_chain_tree *tree)
@@ -576,7 +575,7 @@ int db_col_attr_get(const struct db_filter_col *col,
/**
* Set a filter attribute
- * @param db the seccomp filter collection
+ * @param col the seccomp filter collection
* @param attr the filter attribute
* @param value the filter attribute value
*
@@ -699,7 +698,6 @@ int db_col_db_remove(struct db_filter_col *col, uint32_t arch_token)
/**
* Free and reset the seccomp filter DB
* @param db the seccomp filter DB
- * @param def_action the default filter action
*
* This function frees any existing filters and resets the filter DB to a
* default state; only the DB architecture is preserved.
@@ -827,20 +825,47 @@ int db_syscall_priority(struct db_filter *db,
}
/**
+ * Test if the argument filter can be skipped because it's a tautology
+ * @param arg argument filter
+ *
+ * If this argument filter applied to the lower 32 bit can be skipped this
+ * function returns false.
+ *
+ */
+static bool _db_arg_cmp_need_lo(const struct db_api_arg *arg)
+{
+ if (arg->op == SCMP_CMP_MASKED_EQ && D64_LO(arg->mask) == 0)
+ return false;
+
+ return true;
+}
+
+/**
+ * Test if the argument filter can be skipped because it's a tautology
+ * @param arg argument filter
+ *
+ * If this argument filter applied to the upper 32 bit can be skipped this
+ * function returns false.
+ *
+ */
+static bool _db_arg_cmp_need_hi(const struct db_api_arg *arg)
+{
+ if (arg->op == SCMP_CMP_MASKED_EQ && D64_HI(arg->mask) == 0)
+ return false;
+
+ return true;
+}
+
+/**
* Fixup the node based on the op/mask
* @param node the chain node
*
- * Apply some simplifications based on the comparison op and mask value.
+ * Ensure the datum is masked as well.
*
*/
static void _db_node_mask_fixup(struct db_arg_chain_tree *node)
{
- if (node->op == SCMP_CMP_MASKED_EQ && node->mask == 0) {
- node->op = SCMP_CMP_EQ;
- node->mask = ARG_MASK_MAX;
- node->datum = 0;
- } else
- node->datum &= node->mask;
+ node->datum &= node->mask;
}
/**
@@ -880,6 +905,13 @@ static struct db_sys_list *_db_rule_gen_64(const struct arch_def *arch,
if (chain[iter].valid == 0)
continue;
+ /* TODO: handle the case were either hi or lo isn't needed */
+
+ /* skip generating instruction which are no-ops */
+ if (!_db_arg_cmp_need_hi(&chain[iter]) &&
+ !_db_arg_cmp_need_lo(&chain[iter]))
+ continue;
+
c_iter_hi = malloc(sizeof(*c_iter_hi));
if (c_iter_hi == NULL)
goto gen_64_failure;
@@ -1012,6 +1044,10 @@ static struct db_sys_list *_db_rule_gen_32(const struct arch_def *arch,
if (chain[iter].valid == 0)
continue;
+ /* skip generating instructions which are no-ops */
+ if (!_db_arg_cmp_need_lo(&chain[iter]))
+ continue;
+
c_iter = malloc(sizeof(*c_iter));
if (c_iter == NULL)
goto gen_32_failure;
@@ -1020,6 +1056,7 @@ static struct db_sys_list *_db_rule_gen_32(const struct arch_def *arch,
c_iter->arg = chain[iter].arg;
c_iter->arg_offset = arch_arg_offset(arch, c_iter->arg);
c_iter->op = chain[iter].op;
+ /* implicitly strips off the upper 32 bit */
c_iter->mask = chain[iter].mask;
c_iter->datum = chain[iter].datum;
diff --git a/src/db.h b/src/db.h
index c846461..376cbc3 100644
--- a/src/db.h
+++ b/src/db.h
@@ -33,7 +33,7 @@
struct db_api_arg {
unsigned int arg;
- unsigned int op;
+ enum scmp_compare op;
scmp_datum_t mask;
scmp_datum_t datum;
diff --git a/src/gen_bpf.c b/src/gen_bpf.c
index 8f3ea41..8d1b1b5 100644
--- a/src/gen_bpf.c
+++ b/src/gen_bpf.c
@@ -48,6 +48,14 @@ struct acc_state {
int32_t offset;
uint32_t mask;
};
+#define _ACC_STATE(x,y) \
+ (struct acc_state){ .offset = (x), .mask = (y) }
+#define _ACC_STATE_OFFSET(x) \
+ _ACC_STATE(x,ARG_MASK_MAX)
+#define _ACC_STATE_UNDEF \
+ _ACC_STATE_OFFSET(-1)
+#define _ACC_CMP_EQ(x,y) \
+ ((x).offset == (y).offset && (x).mask == (y).mask)
enum bpf_jump_type {
TGT_NONE = 0,
@@ -97,12 +105,19 @@ struct bpf_instr {
};
#define _BPF_OFFSET_SYSCALL (offsetof(struct seccomp_data, nr))
#define _BPF_SYSCALL(a) _BPF_K(a,_BPF_OFFSET_SYSCALL)
+#define _BPF_OFFSET_ARCH (offsetof(struct seccomp_data, arch))
+#define _BPF_ARCH(a) _BPF_K(a,_BPF_OFFSET_ARCH)
struct bpf_blk {
+ /* bpf instructions */
struct bpf_instr *blks;
unsigned int blk_cnt;
unsigned int blk_alloc;
+ /* accumulator state */
+ struct acc_state acc_start;
+ struct acc_state acc_end;
+
/* priority - higher is better */
unsigned int priority;
@@ -119,7 +134,6 @@ struct bpf_blk {
struct bpf_blk *hash_nxt;
struct bpf_blk *prev, *next;
struct bpf_blk *lvl_prv, *lvl_nxt;
- struct acc_state acc_state;
};
#define _BLK_MSZE(x) \
((x)->blk_cnt * sizeof(*((x)->blks)))
@@ -139,6 +153,8 @@ struct bpf_state {
/* filter attributes */
const struct db_filter_attr *attr;
+ /* bad arch action */
+ uint64_t bad_arch_hsh;
/* default action */
uint64_t def_hsh;
@@ -288,12 +304,70 @@ static void _blk_free(struct bpf_state *state, struct bpf_blk *blk)
}
/**
+ * Allocate and initialize a new instruction block
+ *
+ * Allocate a new BPF instruction block and perform some very basic
+ * initialization. Returns a pointer to the block on success, NULL on failure.
+ *
+ */
+static struct bpf_blk *_blk_alloc(void)
+{
+ struct bpf_blk *blk;
+
+ blk = malloc(sizeof(*blk));
+ if (blk == NULL)
+ return NULL;
+
+ memset(blk, 0, sizeof(*blk));
+ blk->flag_unique = true;
+ blk->acc_start = _ACC_STATE_UNDEF;
+ blk->acc_end = _ACC_STATE_UNDEF;
+
+ return blk;
+}
+
+/**
+ * Resize an instruction block
+ * @param state the BPF state
+ * @param blk the existing instruction block, or NULL
+ * @param size_add the minimum amount of instructions to add
+ *
+ * Resize the given instruction block such that it is at least as large as the
+ * current size plus @size_add. Returns a pointer to the block on success,
+ * NULL on failure.
+ *
+ */
+static struct bpf_blk *_blk_resize(struct bpf_state *state,
+ struct bpf_blk *blk,
+ unsigned int size_add)
+{
+ unsigned int size_adj = (AINC_BLK > size_add ? AINC_BLK : size_add);
+ struct bpf_instr *new;
+
+ if (blk == NULL)
+ return NULL;
+
+ if ((blk->blk_cnt + size_adj) <= blk->blk_alloc)
+ return blk;
+
+ blk->blk_alloc += size_adj;
+ new = realloc(blk->blks, blk->blk_alloc * sizeof(*(blk->blks)));
+ if (new == NULL) {
+ _blk_free(state, blk);
+ return NULL;
+ }
+ blk->blks = new;
+
+ return blk;
+}
+
+/**
* Append a new BPF instruction to an instruction block
* @param state the BPF state
* @param blk the existing instruction block, or NULL
* @param instr the new instruction
*
- * Add the new BPF instruction to the end of the give instruction block. If
+ * Add the new BPF instruction to the end of the given instruction block. If
* the given instruction block is NULL, a new block will be allocated. Returns
* a pointer to the block on success, NULL on failure, and in the case of
* failure the instruction block is free'd.
@@ -303,30 +377,48 @@ static struct bpf_blk *_blk_append(struct bpf_state *state,
struct bpf_blk *blk,
const struct bpf_instr *instr)
{
- struct bpf_instr *new;
-
if (blk == NULL) {
- blk = malloc(sizeof(*blk));
+ blk = _blk_alloc();
if (blk == NULL)
return NULL;
- memset(blk, 0, sizeof(*blk));
- blk->flag_unique = true;
- }
- if ((blk->blk_cnt + 1) > blk->blk_alloc) {
- blk->blk_alloc += AINC_BLK;
- new = realloc(blk->blks, blk->blk_alloc * sizeof(*(blk->blks)));
- if (new == NULL) {
- _blk_free(state, blk);
- return NULL;
- }
- blk->blks = new;
}
+
+ if (_blk_resize(state, blk, 1) == NULL)
+ return NULL;
memcpy(&blk->blks[blk->blk_cnt++], instr, sizeof(*instr));
return blk;
}
/**
+ * Prepend a new BPF instruction to an instruction block
+ * @param state the BPF state
+ * @param blk the existing instruction block, or NULL
+ * @param instr the new instruction
+ *
+ * Add the new BPF instruction to the start of the given instruction block.
+ * If the given instruction block is NULL, a new block will be allocated.
+ * Returns a pointer to the block on success, NULL on failure, and in the case
+ * of failure the instruction block is free'd.
+ *
+ */
+static struct bpf_blk *_blk_prepend(struct bpf_state *state,
+ struct bpf_blk *blk,
+ const struct bpf_instr *instr)
+{
+ /* empty - we can treat this like a normal append operation */
+ if (blk == NULL || blk->blk_cnt == 0)
+ return _blk_append(state, blk, instr);
+
+ if (_blk_resize(state, blk, 1) == NULL)
+ return NULL;
+ memmove(&blk->blks[1], &blk->blks[0], blk->blk_cnt++ * sizeof(*instr));
+ memcpy(&blk->blks[0], instr, sizeof(*instr));
+
+ return blk;
+}
+
+/**
* Append a block of BPF instructions to the final BPF program
* @param prg the BPF program
* @param blk the BPF instruction block
@@ -426,7 +518,7 @@ static void _program_free(struct bpf_program *prg)
/**
* Free the BPF state
- * @param the BPF state
+ * @param state the BPF state
*
* Free all of the BPF state, including the BPF program if present.
*
@@ -715,9 +807,13 @@ static struct bpf_blk *_gen_bpf_node(struct bpf_state *state,
int32_t acc_offset;
uint32_t acc_mask;
uint64_t act_t_hash = 0, act_f_hash = 0;
- struct bpf_blk *blk = NULL, *b_act;
+ struct bpf_blk *blk, *b_act;
struct bpf_instr instr;
- struct acc_state a_state_orig = *a_state;
+
+ blk = _blk_alloc();
+ if (blk == NULL)
+ return NULL;
+ blk->acc_start = *a_state;
/* generate the action blocks */
if (node->act_t_flg) {
@@ -749,6 +845,8 @@ static struct bpf_blk *_gen_bpf_node(struct bpf_state *state,
blk = _blk_append(state, blk, &instr);
if (blk == NULL)
goto node_failure;
+ /* we're not dependent on the accumulator anymore */
+ blk->acc_start = _ACC_STATE_UNDEF;
}
if (acc_mask != a_state->mask) {
/* apply the bitmask */
@@ -806,7 +904,7 @@ static struct bpf_blk *_gen_bpf_node(struct bpf_state *state,
goto node_failure;
blk->node = node;
- blk->acc_state = a_state_orig;
+ blk->acc_end = *a_state;
return blk;
node_failure:
@@ -861,7 +959,7 @@ static struct bpf_blk *_gen_bpf_chain_lvl_res(struct bpf_state *state,
case TGT_PTR_DB:
node = (struct db_arg_chain_tree *)i_iter->jt.tgt.db;
b_new = _gen_bpf_chain(state, sys, node,
- nxt_jump, &blk->acc_state);
+ nxt_jump, &blk->acc_start);
if (b_new == NULL)
return NULL;
i_iter->jt = _BPF_JMP_HSH(b_new->hash);
@@ -887,7 +985,7 @@ static struct bpf_blk *_gen_bpf_chain_lvl_res(struct bpf_state *state,
case TGT_PTR_DB:
node = (struct db_arg_chain_tree *)i_iter->jf.tgt.db;
b_new = _gen_bpf_chain(state, sys, node,
- nxt_jump, &blk->acc_state);
+ nxt_jump, &blk->acc_start);
if (b_new == NULL)
return NULL;
i_iter->jf = _BPF_JMP_HSH(b_new->hash);
@@ -940,6 +1038,7 @@ static struct bpf_blk *_gen_bpf_chain(struct bpf_state *state,
const struct db_arg_chain_tree *c_iter;
unsigned int iter;
struct bpf_jump nxt_jump_tmp;
+ struct acc_state acc = *a_state;
if (chain == NULL) {
b_head = _gen_bpf_action(state, NULL, sys->action);
@@ -954,7 +1053,7 @@ static struct bpf_blk *_gen_bpf_chain(struct bpf_state *state,
/* build all of the blocks for this level */
do {
- b_iter = _gen_bpf_node(state, c_iter, a_state);
+ b_iter = _gen_bpf_node(state, c_iter, &acc);
if (b_iter == NULL)
goto chain_failure;
if (b_head != NULL) {
@@ -1058,7 +1157,7 @@ static struct bpf_blk *_gen_bpf_syscall(struct bpf_state *state,
{
int rc;
struct bpf_instr instr;
- struct bpf_blk *blk_c, *blk_s = NULL;
+ struct bpf_blk *blk_c, *blk_s;
struct bpf_jump def_jump;
struct acc_state a_state;
@@ -1066,20 +1165,27 @@ static struct bpf_blk *_gen_bpf_syscall(struct bpf_state *state,
memset(&def_jump, 0, sizeof(def_jump));
def_jump = _BPF_JMP_HSH(state->def_hsh);
+ blk_s = _blk_alloc();
+ if (blk_s == NULL)
+ return NULL;
+
/* setup the accumulator state */
if (acc_reset) {
_BPF_INSTR(instr, _BPF_OP(state->arch, BPF_LD + BPF_ABS),
_BPF_JMP_NO, _BPF_JMP_NO,
_BPF_SYSCALL(state->arch));
- blk_s = _blk_append(state, NULL, &instr);
+ blk_s = _blk_append(state, blk_s, &instr);
if (blk_s == NULL)
return NULL;
- a_state.offset = _BPF_OFFSET_SYSCALL;
- a_state.mask = ARG_MASK_MAX;
+ /* we've loaded the syscall ourselves */
+ a_state = _ACC_STATE_OFFSET(_BPF_OFFSET_SYSCALL);
+ blk_s->acc_start = _ACC_STATE_UNDEF;
+ blk_s->acc_end = _ACC_STATE_OFFSET(_BPF_OFFSET_SYSCALL);
} else {
- /* set the accumulator state to an unknown value */
- a_state.offset = -1;
- a_state.mask = ARG_MASK_MAX;
+ /* we rely on someone else to load the syscall */
+ a_state = _ACC_STATE_UNDEF;
+ blk_s->acc_start = _ACC_STATE_OFFSET(_BPF_OFFSET_SYSCALL);
+ blk_s->acc_end = _ACC_STATE_OFFSET(_BPF_OFFSET_SYSCALL);
}
/* generate the argument chains */
@@ -1243,26 +1349,31 @@ static struct bpf_blk *_gen_bpf_arch(struct bpf_state *state,
b_new = _blk_append(state, NULL, &instr);
if (b_new == NULL)
goto arch_failure;
+ b_new->acc_end = _ACC_STATE_OFFSET(_BPF_OFFSET_SYSCALL);
if (state->arch->token == SCMP_ARCH_X86_64) {
/* filter out x32 */
_BPF_INSTR(instr,
_BPF_OP(state->arch, BPF_JMP + BPF_JGE),
- _BPF_JMP_NXT(blk_cnt++), _BPF_JMP_NO,
+ _BPF_JMP_HSH(state->bad_arch_hsh),
+ _BPF_JMP_NO,
_BPF_K(state->arch, X32_SYSCALL_BIT));
if (b_head != NULL)
instr.jf = _BPF_JMP_HSH(b_head->hash);
else
instr.jf = _BPF_JMP_HSH(state->def_hsh);
+ blk_cnt++;
} else if (state->arch->token == SCMP_ARCH_X32) {
/* filter out x86_64 */
_BPF_INSTR(instr,
_BPF_OP(state->arch, BPF_JMP + BPF_JGE),
- _BPF_JMP_NO, _BPF_JMP_NXT(blk_cnt++),
+ _BPF_JMP_NO,
+ _BPF_JMP_HSH(state->bad_arch_hsh),
_BPF_K(state->arch, X32_SYSCALL_BIT));
if (b_head != NULL)
instr.jt = _BPF_JMP_HSH(b_head->hash);
else
instr.jt = _BPF_JMP_HSH(state->def_hsh);
+ blk_cnt++;
} else
/* we should never get here */
goto arch_failure;
@@ -1531,6 +1642,7 @@ static int _gen_bpf_build_bpf(struct bpf_state *state,
rc = _hsh_add(state, &b_badarch, 1);
if (rc < 0)
return rc;
+ state->bad_arch_hsh = b_badarch->hash;
/* generate the default action */
b_default = _gen_bpf_action(state, NULL, state->attr->act_default);
@@ -1543,11 +1655,11 @@ static int _gen_bpf_build_bpf(struct bpf_state *state,
/* load the architecture token/number */
_BPF_INSTR(instr, _BPF_OP(state->arch, BPF_LD + BPF_ABS),
- _BPF_JMP_NO, _BPF_JMP_NO,
- _BPF_K(state->arch, offsetof(struct seccomp_data, arch)));
+ _BPF_JMP_NO, _BPF_JMP_NO, _BPF_ARCH(state->arch));
b_head = _blk_append(state, NULL, &instr);
if (b_head == NULL)
return -ENOMEM;
+ b_head->acc_end = _ACC_STATE_OFFSET(_BPF_OFFSET_ARCH);
rc = _hsh_add(state, &b_head, 1);
if (rc < 0)
return rc;
@@ -1638,6 +1750,37 @@ static int _gen_bpf_build_bpf(struct bpf_state *state,
b_jmp = _hsh_find_once(state,
i_iter->k.tgt.hash);
if (b_jmp != NULL) {
+ /* do we need to reload the accumulator? */
+ if ((b_jmp->acc_start.offset != -1) &&
+ !_ACC_CMP_EQ(b_iter->acc_end,
+ b_jmp->acc_start)) {
+ if (b_jmp->acc_start.mask != ARG_MASK_MAX) {
+ _BPF_INSTR(instr,
+ _BPF_OP(state->arch,
+ BPF_ALU + BPF_AND),
+ _BPF_JMP_NO,
+ _BPF_JMP_NO,
+ _BPF_K(state->arch,
+ b_jmp->acc_start.mask));
+ b_jmp = _blk_prepend(state,
+ b_jmp,
+ &instr);
+ if (b_jmp == NULL)
+ return -EFAULT;
+ }
+ _BPF_INSTR(instr,
+ _BPF_OP(state->arch,
+ BPF_LD + BPF_ABS),
+ _BPF_JMP_NO, _BPF_JMP_NO,
+ _BPF_K(state->arch,
+ b_jmp->acc_start.offset));
+ b_jmp = _blk_prepend(state,
+ b_jmp, &instr);
+ if (b_jmp == NULL)
+ return -EFAULT;
+ /* not reliant on the accumulator */
+ b_jmp->acc_start = _ACC_STATE_UNDEF;
+ }
/* insert the new block after this block */
b_jmp->prev = b_iter;
b_jmp->next = b_iter->next;
@@ -1654,6 +1797,7 @@ static int _gen_bpf_build_bpf(struct bpf_state *state,
b_iter = b_iter->prev;
} while (b_iter != NULL);
+
/* NOTE - from here to the end of the function we need to fail via the
* the build_bpf_free_blks label, not just return an error; see
* the _gen_bpf_build_jmp() function for details */
@@ -1806,7 +1950,7 @@ bpf_generate_end:
/**
* Free memory associated with a BPF representation
- * @param fprog the BPF representation
+ * @param program the BPF representation
*
* Free the memory associated with a BPF representation generated by the
* gen_bpf_generate() function.
diff --git a/src/gen_pfc.c b/src/gen_pfc.c
index 3484dab..4f2ee4f 100644
--- a/src/gen_pfc.c
+++ b/src/gen_pfc.c
@@ -177,6 +177,9 @@ static void _gen_pfc_chain(const struct arch_def *arch,
case SCMP_CMP_MASKED_EQ:
fprintf(fds, " & 0x%.8x == ", c_iter->mask);
break;
+ case SCMP_CMP_NE:
+ case SCMP_CMP_LT:
+ case SCMP_CMP_LE:
default:
fprintf(fds, " ??? ");
}
@@ -247,7 +250,7 @@ static void _gen_pfc_syscall(const struct arch_def *arch,
static int _gen_pfc_arch(const struct db_filter_col *col,
const struct db_filter *db, FILE *fds)
{
- int rc;
+ int rc = 0;
struct db_sys_list *s_iter;
struct pfc_sys_list *p_iter = NULL, *p_new, *p_head = NULL, *p_prev;
diff --git a/src/hash.c b/src/hash.c
index cb52b3b..1228307 100644
--- a/src/hash.c
+++ b/src/hash.c
@@ -189,7 +189,7 @@ static uint32_t jhash_word(const uint32_t *k, size_t length, uint32_t initval)
/**
* Hash a variable-length key into a 32-bit value
- * @param k the key (the unaligned variable-length array of bytes)
+ * @param key the key (the unaligned variable-length array of bytes)
* @param length the length of the key, counting by bytes
* @param initval can be any 4-byte value
*
@@ -456,7 +456,7 @@ static uint32_t jhash_le(const void *key, size_t length, uint32_t initval)
/**
* Hash a variable-length key into a 32-bit value
- * @param k the key (the unaligned variable-length array of bytes)
+ * @param key the key (the unaligned variable-length array of bytes)
* @param length the length of the key, counting by bytes
* @param initval can be any 4-byte value
*
@@ -655,7 +655,7 @@ static uint32_t jhash_be( const void *key, size_t length, uint32_t initval)
/**
* Hash a variable-length key into a 32-bit value
- * @param k the key (the unaligned variable-length array of bytes)
+ * @param key the key (the unaligned variable-length array of bytes)
* @param length the length of the key, counting by bytes
* @param initval can be any 4-byte value
*
diff --git a/src/python/seccomp.pyx b/src/python/seccomp.pyx
index 2da8c66..18360a7 100644
--- a/src/python/seccomp.pyx
+++ b/src/python/seccomp.pyx
@@ -420,7 +420,7 @@ cdef class SyscallFilter:
Lookup the given attribute in the filter and return the
attribute's value to the caller.
"""
- value = 0
+ cdef uint32_t value = 0
rc = libseccomp.seccomp_attr_get(self._ctx,
attr, <uint32_t *>&value)
if rc == -errno.EINVAL:
diff --git a/tests/.gitignore b/tests/.gitignore
index 6c2440b..d47ea65 100644
--- a/tests/.gitignore
+++ b/tests/.gitignore
@@ -1,6 +1,7 @@
*.bpf
*.bpfd
*.pfc
+miniseq
util.pyc
00-test.c
00-test
@@ -30,3 +31,6 @@ util.pyc
24-live-arg_allow
25-sim-multilevel_chains_adv
26-sim-arch_all_be_basic
+27-sim-bpf_blk_state
+28-sim-arch_x86
+
diff --git a/tests/02-sim-basic.py b/tests/02-sim-basic.py
index 868664f..60ad321 100755
--- a/tests/02-sim-basic.py
+++ b/tests/02-sim-basic.py
@@ -30,10 +30,10 @@ from seccomp import *
def test(args):
f = SyscallFilter(KILL)
- f.add_rule_exactly(ALLOW, "read");
- f.add_rule_exactly(ALLOW, "write");
- f.add_rule_exactly(ALLOW, "close");
- f.add_rule_exactly(ALLOW, "rt_sigreturn");
+ f.add_rule_exactly(ALLOW, "read")
+ f.add_rule_exactly(ALLOW, "write")
+ f.add_rule_exactly(ALLOW, "close")
+ f.add_rule_exactly(ALLOW, "rt_sigreturn")
return f
args = util.get_opt()
diff --git a/tests/03-sim-basic_chains.py b/tests/03-sim-basic_chains.py
index 324170d..81eac1a 100755
--- a/tests/03-sim-basic_chains.py
+++ b/tests/03-sim-basic_chains.py
@@ -30,11 +30,11 @@ from seccomp import *
def test(args):
f = SyscallFilter(KILL)
- f.add_rule_exactly(ALLOW, "read", Arg(0, EQ, sys.stdin.fileno()));
- f.add_rule_exactly(ALLOW, "write", Arg(0, EQ, sys.stdout.fileno()));
- f.add_rule_exactly(ALLOW, "write", Arg(0, EQ, sys.stderr.fileno()));
- f.add_rule_exactly(ALLOW, "close");
- f.add_rule_exactly(ALLOW, "rt_sigreturn");
+ f.add_rule_exactly(ALLOW, "read", Arg(0, EQ, sys.stdin.fileno()))
+ f.add_rule_exactly(ALLOW, "write", Arg(0, EQ, sys.stdout.fileno()))
+ f.add_rule_exactly(ALLOW, "write", Arg(0, EQ, sys.stderr.fileno()))
+ f.add_rule_exactly(ALLOW, "close")
+ f.add_rule_exactly(ALLOW, "rt_sigreturn")
return f
args = util.get_opt()
diff --git a/tests/04-sim-multilevel_chains.py b/tests/04-sim-multilevel_chains.py
index 73a6921..3878636 100755
--- a/tests/04-sim-multilevel_chains.py
+++ b/tests/04-sim-multilevel_chains.py
@@ -30,22 +30,22 @@ from seccomp import *
def test(args):
f = SyscallFilter(KILL)
- f.add_rule(ALLOW, "open");
- f.add_rule(ALLOW, "close");
+ f.add_rule(ALLOW, "open")
+ f.add_rule(ALLOW, "close")
f.add_rule(ALLOW, "read",
Arg(0, EQ, sys.stdin.fileno()),
Arg(1, NE, 0),
- Arg(2, LT, sys.maxsize));
+ Arg(2, LT, sys.maxsize))
f.add_rule(ALLOW, "write",
Arg(0, EQ, sys.stdout.fileno()),
Arg(1, NE, 0),
- Arg(2, LT, sys.maxsize));
+ Arg(2, LT, sys.maxsize))
f.add_rule(ALLOW, "write",
Arg(0, EQ, sys.stderr.fileno()),
Arg(1, NE, 0),
- Arg(2, LT, sys.maxsize));
- f.add_rule(ALLOW, "close");
- f.add_rule(ALLOW, "rt_sigreturn");
+ Arg(2, LT, sys.maxsize))
+ f.add_rule(ALLOW, "close")
+ f.add_rule(ALLOW, "rt_sigreturn")
return f
args = util.get_opt()
diff --git a/tests/12-sim-basic_masked_ops.tests b/tests/12-sim-basic_masked_ops.tests
index 20e0f6d..5f1327f 100644
--- a/tests/12-sim-basic_masked_ops.tests
+++ b/tests/12-sim-basic_masked_ops.tests
@@ -30,6 +30,12 @@ test type: bpf-sim
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/15-basic-resolver.c b/tests/15-basic-resolver.c
index a8988fd..0bd0cf8 100644
--- a/tests/15-basic-resolver.c
+++ b/tests/15-basic-resolver.c
@@ -21,40 +21,51 @@
#include <errno.h>
#include <string.h>
+#include <stdlib.h>
#include <seccomp.h>
int main(int argc, char *argv[])
{
- char *name;
+ char *name = NULL;
if (seccomp_syscall_resolve_name("open") != __NR_open)
- return 1;
+ goto fail;
if (seccomp_syscall_resolve_name("socket") != __NR_socket)
- return 1;
+ goto fail;
if (seccomp_syscall_resolve_name("INVALID") != __NR_SCMP_ERROR)
- return 1;
+ goto fail;
if (seccomp_syscall_resolve_name_arch(SCMP_ARCH_NATIVE,
"open") != __NR_open)
- return 1;
+ goto fail;
if (seccomp_syscall_resolve_name_arch(SCMP_ARCH_NATIVE,
"socket") != __NR_socket)
- return 1;
+ goto fail;
if (seccomp_syscall_resolve_name_arch(SCMP_ARCH_NATIVE,
"INVALID") != __NR_SCMP_ERROR)
- return 1;
+ goto fail;
name = seccomp_syscall_resolve_num_arch(SCMP_ARCH_NATIVE, __NR_open);
if (name == NULL || strcmp(name, "open") != 0)
- return 1;
+ goto fail;
+ free(name);
+
name = seccomp_syscall_resolve_num_arch(SCMP_ARCH_NATIVE, __NR_socket);
if (name == NULL || strcmp(name, "socket") != 0)
- return 1;
+ goto fail;
+ free(name);
+
name = seccomp_syscall_resolve_num_arch(SCMP_ARCH_NATIVE,
__NR_SCMP_ERROR);
if (name != NULL)
- return 1;
+ goto fail;
+ free(name);
return 0;
+
+fail:
+ if (name != NULL)
+ free(name);
+ return 1;
}
diff --git a/tests/18-sim-basic_whitelist.py b/tests/18-sim-basic_whitelist.py
index a7b9cb7..95ae7c1 100755
--- a/tests/18-sim-basic_whitelist.py
+++ b/tests/18-sim-basic_whitelist.py
@@ -30,11 +30,11 @@ from seccomp import *
def test(args):
f = SyscallFilter(ALLOW)
- f.add_rule_exactly(KILL, "read", Arg(0, EQ, sys.stdin.fileno()));
- f.add_rule_exactly(KILL, "write", Arg(0, EQ, sys.stdout.fileno()));
- f.add_rule_exactly(KILL, "write", Arg(0, EQ, sys.stderr.fileno()));
- f.add_rule_exactly(KILL, "close");
- f.add_rule_exactly(KILL, "rt_sigreturn");
+ f.add_rule_exactly(KILL, "read", Arg(0, EQ, sys.stdin.fileno()))
+ f.add_rule_exactly(KILL, "write", Arg(0, EQ, sys.stdout.fileno()))
+ f.add_rule_exactly(KILL, "write", Arg(0, EQ, sys.stderr.fileno()))
+ f.add_rule_exactly(KILL, "close")
+ f.add_rule_exactly(KILL, "rt_sigreturn")
return f
args = util.get_opt()
diff --git a/tests/22-sim-basic_chains_array.py b/tests/22-sim-basic_chains_array.py
index dfc3a58..c228661 100755
--- a/tests/22-sim-basic_chains_array.py
+++ b/tests/22-sim-basic_chains_array.py
@@ -33,11 +33,11 @@ from seccomp import *
def test(args):
f = SyscallFilter(KILL)
- f.add_rule_exactly(ALLOW, "read", Arg(0, EQ, sys.stdin.fileno()));
- f.add_rule_exactly(ALLOW, "write", Arg(0, EQ, sys.stdout.fileno()));
- f.add_rule_exactly(ALLOW, "write", Arg(0, EQ, sys.stderr.fileno()));
- f.add_rule_exactly(ALLOW, "close");
- f.add_rule_exactly(ALLOW, "rt_sigreturn");
+ f.add_rule_exactly(ALLOW, "read", Arg(0, EQ, sys.stdin.fileno()))
+ f.add_rule_exactly(ALLOW, "write", Arg(0, EQ, sys.stdout.fileno()))
+ f.add_rule_exactly(ALLOW, "write", Arg(0, EQ, sys.stderr.fileno()))
+ f.add_rule_exactly(ALLOW, "close")
+ f.add_rule_exactly(ALLOW, "rt_sigreturn")
return f
args = util.get_opt()
diff --git a/tests/25-sim-multilevel_chains_adv.py b/tests/25-sim-multilevel_chains_adv.py
index 95a673c..0dd85de 100755
--- a/tests/25-sim-multilevel_chains_adv.py
+++ b/tests/25-sim-multilevel_chains_adv.py
@@ -32,11 +32,11 @@ def test(args):
f = SyscallFilter(KILL)
f.add_rule_exactly(ALLOW, 10,
Arg(0, EQ, 11),
- Arg(1, NE, 12));
+ Arg(1, NE, 12))
f.add_rule_exactly(ALLOW, 20,
Arg(0, EQ, 21),
Arg(1, NE, 22),
- Arg(2, EQ, 23));
+ Arg(2, EQ, 23))
return f
args = util.get_opt()
diff --git a/tests/27-sim-bpf_blk_state.c b/tests/27-sim-bpf_blk_state.c
new file mode 100644
index 0000000..fd69044
--- /dev/null
+++ b/tests/27-sim-bpf_blk_state.c
@@ -0,0 +1,103 @@
+/**
+ * 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;
+
+ rc = seccomp_rule_add_exact(ctx, SCMP_ACT_KILL, 1000, 1,
+ SCMP_A0(SCMP_CMP_EQ, 3));
+ if (rc != 0)
+ goto out;
+ rc = seccomp_rule_add_exact(ctx, SCMP_ACT_KILL, 1000, 1,
+ SCMP_A0(SCMP_CMP_EQ, 4));
+ if (rc != 0)
+ goto out;
+ rc = seccomp_rule_add_exact(ctx, SCMP_ACT_KILL, 1000, 1,
+ SCMP_A0(SCMP_CMP_EQ, 5));
+ if (rc != 0)
+ goto out;
+ rc = seccomp_rule_add_exact(ctx, SCMP_ACT_KILL, 1000, 1,
+ SCMP_A0(SCMP_CMP_EQ, 6));
+ if (rc != 0)
+ goto out;
+ rc = seccomp_rule_add_exact(ctx, SCMP_ACT_KILL, 1000, 1,
+ SCMP_A0(SCMP_CMP_EQ, 7));
+ if (rc != 0)
+ goto out;
+ rc = seccomp_rule_add_exact(ctx, SCMP_ACT_KILL, 1000, 1,
+ SCMP_A0(SCMP_CMP_EQ, 8));
+ if (rc != 0)
+ goto out;
+ rc = seccomp_rule_add_exact(ctx, SCMP_ACT_KILL, 1000, 1,
+ SCMP_A0(SCMP_CMP_EQ, 9));
+ if (rc != 0)
+ goto out;
+ rc = seccomp_rule_add_exact(ctx, SCMP_ACT_KILL, 1000, 1,
+ SCMP_A0(SCMP_CMP_EQ, 11));
+ if (rc != 0)
+ goto out;
+ rc = seccomp_rule_add_exact(ctx, SCMP_ACT_KILL, 1000, 1,
+ SCMP_A0(SCMP_CMP_EQ, 12));
+ if (rc != 0)
+ goto out;
+ rc = seccomp_rule_add_exact(ctx, SCMP_ACT_KILL, 1000, 1,
+ SCMP_A0(SCMP_CMP_EQ, 13));
+ if (rc != 0)
+ goto out;
+ rc = seccomp_rule_add_exact(ctx, SCMP_ACT_KILL, 1000, 1,
+ SCMP_A0(SCMP_CMP_EQ, 14));
+ if (rc != 0)
+ goto out;
+ rc = seccomp_rule_add_exact(ctx, SCMP_ACT_KILL, 1000, 1,
+ SCMP_A0(SCMP_CMP_EQ, 15));
+ if (rc != 0)
+ goto out;
+ rc = seccomp_rule_add_exact(ctx, SCMP_ACT_KILL, 1000, 1,
+ SCMP_A0(SCMP_CMP_GE, 16));
+ 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/27-sim-bpf_blk_state.py b/tests/27-sim-bpf_blk_state.py
new file mode 100755
index 0000000..ff53ac9
--- /dev/null
+++ b/tests/27-sim-bpf_blk_state.py
@@ -0,0 +1,53 @@
+#!/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.add_rule_exactly(KILL, 1000, Arg(0, EQ, 3))
+ f.add_rule_exactly(KILL, 1000, Arg(0, EQ, 4))
+ f.add_rule_exactly(KILL, 1000, Arg(0, EQ, 5))
+ f.add_rule_exactly(KILL, 1000, Arg(0, EQ, 6))
+ f.add_rule_exactly(KILL, 1000, Arg(0, EQ, 7))
+ f.add_rule_exactly(KILL, 1000, Arg(0, EQ, 8))
+ f.add_rule_exactly(KILL, 1000, Arg(0, EQ, 9))
+ f.add_rule_exactly(KILL, 1000, Arg(0, EQ, 11))
+ f.add_rule_exactly(KILL, 1000, Arg(0, EQ, 12))
+ f.add_rule_exactly(KILL, 1000, Arg(0, EQ, 13))
+ f.add_rule_exactly(KILL, 1000, Arg(0, EQ, 14))
+ f.add_rule_exactly(KILL, 1000, Arg(0, EQ, 15))
+ f.add_rule_exactly(KILL, 1000, Arg(0, GE, 16))
+ 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/27-sim-bpf_blk_state.tests b/tests/27-sim-bpf_blk_state.tests
new file mode 100644
index 0000000..a4a8ae1
--- /dev/null
+++ b/tests/27-sim-bpf_blk_state.tests
@@ -0,0 +1,24 @@
+#
+# 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
+27-sim-bpf_blk_state all 1000 0-2 N N N N N ALLOW
+27-sim-bpf_blk_state all 1000 3-9 N N N N N KILL
+27-sim-bpf_blk_state all 1000 10 N N N N N ALLOW
+27-sim-bpf_blk_state all 1000 11-32 N N N N N KILL
+
+test type: bpf-sim-fuzz
+
+# Testname StressCount
+27-sim-bpf_blk_state 50
+
+test type: bpf-valgrind
+
+# Testname
+27-sim-bpf_blk_state
diff --git a/tests/28-sim-arch_x86.c b/tests/28-sim-arch_x86.c
new file mode 100644
index 0000000..fa6302f
--- /dev/null
+++ b/tests/28-sim-arch_x86.c
@@ -0,0 +1,71 @@
+/**
+ * Seccomp Library test program
+ *
+ * This test triggered a bug in libseccomp erroneously allowing the close()
+ * syscall on x32 instead of 'KILL'ing it, as it should do for unsupported
+ * architectures.
+ *
+ * Copyright (c) 2012 Red Hat <pmoore@redhat.com>
+ * Authors: Paul Moore <pmoore@redhat.com>
+ * 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 <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;
+
+ rc = seccomp_arch_remove(ctx, SCMP_ARCH_NATIVE);
+ if (rc != 0)
+ goto out;
+
+ /* add x86-64 and x86 (in that order!) but explicitly leave out x32 */
+ rc = seccomp_arch_add(ctx, SCMP_ARCH_X86_64);
+ if (rc != 0)
+ goto out;
+ rc = seccomp_arch_add(ctx, SCMP_ARCH_X86);
+ if (rc != 0)
+ goto out;
+
+ rc = seccomp_rule_add(ctx, SCMP_ACT_ERRNO(1), SCMP_SYS(close), 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/28-sim-arch_x86.py b/tests/28-sim-arch_x86.py
new file mode 100644
index 0000000..3ef7b77
--- /dev/null
+++ b/tests/28-sim-arch_x86.py
@@ -0,0 +1,47 @@
+#!/usr/bin/env python
+
+#
+# Seccomp Library test program
+#
+# Copyright (c) 2015 Red Hat <pmoore@redhat.com>
+# Author: Paul Moore <pmoore@redhat.com>
+#
+# Adapted from 29-sim-arch_x86.c by 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>.
+#
+
+import argparse
+import sys
+
+import util
+
+from seccomp import *
+
+def test(args):
+ f = SyscallFilter(ALLOW)
+ f.remove_arch(Arch())
+ # add x86-64 and x86 (in that order!) but explicitly leave out x32
+ f.add_arch(Arch("x86_64"))
+ f.add_arch(Arch("x86"))
+ f.add_rule(ERRNO(1), "close")
+ 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/28-sim-arch_x86.tests b/tests/28-sim-arch_x86.tests
new file mode 100644
index 0000000..45978aa
--- /dev/null
+++ b/tests/28-sim-arch_x86.tests
@@ -0,0 +1,27 @@
+#
+# libseccomp regression test automation data
+#
+# This test triggered a bug in libseccomp erroneously allowing the close()
+# syscall on x32 instead of 'KILL'ing it, as it should do for unsupported
+# architectures.
+#
+# Author: Mathias Krause <minipli@googlemail.com>
+#
+
+test type: bpf-sim
+
+# Testname Arch Syscall Arg0 Arg1 Arg2 Arg3 Arg4 Arg5 Result
+28-sim-arch_x86 +x86,+x86_64 read N N N N N N ALLOW
+28-sim-arch_x86 +x86,+x86_64 close N N N N N N ERRNO(1)
+28-sim-arch_x86 +arm,+x32 read N N N N N N KILL
+28-sim-arch_x86 +arm,+x32 close N N N N N N KILL
+
+test type: bpf-sim-fuzz
+
+# Testname StressCount
+28-sim-arch_x86 50
+
+test type: bpf-valgrind
+
+# Testname
+28-sim-arch_x86
diff --git a/tests/Makefile.am b/tests/Makefile.am
index edb50a3..ba670c6 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 \
@@ -51,7 +54,9 @@ check_PROGRAMS = \
23-sim-arch_all_le_basic \
24-live-arg_allow \
25-sim-multilevel_chains_adv \
- 26-sim-arch_all_be_basic
+ 26-sim-arch_all_be_basic \
+ 27-sim-bpf_blk_state \
+ 28-sim-arch_x86
EXTRA_DIST_TESTPYTHON = \
util.py \
@@ -80,7 +85,9 @@ EXTRA_DIST_TESTPYTHON = \
23-sim-arch_all_le_basic.py \
24-live-arg_allow.py \
25-sim-multilevel_chains_adv.py \
- 26-sim-arch_all_be_basic.py
+ 26-sim-arch_all_be_basic.py \
+ 27-sim-bpf_blk_state.py \
+ 28-sim-arch_x86.py
EXTRA_DIST_TESTCFGS = \
01-sim-allow.tests \
@@ -108,7 +115,9 @@ EXTRA_DIST_TESTCFGS = \
23-sim-arch_all_le_basic.tests \
24-live-arg_allow.tests \
25-sim-multilevel_chains_adv.tests \
- 26-sim-arch_all_be_basic.tests
+ 26-sim-arch_all_be_basic.tests \
+ 27-sim-bpf_blk_state.tests \
+ 28-sim-arch_x86.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 9f0c17e..2aba23b 100755
--- a/tests/regression
+++ b/tests/regression
@@ -170,6 +170,23 @@ 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() {
+ ${basedir}/miniseq "$1" "$2"
+}
+
+#
# Run the specified test command (with valgrind if requested)
#
# Arguments:
@@ -251,7 +268,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) \
@@ -468,13 +485,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
@@ -833,7 +850,6 @@ function run_tests() {
verify_deps head
verify_deps sed
verify_deps awk
-verify_deps seq
verify_deps tr
# global variables
diff --git a/tools/Makefile.am b/tools/Makefile.am
index 422b35d..b18dc9b 100644
--- a/tools/Makefile.am
+++ b/tools/Makefile.am
@@ -16,6 +16,8 @@
# along with this library; if not, see <http://www.gnu.org/licenses>.
#
+AM_CPPFLAGS = -I$(top_builddir)/include
+
noinst_LTLIBRARIES = util.la
util_la_SOURCES = util.c util.h bpf.h
util_la_LDFLAGS = -module
diff --git a/tools/check-syntax b/tools/check-syntax
index aebdf50..1ef5faf 100755
--- a/tools/check-syntax
+++ b/tools/check-syntax
@@ -3,7 +3,7 @@
#
# libseccomp code syntax checking tool
#
-# Copyright (c) 2013 Red Hat <pmoore@redhat.com>
+# Copyright (c) 2013,2015 Red Hat <pmoore@redhat.com>
# Author: Paul Moore <pmoore@redhat.com>
#
@@ -54,18 +54,17 @@ usage: check-syntax [-h]
libseccomp code syntax checking tool
optional arguments:
-h show this help message and exit
+ -f fix the file formatting
EOF
}
#
-# Check the formatting on a C source/header file
+# Generate a properly formatted C source/header file
#
# Arguments:
-# 1 File to check
+# 1 Source file
#
function tool_c_style() {
- [[ -z "$1" || ! -r "$1" ]] && return
-
astyle --options=none --lineend=linux --mode=c \
--style=linux \
--indent=force-tab=8 \
@@ -77,8 +76,33 @@ function tool_c_style() {
--align-pointer=name \
--align-reference=name \
--max-code-length=80 \
- --break-after-logical < "$1" \
- | diff -pu --label="$1.orig" "$1" --label="$1" -
+ --break-after-logical < "$1"
+}
+
+#
+# Check the formatting on a C source/header file
+#
+# Arguments:
+# 1 File to check
+#
+function tool_c_style_check() {
+ [[ -z "$1" || ! -r "$1" ]] && return
+
+ tool_c_style "$1" | diff -pu --label="$1.orig" "$1" --label="$1" -
+}
+
+#
+# Fix the formatting on a C source/header file
+#
+# Arguments:
+# 1 File to fix
+#
+function tool_c_style_fix() {
+ [[ -z "$1" || ! -r "$1" ]] && return
+
+ tmp="$(mktemp --tmpdir=$(dirname "$1"))"
+ tool_c_style "$1" > "$tmp"
+ mv "$tmp" "$1"
}
#
@@ -88,7 +112,18 @@ function check_c() {
for i in $CHK_C_LIST; do
echo "$CHK_C_EXCLUDE" | grep -q "$i" && continue
echo "Differences for $i"
- tool_c_style "$i"
+ tool_c_style_check "$i"
+ done
+}
+
+#
+# Perform all known syntax fixess for the configured C sources/headers
+#
+function fix_c() {
+ for i in $CHK_C_LIST; do
+ echo "$CHK_C_EXCLUDE" | grep -q "$i" && continue
+ echo "Fixing $i"
+ tool_c_style_fix "$i"
done
}
@@ -97,8 +132,13 @@ function check_c() {
verify_deps astyle
-while getopts "h" opt; do
+opt_fix=0
+
+while getopts "fh" opt; do
case $opt in
+ f)
+ opt_fix=1
+ ;;
h|*)
usage
exit 1
@@ -109,7 +149,11 @@ done
# display the results
echo "=============== $(date) ==============="
echo "Code Syntax Check Results (\"check-syntax $*\")"
-check_c
+if [[ $opt_fix -eq 1 ]]; then
+ fix_c
+else
+ check_c
+fi
echo "============================================================"
# exit
diff --git a/tools/util.h b/tools/util.h
index 806f78a..2fed617 100644
--- a/tools/util.h
+++ b/tools/util.h
@@ -22,21 +22,43 @@
#ifndef _UTIL_H
#define _UTIL_H
+#include <elf.h>
#include <inttypes.h>
#include <linux/audit.h>
+/**
+ * The ARM architecture tokens
+ */
+/* AArch64 support for audit was merged in 3.17-rc1 */
+#ifndef AUDIT_ARCH_AARCH64
+#ifndef EM_AARCH64
+#define EM_AARCH64 183
+#endif /* EM_AARCH64 */
+#define AUDIT_ARCH_AARCH64 (EM_AARCH64|__AUDIT_ARCH_64BIT|__AUDIT_ARCH_LE)
+#endif /* AUDIT_ARCH_AARCH64 */
+
+/**
+ * The MIPS architecture tokens
+ */
#ifndef __AUDIT_ARCH_CONVENTION_MIPS64_N32
#define __AUDIT_ARCH_CONVENTION_MIPS64_N32 0x20000000
#endif
-
-#ifndef AUDIT_ARCH_MIPS64N32
+#ifndef EM_MIPS
+#define EM_MIPS 8
+#endif
+#ifndef AUDIT_ARCH_MIPS
+#define AUDIT_ARCH_MIPS (EM_MIPS)
+#endif
+#ifndef AUDIT_ARCH_MIPS64
+#define AUDIT_ARCH_MIPS64 (EM_MIPS|__AUDIT_ARCH_64BIT)
+#endif
/* MIPS64N32 support was merged in 3.15 */
+#ifndef AUDIT_ARCH_MIPS64N32
#define AUDIT_ARCH_MIPS64N32 (EM_MIPS|__AUDIT_ARCH_64BIT|\
__AUDIT_ARCH_CONVENTION_MIPS64_N32)
#endif
-
-#ifndef AUDIT_ARCH_MIPSEL64N32
/* MIPSEL64N32 support was merged in 3.15 */
+#ifndef AUDIT_ARCH_MIPSEL64N32
#define AUDIT_ARCH_MIPSEL64N32 (EM_MIPS|__AUDIT_ARCH_64BIT|__AUDIT_ARCH_LE|\
__AUDIT_ARCH_CONVENTION_MIPS64_N32)
#endif