Add the arch_syscall_translate() function which converts the syscall table from the native architecture to the desired architecture.
Signed-off-by: Paul Moore <[email protected]> --- 0 files changed diff --git a/src/Makefile b/src/Makefile index f2386a0..394e21a 100644 --- a/src/Makefile +++ b/src/Makefile @@ -39,7 +39,7 @@ LIB_SHARED = libseccomp.so.$(VERSION_RELEASE) OBJS = \ api.o db.o arch.o \ arch-i386.o arch-i386-syscalls.o \ - arch-x86_64-syscalls.o \ + arch-x86_64.o arch-x86_64-syscalls.o \ hash.o \ gen_pfc.o gen_bpf.o diff --git a/src/api.c b/src/api.c index 7d6bf3a..3e7f8d7 100644 --- a/src/api.c +++ b/src/api.c @@ -160,6 +160,10 @@ int seccomp_syscall_priority(scmp_filter_ctx ctx, int syscall, uint8_t priority) return -EINVAL; filter = (struct db_filter *)ctx; + rc = arch_syscall_translate(filter->arch, &syscall); + if (rc < 0) + return rc; + /* if this is a pseudo syscall (syscall < 0) then we need to rewrite * the syscall for some arch specific reason */ if (syscall < 0) { @@ -209,6 +213,10 @@ static int _seccomp_rule_add(struct db_filter *filter, if (action == filter->attr.act_default) return -EPERM; + rc = arch_syscall_translate(filter->arch, &syscall); + if (rc < 0) + return rc; + /* collect the arguments for the filter rule */ chain_len_max = arch_arg_count_max(filter->arch); chain = malloc(sizeof(*chain) * chain_len_max); diff --git a/src/arch-i386.c b/src/arch-i386.c index 7695bfc..577d6c8 100644 --- a/src/arch-i386.c +++ b/src/arch-i386.c @@ -21,6 +21,7 @@ #include <stdlib.h> #include <errno.h> +#include <linux/audit.h> #include "arch.h" #include "arch-i386.h" @@ -29,6 +30,12 @@ #define __i386_NR_socketcall 102 #define __i386_NR_ipc 117 +const struct arch_def arch_def_i386 = { + .token = AUDIT_ARCH_I386, + .size = ARCH_SIZE_32, + .endian = ARCH_ENDIAN_LITTLE, +}; + /** * Rewrite a syscall value to match the architecture * @param arch the architecture definition diff --git a/src/arch-i386.h b/src/arch-i386.h index cea4e9a..bc24dbe 100644 --- a/src/arch-i386.h +++ b/src/arch-i386.h @@ -28,6 +28,7 @@ #define i386_arg_count_max 6 +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); diff --git a/src/arch-x86_64.c b/src/arch-x86_64.c new file mode 100644 index 0000000..9f6af9c --- /dev/null +++ b/src/arch-x86_64.c @@ -0,0 +1,33 @@ +/** + * Enhanced Seccomp x86_64 Specific Code + * + * Copyright (c) 2012 Red Hat <[email protected]> + * Author: Paul Moore <[email protected]> + */ + +/* + * 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 <stdlib.h> +#include <errno.h> +#include <linux/audit.h> + +#include "arch.h" +#include "arch-x86_64.h" + +const struct arch_def arch_def_x86_64 = { + .token = AUDIT_ARCH_X86_64, + .size = ARCH_SIZE_64, + .endian = ARCH_ENDIAN_LITTLE, +}; diff --git a/src/arch-x86_64.h b/src/arch-x86_64.h index 3f13c17..73de6db 100644 --- a/src/arch-x86_64.h +++ b/src/arch-x86_64.h @@ -29,6 +29,7 @@ #define x86_64_arg_count_max 6 +extern const struct arch_def arch_def_x86_64; extern const struct arch_syscall_def x86_64_syscall_table[]; #define x86_64_arg_offset_lo(x) (arch_arg_offset(x)) diff --git a/src/arch.c b/src/arch.c index ddd6dce..8ab3c0a 100644 --- a/src/arch.c +++ b/src/arch.c @@ -59,6 +59,27 @@ const struct arch_def arch_def_native = { }; /** + * Lookup the syscall table for an architecture + * @param token the architecure token + * + * Return the architecture's syscall table, returns NULL on failure. + * + */ +const struct arch_syscall_def *_arch_def_lookup(uint32_t token) +{ + switch (token) { + case AUDIT_ARCH_I386: + return i386_syscall_table; + break; + case AUDIT_ARCH_X86_64: + return x86_64_syscall_table; + break; + } + + return NULL; +} + +/** * Determine the maximum number of syscall arguments * @param arch the architecture definition * @@ -133,16 +154,9 @@ int arch_syscall_resolve_name(const struct arch_def *arch, const char *name) unsigned int iter; const struct arch_syscall_def *table; - switch (arch->token) { - case AUDIT_ARCH_I386: - table = i386_syscall_table; - break; - case AUDIT_ARCH_X86_64: - table = x86_64_syscall_table; - break; - default: + table = _arch_def_lookup(arch->token); + if (table == NULL) return __NR_SCMP_ERROR; - } /* XXX - plenty of room for future improvement here */ for (iter = 0; table[iter].name != NULL; iter++) { @@ -168,16 +182,9 @@ const char *arch_syscall_resolve_num(const struct arch_def *arch, int num) unsigned int iter; const struct arch_syscall_def *table; - switch (arch->token) { - case AUDIT_ARCH_I386: - table = i386_syscall_table; - break; - case AUDIT_ARCH_X86_64: - table = x86_64_syscall_table; - break; - default: + table = _arch_def_lookup(arch->token); + if (table == NULL) return NULL; - } /* XXX - plenty of room for future improvement here */ for (iter = 0; table[iter].num != __NR_SCMP_ERROR; iter++) { @@ -189,6 +196,36 @@ const char *arch_syscall_resolve_num(const struct arch_def *arch, int num) } /** + * Translate the syscall number + * @param arch the architecture definition + * @param syscall the syscall number + * + * Translate the syscall number, in the context of the native architecure, to + * the provided architecure. Returns zero on success, negative values on + * failure. + * + */ +int arch_syscall_translate(const struct arch_def *arch, int *syscall) +{ + int sc_num; + const char *sc_name; + + if (arch->token != arch_def_native.token) { + sc_name = arch_syscall_resolve_num(&arch_def_native, *syscall); + if (sc_name == NULL) + return -EFAULT; + + sc_num = arch_syscall_resolve_name(arch, sc_name); + if (sc_num == __NR_SCMP_ERROR) + return -EFAULT; + + *syscall = sc_num; + } + + return 0; +} + +/** * Rewrite a syscall value to match the architecture * @param arch the architecture definition * @param syscall the syscall number diff --git a/src/arch.h b/src/arch.h index 31a965e..4e14ca6 100644 --- a/src/arch.h +++ b/src/arch.h @@ -89,6 +89,7 @@ int arch_arg_offset_hi(const struct arch_def *arch, unsigned int arg); 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_filter_rewrite(const struct arch_def *arch, ------------------------------------------------------------------------------ Don't let slow site performance ruin your business. Deploy New Relic APM Deploy New Relic app performance management and know exactly what is happening inside your Ruby, Python, PHP, Java, and .NET app Try New Relic at no cost today and get our sweet Data Nerd shirt too! http://p.sf.net/sfu/newrelic-dev2dev _______________________________________________ libseccomp-discuss mailing list [email protected] https://lists.sourceforge.net/lists/listinfo/libseccomp-discuss
