diff options
author | Paul Moore <pmoore@redhat.com> | 2013-01-21 16:56:52 -0500 |
---|---|---|
committer | Paul Moore <pmoore@redhat.com> | 2013-01-21 16:56:52 -0500 |
commit | d76450119d16a92eb313be09612856cc7b34713f (patch) | |
tree | feee5520d81e44c1f0a7d81bacc3eab26cc4c072 | |
parent | feb4661dddca8442bff27f5431472d020d530412 (diff) | |
download | libseccomp-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.h | 370 | ||||
-rw-r--r-- | src/api.c | 10 | ||||
-rw-r--r-- | src/arch-i386-syscalls.c | 10 | ||||
-rw-r--r-- | src/arch-i386.c | 32 | ||||
-rw-r--r-- | src/arch-i386.h | 3 | ||||
-rw-r--r-- | src/arch-x86_64-syscalls.c | 69 | ||||
-rw-r--r-- | src/arch.c | 64 | ||||
-rw-r--r-- | src/arch.h | 3 | ||||
-rw-r--r-- | tests/11-basic-errors.c | 7 | ||||
-rw-r--r-- | 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 @@ -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 }, @@ -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; } @@ -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; |