summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Moore <pmoore@redhat.com>2013-01-21 16:56:52 -0500
committerPaul Moore <pmoore@redhat.com>2013-01-21 16:56:52 -0500
commitd76450119d16a92eb313be09612856cc7b34713f (patch)
treefeee5520d81e44c1f0a7d81bacc3eab26cc4c072
parentfeb4661dddca8442bff27f5431472d020d530412 (diff)
downloadlibseccomp-d76450119d16a92eb313be09612856cc7b34713f.tar.gz
arch: ensure full syscall coverage across x86 and x86_64
This patch ensures that you can create non-native filters using syscalls not present in the native architecture. Signed-off-by: Paul Moore <pmoore@redhat.com>
-rw-r--r--include/seccomp.h370
-rw-r--r--src/api.c10
-rw-r--r--src/arch-i386-syscalls.c10
-rw-r--r--src/arch-i386.c32
-rw-r--r--src/arch-i386.h3
-rw-r--r--src/arch-x86_64-syscalls.c69
-rw-r--r--src/arch.c64
-rw-r--r--src/arch.h3
-rw-r--r--tests/11-basic-errors.c7
-rw-r--r--tools/sys_resolver.c2
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;