This patch ensures that you can create non-native filters using
syscalls not present in the native architecture.

Signed-off-by: Paul Moore <[email protected]>
---
 include/seccomp.h          |  370 ++++++++++++++++++++++++++++++++++++++++++++
 src/api.c                  |   10 +
 src/arch-i386-syscalls.c   |   10 +
 src/arch-i386.c            |   32 ++--
 src/arch-i386.h            |    3 
 src/arch-x86_64-syscalls.c |   69 ++++++++
 src/arch.c                 |   64 ++++++--
 src/arch.h                 |    3 
 tests/11-basic-errors.c    |    7 -
 tools/sys_resolver.c       |    2 
 10 files changed, 529 insertions(+), 41 deletions(-)

diff --git a/include/seccomp.h b/include/seccomp.h
index e3573b3..806ce38 100644
--- a/include/seccomp.h
+++ b/include/seccomp.h
@@ -428,6 +428,8 @@ int seccomp_export_bpf(const scmp_filter_ctx ctx, int fd);
 /* NOTE - pseudo syscall values {-1..-99} are reserved */
 #define __NR_SCMP_ERROR                -1
 
+/* socket syscalls */
+
 #define __PNR_socket           -101
 #ifndef __NR_socket
 #define __NR_socket            __PNR_socket
@@ -528,6 +530,7 @@ int seccomp_export_bpf(const scmp_filter_ctx ctx, int fd);
 #define __NR_sendmmsg          __PNR_sendmmsg
 #endif /* __NR_sendmmsg */
 
+/* ipc syscalls */
 
 #define __PNR_semop            -201
 #ifndef __NR_semop
@@ -589,6 +592,373 @@ int seccomp_export_bpf(const scmp_filter_ctx ctx, int fd);
 #define __NR_shmctl            __PNR_shmctl
 #endif /* __NR_shmctl */
 
+/* single syscalls */
+
+#define __PNR_arch_prctl       -10001
+#ifndef __NR_arch_prctl
+#define __NR_arch_prctl                __PNR_arch_prctl
+#endif /* __NR_arch_prctl */
+
+#define __PNR_bdflush          -10002
+#ifndef __NR_bdflush
+#define __NR_bdflush           __PNR_bdflush
+#endif /* __NR_bdflush */
+
+#define __PNR_break            -10003
+#ifndef __NR_break
+#define __NR_break             __PNR_break
+#endif /* __NR_break */
+
+#define __PNR_chown32          -10004
+#ifndef __NR_chown32
+#define __NR_chown32           __PNR_chown32
+#endif /* __NR_chown32 */
+
+#define __PNR_epoll_ctl_old    -10005
+#ifndef __NR_epoll_ctl_old
+#define __NR_epoll_ctl_old     __PNR_epoll_ctl_old
+#endif /* __NR_epoll_ctl_old */
+
+#define __PNR_epoll_wait_old   -10006
+#ifndef __NR_epoll_wait_old
+#define __NR_epoll_wait_old    __PNR_epoll_wait_old
+#endif /* __NR_epoll_wait_old */
+
+#define __PNR_fadvise64_64     -10007
+#ifndef __NR_fadvise64_64
+#define __NR_fadvise64_64      __PNR_fadvise64_64
+#endif /* __NR_fadvise64_64 */
+
+#define __PNR_fchown32         -10008
+#ifndef __NR_fchown32
+#define __NR_fchown32          __PNR_fchown32
+#endif /* __NR_fchown32 */
+
+#define __PNR_fcntl64          -10009
+#ifndef __NR_fcntl64
+#define __NR_fcntl64           __PNR_fcntl64
+#endif /* __NR_fcntl64 */
+
+#define __PNR_fstat64          -10010
+#ifndef __NR_fstat64
+#define __NR_fstat64           __PNR_fstat64
+#endif /* __NR_fstat64 */
+
+#define __PNR_fstatat64                -10011
+#ifndef __NR_fstatat64
+#define __NR_fstatat64         __PNR_fstatat64
+#endif /* __NR_fstatat64 */
+
+#define __PNR_fstatfs64                -10012
+#ifndef __NR_fstatfs64
+#define __NR_fstatfs64         __PNR_fstatfs64
+#endif /* __NR_fstatfs64 */
+
+#define __PNR_ftime            -10013
+#ifndef __NR_ftime
+#define __NR_ftime             __PNR_ftime
+#endif /* __NR_ftime */
+
+#define __PNR_ftruncate64      -10014
+#ifndef __NR_ftruncate64
+#define __NR_ftruncate64       __PNR_ftruncate64
+#endif /* __NR_ftruncate64 */
+
+#define __PNR_getegid32                -10015
+#ifndef __NR_getegid32
+#define __NR_getegid32         __PNR_getegid32
+#endif /* __NR_getegid32 */
+
+#define __PNR_geteuid32                -10016
+#ifndef __NR_geteuid32
+#define __NR_geteuid32         __PNR_geteuid32
+#endif /* __NR_geteuid32 */
+
+#define __PNR_getgid32         -10017
+#ifndef __NR_getgid32
+#define __NR_getgid32          __PNR_getgid32
+#endif /* __NR_getgid32 */
+
+#define __PNR_getgroups32      -10018
+#ifndef __NR_getgroups32
+#define __NR_getgroups32       __PNR_getgroups32
+#endif /* __NR_getgroups32 */
+
+#define __PNR_getresgid32      -10019
+#ifndef __NR_getresgid32
+#define __NR_getresgid32       __PNR_getresgid32
+#endif /* __NR_getresgid32 */
+
+#define __PNR_getresuid32      -10020
+#ifndef __NR_getresuid32
+#define __NR_getresuid32       __PNR_getresuid32
+#endif /* __NR_getresuid32 */
+
+#define __PNR_getuid32         -10021
+#ifndef __NR_getuid32
+#define __NR_getuid32          __PNR_getuid32
+#endif /* __NR_getuid32 */
+
+#define __PNR_gtty             -10022
+#ifndef __NR_gtty
+#define __NR_gtty              __PNR_gtty
+#endif /* __NR_gtty */
+
+#define __PNR_idle             -10023
+#ifndef __NR_idle
+#define __NR_idle              __PNR_idle
+#endif /* __NR_idle */
+
+#define __PNR_ipc              -10024
+#ifndef __NR_ipc
+#define __NR_ipc               __PNR_ipc
+#endif /* __NR_ipc */
+
+#define __PNR_lchown32         -10025
+#ifndef __NR_lchown32
+#define __NR_lchown32          __PNR_lchown32
+#endif /* __NR_lchown32 */
+
+#define __PNR__llseek          -10026
+#ifndef __NR__llseek
+#define __NR__llseek           __PNR__llseek
+#endif /* __NR__llseek */
+
+#define __PNR_lock             -10027
+#ifndef __NR_lock
+#define __NR_lock              __PNR_lock
+#endif /* __NR_lock */
+
+#define __PNR_lstat64          -10028
+#ifndef __NR_lstat64
+#define __NR_lstat64           __PNR_lstat64
+#endif /* __NR_lstat64 */
+
+#define __PNR_mmap2            -10029
+#ifndef __NR_mmap2
+#define __NR_mmap2             __PNR_mmap2
+#endif /* __NR_mmap2 */
+
+#define __PNR_mpx              -10030
+#ifndef __NR_mpx
+#define __NR_mpx               __PNR_mpx
+#endif /* __NR_mpx */
+
+#define __PNR_newfstatat       -10031
+#ifndef __NR_newfstatat
+#define __NR_newfstatat                __PNR_newfstatat
+#endif /* __NR_newfstatat */
+
+#define __PNR__newselect       -10032
+#ifndef __NR__newselect
+#define __NR__newselect                __PNR__newselect
+#endif /* __NR__newselect */
+
+#define __PNR_nice             -10033
+#ifndef __NR_nice
+#define __NR_nice              __PNR_nice
+#endif /* __NR_nice */
+
+#define __PNR_oldfstat         -10034
+#ifndef __NR_oldfstat
+#define __NR_oldfstat          __PNR_oldfstat
+#endif /* __NR_oldfstat */
+
+#define __PNR_oldlstat         -10035
+#ifndef __NR_oldlstat
+#define __NR_oldlstat          __PNR_oldlstat
+#endif /* __NR_oldlstat */
+
+#define __PNR_oldolduname      -10036
+#ifndef __NR_oldolduname
+#define __NR_oldolduname       __PNR_oldolduname
+#endif /* __NR_oldolduname */
+
+#define __PNR_oldstat          -10037
+#ifndef __NR_oldstat
+#define __NR_oldstat           __PNR_oldstat
+#endif /* __NR_oldstat */
+
+#define __PNR_olduname         -10038
+#ifndef __NR_olduname
+#define __NR_olduname          __PNR_olduname
+#endif /* __NR_olduname */
+
+#define __PNR_prof             -10039
+#ifndef __NR_prof
+#define __NR_prof              __PNR_prof
+#endif /* __NR_prof */
+
+#define __PNR_profil           -10040
+#ifndef __NR_profil
+#define __NR_profil            __PNR_profil
+#endif /* __NR_profil */
+
+#define __PNR_readdir          -10041
+#ifndef __NR_readdir
+#define __NR_readdir           __PNR_readdir
+#endif /* __NR_readdir */
+
+#define __PNR_security         -10042
+#ifndef __NR_security
+#define __NR_security          __PNR_security
+#endif /* __NR_security */
+
+#define __PNR_sendfile64       -10043
+#ifndef __NR_sendfile64
+#define __NR_sendfile64                __PNR_sendfile64
+#endif /* __NR_sendfile64 */
+
+#define __PNR_setfsgid32       -10044
+#ifndef __NR_setfsgid32
+#define __NR_setfsgid32                __PNR_setfsgid32
+#endif /* __NR_setfsgid32 */
+
+#define __PNR_setfsuid32       -10045
+#ifndef __NR_setfsuid32
+#define __NR_setfsuid32                __PNR_setfsuid32
+#endif /* __NR_setfsuid32 */
+
+#define __PNR_setgid32         -10046
+#ifndef __NR_setgid32
+#define __NR_setgid32          __PNR_setgid32
+#endif /* __NR_setgid32 */
+
+#define __PNR_setgroups32      -10047
+#ifndef __NR_setgroups32
+#define __NR_setgroups32       __PNR_setgroups32
+#endif /* __NR_setgroups32 */
+
+#define __PNR_setregid32       -10048
+#ifndef __NR_setregid32
+#define __NR_setregid32                __PNR_setregid32
+#endif /* __NR_setregid32 */
+
+#define __PNR_setresgid32      -10049
+#ifndef __NR_setresgid32
+#define __NR_setresgid32       __PNR_setresgid32
+#endif /* __NR_setresgid32 */
+
+#define __PNR_setresuid32      -10050
+#ifndef __NR_setresuid32
+#define __NR_setresuid32       __PNR_setresuid32
+#endif /* __NR_setresuid32 */
+
+#define __PNR_setreuid32       -10051
+#ifndef __NR_setreuid32
+#define __NR_setreuid32                __PNR_setreuid32
+#endif /* __NR_setreuid32 */
+
+#define __PNR_setuid32         -10052
+#ifndef __NR_setuid32
+#define __NR_setuid32          __PNR_setuid32
+#endif /* __NR_setuid32 */
+
+#define __PNR_sgetmask         -10053
+#ifndef __NR_sgetmask
+#define __NR_sgetmask          __PNR_sgetmask
+#endif /* __NR_sgetmask */
+
+#define __PNR_sigaction                -10054
+#ifndef __NR_sigaction
+#define __NR_sigaction         __PNR_sigaction
+#endif /* __NR_sigaction */
+
+#define __PNR_signal           -10055
+#ifndef __NR_signal
+#define __NR_signal            __PNR_signal
+#endif /* __NR_signal */
+
+#define __PNR_sigpending       -10056
+#ifndef __NR_sigpending
+#define __NR_sigpending                __PNR_sigpending
+#endif /* __NR_sigpending */
+
+#define __PNR_sigprocmask      -10057
+#ifndef __NR_sigprocmask
+#define __NR_sigprocmask       __PNR_sigprocmask
+#endif /* __NR_sigprocmask */
+
+#define __PNR_sigreturn                -10058
+#ifndef __NR_sigreturn
+#define __NR_sigreturn         __PNR_sigreturn
+#endif /* __NR_sigreturn */
+
+#define __PNR_sigsuspend       -10059
+#ifndef __NR_sigsuspend
+#define __NR_sigsuspend                __PNR_sigsuspend
+#endif /* __NR_sigsuspend */
+
+#define __PNR_socketcall       -10060
+#ifndef __NR_socketcall
+#define __NR_socketcall                __PNR_socketcall
+#endif /* __NR_socketcall */
+
+#define __PNR_ssetmask         -10061
+#ifndef __NR_ssetmask
+#define __NR_ssetmask          __PNR_ssetmask
+#endif /* __NR_ssetmask */
+
+#define __PNR_stat64           -10062
+#ifndef __NR_stat64
+#define __NR_stat64            __PNR_stat64
+#endif /* __NR_stat64 */
+
+#define __PNR_statfs64         -10063
+#ifndef __NR_statfs64
+#define __NR_statfs64          __PNR_statfs64
+#endif /* __NR_statfs64 */
+
+#define __PNR_stime            -10064
+#ifndef __NR_stime
+#define __NR_stime             __PNR_stime
+#endif /* __NR_stime */
+
+#define __PNR_stty             -10065
+#ifndef __NR_stty
+#define __NR_stty              __PNR_stty
+#endif /* __NR_stty */
+
+#define __PNR_truncate64       -10066
+#ifndef __NR_truncate64
+#define __NR_truncate64                __PNR_truncate64
+#endif /* __NR_truncate64 */
+
+#define __PNR_tuxcall          -10067
+#ifndef __NR_tuxcall
+#define __NR_tuxcall           __PNR_tuxcall
+#endif /* __NR_tuxcall */
+
+#define __PNR_ugetrlimit       -10068
+#ifndef __NR_ugetrlimit
+#define __NR_ugetrlimit                __PNR_ugetrlimit
+#endif /* __NR_ugetrlimit */
+
+#define __PNR_ulimit           -10069
+#ifndef __NR_ulimit
+#define __NR_ulimit            __PNR_ulimit
+#endif /* __NR_ulimit */
+
+#define __PNR_umount           -10070
+#ifndef __NR_umount
+#define __NR_umount            __PNR_umount
+#endif /* __NR_umount */
+
+#define __PNR_vm86             -10071
+#ifndef __NR_vm86
+#define __NR_vm86              __PNR_vm86
+#endif /* __NR_vm86 */
+
+#define __PNR_vm86old          -10072
+#ifndef __NR_vm86old
+#define __NR_vm86old           __PNR_vm86old
+#endif /* __NR_vm86old */
+
+#define __PNR_waitpid          -10073
+#ifndef __NR_waitpid
+#define __NR_waitpid           __PNR_waitpid
+#endif /* __NR_waitpid */
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/src/api.c b/src/api.c
index 8f03c3d..5072afc 100644
--- a/src/api.c
+++ b/src/api.c
@@ -324,8 +324,14 @@ int seccomp_syscall_priority(scmp_filter_ctx ctx, int 
syscall, uint8_t priority)
                /* if this is a pseudo syscall (syscall < 0) then we need to
                 * rewrite the syscall for some arch specific reason */
                if (syscall_tmp < 0) {
-                       rc_tmp = arch_syscall_rewrite(filter->arch,
+                       /* we set this as a strict op - we don't really care
+                        * 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,
                                                      &syscall_tmp);
+                       if (rc == -EDOM)
+                               continue;
                        if (rc_tmp < 0)
                                goto syscall_priority_failure;
                }
@@ -435,6 +441,8 @@ static int _seccomp_rule_add(struct db_filter_col *col,
                if (syscall_tmp < 0) {
                        rc_tmp = arch_filter_rewrite(filter->arch, strict,
                                                     &syscall_tmp, chain);
+                       if ((rc == -EDOM) && (!strict))
+                               continue;
                        if (rc_tmp < 0)
                                goto rule_add_failure;
                }
diff --git a/src/arch-i386-syscalls.c b/src/arch-i386-syscalls.c
index cde879c..d08d129 100644
--- a/src/arch-i386-syscalls.c
+++ b/src/arch-i386-syscalls.c
@@ -35,6 +35,7 @@ const struct arch_syscall_def i386_syscall_table[] = \
        { "adjtimex", 124 },
        { "afs_syscall", 137 },
        { "alarm", 27 },
+       { "arch_prctl", __PNR_arch_prctl },
        { "bdflush", 134 },
        { "bind", __PNR_bind },
        { "break", 17 },
@@ -63,8 +64,10 @@ const struct arch_syscall_def i386_syscall_table[] = \
        { "epoll_create", 254 },
        { "epoll_create1", 329 },
        { "epoll_ctl", 255 },
+       { "epoll_ctl_old", __PNR_epoll_ctl_old },
        { "epoll_pwait", 319 },
        { "epoll_wait", 256 },
+       { "epoll_wait_old", __PNR_epoll_wait_old },
        { "eventfd", 323 },
        { "eventfd2", 328 },
        { "execve", 11 },
@@ -213,6 +216,7 @@ const struct arch_syscall_def i386_syscall_table[] = \
        { "name_to_handle_at", 341 },
        { "nanosleep", 162 },
        { "_newselect", 142 },
+       { "newfstatat", __PNR_newfstatat },
        { "nfsservctl", 169 },
        { "nice", 34 },
        { "oldfstat", 28 },
@@ -255,8 +259,8 @@ const struct arch_syscall_def i386_syscall_table[] = \
        { "reboot", 88 },
        { "recv", __PNR_recv },
        { "recvfrom", __PNR_recvfrom },
-       { "recvmsg", __PNR_recvmsg },
        { "recvmmsg", 337 },
+       { "recvmsg", __PNR_recvmsg },
        { "remap_file_pages", 257 },
        { "removexattr", 235 },
        { "rename", 38 },
@@ -282,6 +286,7 @@ const struct arch_syscall_def i386_syscall_table[] = \
        { "sched_setparam", 154 },
        { "sched_setscheduler", 156 },
        { "sched_yield", 158 },
+       { "security", __PNR_security },
        { "select", 82 },
        { "semctl", __PNR_semctl },
        { "semget", __PNR_semget },
@@ -290,8 +295,8 @@ const struct arch_syscall_def i386_syscall_table[] = \
        { "send", __PNR_send },
        { "sendfile", 187 },
        { "sendfile64", 239 },
-       { "sendmsg", __PNR_sendmsg },
        { "sendmmsg", 345 },
+       { "sendmsg", __PNR_sendmsg },
        { "sendto", __PNR_sendto },
        { "set_mempolicy", 276 },
        { "set_robust_list", 311 },
@@ -378,6 +383,7 @@ const struct arch_syscall_def i386_syscall_table[] = \
        { "tkill", 238 },
        { "truncate", 92 },
        { "truncate64", 193 },
+       { "tuxcall", __PNR_tuxcall },
        { "ugetrlimit", 191 },
        { "ulimit", 58 },
        { "umask", 60 },
diff --git a/src/arch-i386.c b/src/arch-i386.c
index 577d6c8..8605e25 100644
--- a/src/arch-i386.c
+++ b/src/arch-i386.c
@@ -39,21 +39,26 @@ const struct arch_def arch_def_i386 = {
 /**
  * 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.  Returns
- * zero on success, negative values on failure.
+ * 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.
  *
  */
-int i386_syscall_rewrite(const struct arch_def *arch, int *syscall)
+int i386_syscall_rewrite(const struct arch_def *arch, unsigned int strict,
+                        int *syscall)
 {
        if ((*syscall) <= -100 && (*syscall) >= -117)
                *syscall = __i386_NR_socketcall;
        else if ((*syscall) <= -200 && (*syscall) >= -211)
                *syscall = __i386_NR_ipc;
-       else if ((*syscall) < 0)
-               return -EINVAL;
+       else if (((*syscall) < 0) && (strict))
+               return -EDOM;
 
        return 0;
 }
@@ -81,8 +86,8 @@ int i386_filter_rewrite(const struct arch_def *arch,
 
        if ((*syscall) <= -100 && (*syscall) >= -117) {
                for (iter = 0; iter < i386_arg_count_max; iter++) {
-                       if (chain[iter].valid != 0)
-                               goto filter_rewrite_failure;
+                       if ((chain[iter].valid != 0) && (strict))
+                               return -EINVAL;
                }
                chain[0].arg = 0;
                chain[0].op = SCMP_CMP_EQ;
@@ -92,8 +97,8 @@ int i386_filter_rewrite(const struct arch_def *arch,
                *syscall = __i386_NR_socketcall;
        } else if ((*syscall) <= -200 && (*syscall) >= -211) {
                for (iter = 0; iter < i386_arg_count_max; iter++) {
-                       if (chain[iter].valid != 0)
-                               goto filter_rewrite_failure;
+                       if ((chain[iter].valid != 0) && (strict))
+                               return -EINVAL;
                }
                chain[0].arg = 0;
                chain[0].op = SCMP_CMP_EQ;
@@ -101,13 +106,8 @@ int i386_filter_rewrite(const struct arch_def *arch,
                chain[0].datum = abs(*syscall) % 200;
                chain[0].valid = 1;
                *syscall = __i386_NR_ipc;
-       } else if ((*syscall) < 0)
-               return -EINVAL;
-
-       return 0;
+       } else if (((*syscall) < 0) && (strict))
+               return -EDOM;
 
-filter_rewrite_failure:
-       if (strict)
-               return -EINVAL;
        return 0;
 }
diff --git a/src/arch-i386.h b/src/arch-i386.h
index bc24dbe..809b769 100644
--- a/src/arch-i386.h
+++ b/src/arch-i386.h
@@ -31,7 +31,8 @@
 extern const struct arch_def arch_def_i386;
 extern const struct arch_syscall_def i386_syscall_table[];
 
-int i386_syscall_rewrite(const struct arch_def *arch, int *syscall);
+int i386_syscall_rewrite(const struct arch_def *arch, unsigned int strict,
+                        int *syscall);
 
 int i386_filter_rewrite(const struct arch_def *arch,
                        unsigned int strict,
diff --git a/src/arch-x86_64-syscalls.c b/src/arch-x86_64-syscalls.c
index f6c521d..9684be3 100644
--- a/src/arch-x86_64-syscalls.c
+++ b/src/arch-x86_64-syscalls.c
@@ -36,13 +36,16 @@ const struct arch_syscall_def x86_64_syscall_table[] = \
        { "afs_syscall", 183 },
        { "alarm", 37 },
        { "arch_prctl", 158 },
+       { "bdflush", __PNR_bdflush },
        { "bind", 49 },
+       { "break", __PNR_break },
        { "brk", 12 },
        { "capget", 125 },
        { "capset", 126 },
        { "chdir", 80 },
        { "chmod", 90 },
        { "chown", 92 },
+       { "chown32", __PNR_chown32 },
        { "chroot", 161 },
        { "clock_adjtime", 305 },
        { "clock_getres", 229 },
@@ -72,6 +75,7 @@ const struct arch_syscall_def x86_64_syscall_table[] = \
        { "exit_group", 231 },
        { "faccessat", 269 },
        { "fadvise64", 221 },
+       { "fadvise64_64", __PNR_fadvise64_64 },
        { "fallocate", 285 },
        { "fanotify_init", 300 },
        { "fanotify_mark", 301 },
@@ -79,8 +83,10 @@ const struct arch_syscall_def x86_64_syscall_table[] = \
        { "fchmod", 91 },
        { "fchmodat", 268 },
        { "fchown", 93 },
+       { "fchown32", __PNR_fchown32 },
        { "fchownat", 260 },
        { "fcntl", 72 },
+       { "fcntl64", __PNR_fcntl64 },
        { "fdatasync", 75 },
        { "fgetxattr", 193 },
        { "flistxattr", 196 },
@@ -89,9 +95,14 @@ const struct arch_syscall_def x86_64_syscall_table[] = \
        { "fremovexattr", 199 },
        { "fsetxattr", 190 },
        { "fstat", 5 },
+       { "fstat64", __PNR_fstat64 },
+       { "fstatat64", __PNR_fstatat64 },
+       { "fstatfs64", __PNR_fstatfs64 },
        { "fstatfs", 138 },
        { "fsync", 74 },
+       { "ftime", __PNR_ftime },
        { "ftruncate", 77 },
+       { "ftruncate64", __PNR_ftruncate64 },
        { "futex", 202 },
        { "futimesat", 261 },
        { "get_kernel_syms", 177 },
@@ -103,9 +114,13 @@ const struct arch_syscall_def x86_64_syscall_table[] = \
        { "getdents", 78 },
        { "getdents64", 217 },
        { "getegid", 108 },
+       { "getegid32", __PNR_getegid32 },
        { "geteuid", 107 },
+       { "geteuid32", __PNR_geteuid32 },
        { "getgid", 104 },
+       { "getgid32", __PNR_getgid32 },
        { "getgroups", 115 },
+       { "getgroups32", __PNR_getgroups32 },
        { "getitimer", 36 },
        { "getpeername", 52 },
        { "getpgid", 121 },
@@ -115,7 +130,9 @@ const struct arch_syscall_def x86_64_syscall_table[] = \
        { "getppid", 110 },
        { "getpriority", 140 },
        { "getresgid", 120 },
+       { "getresgid32", __PNR_getresgid32 },
        { "getresuid", 118 },
+       { "getresuid32", __PNR_getresuid32 },
        { "getrlimit", 97 },
        { "getrusage", 98 },
        { "getsid", 124 },
@@ -124,7 +141,10 @@ const struct arch_syscall_def x86_64_syscall_table[] = \
        { "gettid", 186 },
        { "gettimeofday", 96 },
        { "getuid", 102 },
+       { "getuid32", __PNR_getuid32 },
        { "getxattr", 191 },
+       { "gtty", __PNR_gtty },
+       { "idle", __PNR_idle },
        { "init_module", 175 },
        { "inotify_add_watch", 254 },
        { "inotify_init", 253 },
@@ -140,22 +160,27 @@ const struct arch_syscall_def x86_64_syscall_table[] = \
        { "iopl", 172 },
        { "ioprio_get", 252 },
        { "ioprio_set", 251 },
+       { "ipc", __PNR_ipc },
        { "kcmp", 312 },
        { "kexec_load", 246 },
        { "keyctl", 250 },
        { "kill", 62 },
        { "lchown", 94 },
+       { "lchown32", __PNR_lchown32 },
        { "lgetxattr", 192 },
        { "link", 86 },
        { "linkat", 265 },
        { "listen", 50 },
        { "listxattr", 194 },
        { "llistxattr", 195 },
+       { "_llseek", __PNR__llseek },
+       { "lock", __PNR_lock },
        { "lookup_dcookie", 212 },
        { "lremovexattr", 198 },
        { "lseek", 8 },
        { "lsetxattr", 189 },
        { "lstat", 6 },
+       { "lstat64", __PNR_lstat64 },
        { "madvise", 28 },
        { "mbind", 237 },
        { "migrate_pages", 256 },
@@ -167,10 +192,12 @@ const struct arch_syscall_def x86_64_syscall_table[] = \
        { "mlock", 149 },
        { "mlockall", 151 },
        { "mmap", 9 },
+       { "mmap2", __PNR_mmap2 },
        { "modify_ldt", 154 },
        { "mount", 165 },
        { "move_pages", 279 },
        { "mprotect", 10 },
+       { "mpx", __PNR_mpx },
        { "mq_getsetattr", 245 },
        { "mq_notify", 244 },
        { "mq_open", 240 },
@@ -188,8 +215,15 @@ const struct arch_syscall_def x86_64_syscall_table[] = \
        { "munmap", 11 },
        { "name_to_handle_at", 303 },
        { "nanosleep", 35 },
+       { "_newselect", __PNR__newselect },
        { "newfstatat", 262 },
+       { "nice", __PNR_nice },
        { "nfsservctl", 180 },
+       { "oldfstat", __PNR_oldfstat },
+       { "oldlstat", __PNR_oldlstat },
+       { "oldolduname", __PNR_oldolduname },
+       { "oldstat", __PNR_oldstat },
+       { "olduname", __PNR_olduname },
        { "open", 2 },
        { "open_by_handle_at", 304 },
        { "openat", 257 },
@@ -207,6 +241,8 @@ const struct arch_syscall_def x86_64_syscall_table[] = \
        { "prlimit64", 302 },
        { "process_vm_readv", 310 },
        { "process_vm_writev", 311 },
+       { "prof", __PNR_prof },
+       { "profil", __PNR_profil },
        { "pselect6", 270 },
        { "ptrace", 101 },
        { "putpmsg", 182 },
@@ -216,10 +252,12 @@ const struct arch_syscall_def x86_64_syscall_table[] = \
        { "quotactl", 179 },
        { "read", 0 },
        { "readahead", 187 },
+       { "readdir", __PNR_readdir },
        { "readlink", 89 },
        { "readlinkat", 267 },
        { "readv", 19 },
        { "reboot", 169 },
+       { "recv", __PNR_recv },
        { "recvfrom", 45 },
        { "recvmmsg", 299 },
        { "recvmsg", 47 },
@@ -254,7 +292,9 @@ const struct arch_syscall_def x86_64_syscall_table[] = \
        { "semget", 64 },
        { "semop", 65 },
        { "semtimedop", 220 },
+       { "send", __PNR_send },
        { "sendfile", 40 },
+       { "sendfile64", __PNR_sendfile64 },
        { "sendmmsg", 307 },
        { "sendmsg", 46 },
        { "sendto", 44 },
@@ -264,37 +304,59 @@ const struct arch_syscall_def x86_64_syscall_table[] = \
        { "set_tid_address", 218 },
        { "setdomainname", 171 },
        { "setfsgid", 123 },
+       { "setfsgid32", __PNR_setfsgid32 },
        { "setfsuid", 122 },
+       { "setfsuid32", __PNR_setfsuid32 },
        { "setgid", 106 },
+       { "setgid32", __PNR_setgid32 },
        { "setgroups", 116 },
+       { "setgroups32", __PNR_setgroups32 },
        { "sethostname", 170 },
        { "setitimer", 38 },
        { "setns", 308 },
        { "setpgid", 109 },
        { "setpriority", 141 },
        { "setregid", 114 },
+       { "setregid32", __PNR_setregid32 },
        { "setresgid", 119 },
+       { "setresgid32", __PNR_setresgid32 },
        { "setresuid", 117 },
+       { "setresuid32", __PNR_setresuid32 },
        { "setreuid", 113 },
+       { "setreuid32", __PNR_setreuid32 },
        { "setrlimit", 160 },
        { "setsid", 112 },
        { "setsockopt", 54 },
        { "settimeofday", 164 },
        { "setuid", 105 },
+       { "setuid32", __PNR_setuid32 },
        { "setxattr", 188 },
+       { "sgetmask", __PNR_sgetmask },
        { "shmat", 30 },
        { "shmctl", 31 },
        { "shmdt", 67 },
        { "shmget", 29 },
        { "shutdown", 48 },
+       { "sigaction", __PNR_sigaction },
        { "sigaltstack", 131 },
+       { "signal", __PNR_signal },
        { "signalfd", 282 },
        { "signalfd4", 289 },
+       { "sigpending", __PNR_sigpending },
+       { "sigprocmask", __PNR_sigprocmask },
+       { "sigreturn", __PNR_sigreturn },
+       { "sigsuspend", __PNR_sigsuspend },
        { "socket", 41 },
+       { "socketcall", __PNR_socketcall },
        { "socketpair", 53 },
        { "splice", 275 },
+       { "ssetmask", __PNR_ssetmask },
        { "stat", 4 },
+       { "stat64", __PNR_stat64 },
        { "statfs", 137 },
+       { "statfs64", __PNR_statfs64 },
+       { "stime", __PNR_stime },
+       { "stty", __PNR_stty },
        { "swapoff", 168 },
        { "swapon", 167 },
        { "symlink", 88 },
@@ -320,8 +382,12 @@ const struct arch_syscall_def x86_64_syscall_table[] = \
        { "times", 100 },
        { "tkill", 200 },
        { "truncate", 76 },
+       { "truncate64", __PNR_truncate64 },
        { "tuxcall", 184 },
+       { "ugetrlimit", __PNR_ugetrlimit },
+       { "ulimit", __PNR_ulimit },
        { "umask", 95 },
+       { "umount", __PNR_umount },
        { "umount2", 166 },
        { "uname", 63 },
        { "unlink", 87 },
@@ -334,10 +400,13 @@ const struct arch_syscall_def x86_64_syscall_table[] = \
        { "utimes", 235 },
        { "vfork", 58 },
        { "vhangup", 153 },
+       { "vm86", __PNR_vm86 },
+       { "vm86old", __PNR_vm86old },
        { "vmsplice", 278 },
        { "vserver", 236 },
        { "wait4", 61 },
        { "waitid", 247 },
+       { "waitpid", __PNR_waitpid },
        { "write", 1 },
        { "writev", 20 },
        { NULL, __NR_SCMP_ERROR },
diff --git a/src/arch.c b/src/arch.c
index a82f33f..4758296 100644
--- a/src/arch.c
+++ b/src/arch.c
@@ -267,21 +267,42 @@ 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.  Returns
- * zero on success, negative values on failure.
+ * 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.
  *
  */
-int arch_syscall_rewrite(const struct arch_def *arch, int *syscall)
+int arch_syscall_rewrite(const struct arch_def *arch, unsigned int strict,
+                        int *syscall)
 {
-       switch (arch->token) {
-       case AUDIT_ARCH_I386:
-               return i386_syscall_rewrite(arch, syscall);
-       default:
-               return -EDOM;
+       int sys = *syscall;
+
+       if (sys >= 0) {
+               /* we shouldn't be here - no rewrite needed */
+               return 0;
+       } else if (sys < 0 && sys > -100) {
+               /* reserved values */
+               return -EINVAL;
+       } else if (sys <= -100 && sys > -10000) {
+               /* rewritable syscalls */
+               switch (arch->token) {
+               case AUDIT_ARCH_I386:
+                       return i386_syscall_rewrite(arch, strict, 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)
+               return -EDOM;
+       return 0;
 }
 
 /**
@@ -303,10 +324,27 @@ int arch_filter_rewrite(const struct arch_def *arch,
                        unsigned int strict,
                        int *syscall, struct db_api_arg *chain)
 {
-       switch (arch->token) {
-       case AUDIT_ARCH_I386:
-               return i386_filter_rewrite(arch, strict, syscall, chain);
-       default:
-               return -EDOM;
+       int sys = *syscall;
+
+       if (sys >= 0) {
+               /* we shouldn't be here - no rewrite needed */
+               return 0;
+       } else if (sys < 0 && sys > -100) {
+               /* reserved values */
+               return -EINVAL;
+       } else if (sys <= -100 && sys > -10000) {
+               /* rewritable syscalls */
+               switch (arch->token) {
+               case AUDIT_ARCH_I386:
+                       return i386_filter_rewrite(arch,
+                                                  strict, syscall, chain);
+               }
+               /* 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)
+               return -EDOM;
+       return 0;
 }
diff --git a/src/arch.h b/src/arch.h
index ada353d..98f2dc0 100644
--- a/src/arch.h
+++ b/src/arch.h
@@ -95,7 +95,8 @@ 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, int *syscall);
+int arch_syscall_rewrite(const struct arch_def *arch, unsigned int strict,
+                        int *syscall);
 
 int arch_filter_rewrite(const struct arch_def *arch,
                        unsigned int strict,
diff --git a/tests/11-basic-errors.c b/tests/11-basic-errors.c
index 615a7de..07710e6 100644
--- a/tests/11-basic-errors.c
+++ b/tests/11-basic-errors.c
@@ -62,14 +62,9 @@ int main(int argc, char *argv[])
        if (ctx == NULL)
                return -1;
        else {
-               rc = seccomp_syscall_priority(ctx, -1000, 1);
-#if __i386__
+               rc = seccomp_syscall_priority(ctx, -10, 1);
                if (rc != -EINVAL)
                        return -1;
-#else
-               if (rc != -EDOM)
-                       return -1;
-#endif
        }
        seccomp_release(ctx);
        ctx = NULL;
diff --git a/tools/sys_resolver.c b/tools/sys_resolver.c
index 9fc6065..6358b30 100644
--- a/tools/sys_resolver.c
+++ b/tools/sys_resolver.c
@@ -82,7 +82,7 @@ int main(int argc, char *argv[])
        sys_num = arch_syscall_resolve_name(arch, argv[optind]);
        if (translate != 0)
                /* we ignore errors and just output the resolved number */
-               arch_syscall_rewrite(arch, &sys_num);
+               arch_syscall_rewrite(arch, 0, &sys_num);
        printf("%d\n", sys_num);
 
        return 0;


------------------------------------------------------------------------------
Master Visual Studio, SharePoint, SQL, ASP.NET, C# 2012, HTML5, CSS,
MVC, Windows 8 Apps, JavaScript and much more. Keep your skills current
with LearnDevNow - 3,200 step-by-step video tutorials by Microsoft
MVPs and experts. ON SALE this month only -- learn more at:
http://p.sf.net/sfu/learnnow-d2d
_______________________________________________
libseccomp-discuss mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/libseccomp-discuss

Reply via email to