This patch adds a dead simple, and a bit hack-ish, little program that checks the internal syscall tables for consistency across the different supported architectures. We also tie this test into the autotools test infrastructure. This should be of particular importance when adding or updating architectures.
This patch also fixed some automake/libtool problems which were causing us to double-build some objects under src/. Signed-off-by: Paul Moore <[email protected]> --- Makefile.am | 1 src/Makefile.am | 40 ++++++++++------ src/arch-arm-syscalls.c | 14 ++++++ src/arch-arm.h | 2 + src/arch-mips-syscalls.c | 14 ++++++ src/arch-mips.h | 2 + src/arch-syscall-check.c | 109 ++++++++++++++++++++++++++++++++++++++++++++ src/arch-x86-syscalls.c | 16 ++++++ src/arch-x86.h | 2 + src/arch-x86_64-syscalls.c | 15 ++++++ src/arch-x86_64.h | 2 + 11 files changed, 201 insertions(+), 16 deletions(-) create mode 100644 src/arch-syscall-check.c diff --git a/Makefile.am b/Makefile.am index b70e4fa..4709b78 100644 --- a/Makefile.am +++ b/Makefile.am @@ -29,6 +29,7 @@ AM_MAKEFLAGS_ = ${AM_MAKEFLAGS_0} AM_MAKEFLAGS = ${AM_MAKEFLAGS_@AM_V@} check-build: all + ${MAKE} ${AM_MAKEFLAGS} -C src check-build ${MAKE} ${AM_MAKEFLAGS} -C tests check-build check-syntax: diff --git a/src/Makefile.am b/src/Makefile.am index 5062c55..d95c0a6 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -21,26 +21,36 @@ if ENABLE_PYTHON SUBDIRS += python endif -SOURCES = \ - api.c arch.c db.c gen_pfc.c gen_bpf.c hash.c \ - arch-x86.c arch-x86-syscalls.c \ - arch-x86_64.c arch-x86_64-syscalls.c \ - arch-x32.c arch-x32-syscalls.c \ - arch-arm.c arch-arm-syscalls.c \ - arch-mips.c arch-mips-syscalls.c \ - \ - arch.h db.h gen_bpf.h gen_pfc.h hash.h system.h \ - arch-x86.h arch-x86_64.h arch-x32.h\ - arch-arm.h \ - arch-mips.h +SOURCES_ARCH = \ + arch.c arch.h \ + arch-x86.h arch-x86.c arch-x86-syscalls.c \ + arch-x86_64.h arch-x86_64.c arch-x86_64-syscalls.c \ + arch-x32.h arch-x32.c arch-x32-syscalls.c \ + arch-arm.h arch-arm.c arch-arm-syscalls.c \ + arch-mips.h arch-mips.c arch-mips-syscalls.c -noinst_LTLIBRARIES = libseccomp-internal.la +SOURCES_GEN = \ + api.c system.h \ + db.h db.c \ + hash.h hash.c \ + gen_pfc.h gen_pfc.c gen_bpf.h gen_bpf.c + +TESTS = arch-syscall-check -libseccomp_internal_la_SOURCES = ${SOURCES} +check_PROGRAMS = arch-syscall-check +noinst_LTLIBRARIES = libseccomp-internal.la lib_LTLIBRARIES = libseccomp.la -libseccomp_la_SOURCES = ${SOURCES} +arch_syscall_check_SOURCES = arch-syscall-check.c +arch_syscall_check_LDADD = libseccomp-internal.la + +libseccomp_internal_la_SOURCES = ${SOURCES_GEN} ${SOURCES_ARCH} + +libseccomp_la_SOURCES = libseccomp-internal.la libseccomp_la_CFLAGS = -fvisibility=hidden libseccomp_la_LDFLAGS = \ -version-number ${VERSION_MAJOR}:${VERSION_MINOR}:${VERSION_MICRO} + +check-build: + ${MAKE} ${AM_MAKEFLAGS} ${check_PROGRAMS} diff --git a/src/arch-arm-syscalls.c b/src/arch-arm-syscalls.c index 66db33b..898bc5c 100644 --- a/src/arch-arm-syscalls.c +++ b/src/arch-arm-syscalls.c @@ -477,3 +477,17 @@ const char *arm_syscall_resolve_num(int num) return NULL; } + +/** + * Iterate through the syscall table and return the syscall name + * @param spot the offset into the syscall table + * + * Return the syscall name at position @spot or NULL on failure. This function + * should only ever be used internally by libseccomp. + * + */ +const char *arm_syscall_iterate_name(unsigned int spot) +{ + /* XXX - no safety checks here */ + return arm_syscall_table[spot].name; +} diff --git a/src/arch-arm.h b/src/arch-arm.h index c585ab1..4ffa167 100644 --- a/src/arch-arm.h +++ b/src/arch-arm.h @@ -36,4 +36,6 @@ extern const struct arch_def arch_def_arm; int arm_syscall_resolve_name(const char *name); const char *arm_syscall_resolve_num(int num); +const char *arm_syscall_iterate_name(unsigned int spot); + #endif diff --git a/src/arch-mips-syscalls.c b/src/arch-mips-syscalls.c index 30d281b..aa3d114 100644 --- a/src/arch-mips-syscalls.c +++ b/src/arch-mips-syscalls.c @@ -470,3 +470,17 @@ const char *mips_syscall_resolve_num(int num) return NULL; } + +/** + * Iterate through the syscall table and return the syscall name + * @param spot the offset into the syscall table + * + * Return the syscall name at position @spot or NULL on failure. This function + * should only ever be used internally by libseccomp. + * + */ +const char *mips_syscall_iterate_name(unsigned int spot) +{ + /* XXX - no safety checks here */ + return mips_syscall_table[spot].name; +} diff --git a/src/arch-mips.h b/src/arch-mips.h index 1258c26..02ca347 100644 --- a/src/arch-mips.h +++ b/src/arch-mips.h @@ -39,4 +39,6 @@ extern const struct arch_def arch_def_mipsel; int mips_syscall_resolve_name(const char *name); const char *mips_syscall_resolve_num(int num); +const char *mips_syscall_iterate_name(unsigned int spot); + #endif diff --git a/src/arch-syscall-check.c b/src/arch-syscall-check.c new file mode 100644 index 0000000..9198682 --- /dev/null +++ b/src/arch-syscall-check.c @@ -0,0 +1,109 @@ +/** + * Enhanced Seccomp Architecture Sycall Checker + * + * Copyright (c) 2014 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 <stdio.h> +#include <string.h> + +#include "arch.h" +#include "arch-x86.h" +#include "arch-x86_64.h" +#include "arch-arm.h" +#include "arch-mips.h" + +void syscall_check(char *str_miss, const char *syscall, + const char *arch_name, const char *arch_sys) +{ + if (strcmp(syscall, arch_sys)) { + if (str_miss[0] != '\0') + strcat(str_miss, ","); + strcat(str_miss, arch_name); + } +} + +int main(int argc, char *argv[]) +{ + int i_x86 = 0; + int i_x86_64 = 0; + int i_arm = 0; + int i_mips = 0; + const char *sys_name, *tmp; + char str_miss[256]; + + do { + str_miss[0] = '\0'; + tmp = x86_syscall_iterate_name(i_x86); + if (tmp) + sys_name = tmp; + + /* check each arch using x86 as the reference */ + syscall_check(str_miss, sys_name, + "x86_64", x86_64_syscall_iterate_name(i_x86_64)); + syscall_check(str_miss, sys_name, + "arm", arm_syscall_iterate_name(i_arm)); + syscall_check(str_miss, sys_name, + "mips", mips_syscall_iterate_name(i_mips)); + + /* output the results */ + printf("%s: ", sys_name); + if (str_miss[0] != '\0') { + printf("MISS(%s)\n", str_miss); + return 1; + } else + printf("OK\n"); + + /* next */ + if (x86_syscall_iterate_name(i_x86 + 1)) + i_x86++; + if (!x86_64_syscall_iterate_name(++i_x86_64)) + i_x86_64 = -1; + if (!arm_syscall_iterate_name(++i_arm)) + i_arm = -1; + if (!mips_syscall_iterate_name(++i_mips)) + i_mips = -1; + } while (i_x86_64 >= 0 && i_arm >= 0 && i_mips >= 0); + + /* check for any leftovers */ + tmp = x86_syscall_iterate_name(i_x86 + 1); + if (tmp) { + printf("%s: ERROR, x86 has additional syscalls\n", tmp); + return 1; + } + if (i_x86_64 >= 0) { + printf("%s: ERROR, x86_64 has additional syscalls\n", + x86_64_syscall_iterate_name(i_x86_64)); + return 1; + } + if (i_arm >= 0) { + printf("%s: ERROR, arm has additional syscalls\n", + arm_syscall_iterate_name(i_arm)); + return 1; + } + if (i_mips >= 0) { + printf("%s: ERROR, mips has additional syscalls\n", + mips_syscall_iterate_name(i_mips)); + return 1; + } + + /* if we made it here, all is good */ + return 0; +} diff --git a/src/arch-x86-syscalls.c b/src/arch-x86-syscalls.c index 79f1b91..760cf3d 100644 --- a/src/arch-x86-syscalls.c +++ b/src/arch-x86-syscalls.c @@ -27,7 +27,7 @@ #include "arch-x86.h" /* NOTE: based on Linux 3.4.7 */ -static const struct arch_syscall_def x86_syscall_table[] = { \ +const struct arch_syscall_def x86_syscall_table[] = { \ { "accept", __PNR_accept }, { "accept4", __PNR_accept4 }, { "access", 33 }, @@ -466,3 +466,17 @@ const char *x86_syscall_resolve_num(int num) return NULL; } + +/** + * Iterate through the syscall table and return the syscall name + * @param spot the offset into the syscall table + * + * Return the syscall name at position @spot or NULL on failure. This function + * should only ever be used internally by libseccomp. + * + */ +const char *x86_syscall_iterate_name(unsigned int spot) +{ + /* XXX - no safety checks here */ + return x86_syscall_table[spot].name; +} diff --git a/src/arch-x86.h b/src/arch-x86.h index 0e9a370..9461f3d 100644 --- a/src/arch-x86.h +++ b/src/arch-x86.h @@ -37,6 +37,8 @@ extern const struct arch_def arch_def_x86; int x86_syscall_resolve_name(const char *name); const char *x86_syscall_resolve_num(int num); +const char *x86_syscall_iterate_name(unsigned int spot); + int x86_syscall_rewrite(const struct arch_def *arch, bool strict, int *syscall); int x86_filter_rewrite(const struct arch_def *arch, bool strict, diff --git a/src/arch-x86_64-syscalls.c b/src/arch-x86_64-syscalls.c index af095b8..bceb352 100644 --- a/src/arch-x86_64-syscalls.c +++ b/src/arch-x86_64-syscalls.c @@ -466,3 +466,18 @@ const char *x86_64_syscall_resolve_num(int num) return NULL; } + +/** + * Iterate through the syscall table and return the syscall name + * @param spot the offset into the syscall table + * + * Return the syscall name at position @spot or NULL on failure. This function + * should only ever be used internally by libseccomp. + * + */ +const char *x86_64_syscall_iterate_name(unsigned int spot) +{ + /* XXX - no safety checks here */ + return x86_64_syscall_table[spot].name; +} + diff --git a/src/arch-x86_64.h b/src/arch-x86_64.h index 1fd3114..babb049 100644 --- a/src/arch-x86_64.h +++ b/src/arch-x86_64.h @@ -38,4 +38,6 @@ extern const struct arch_def arch_def_x86_64; int x86_64_syscall_resolve_name(const char *name); const char *x86_64_syscall_resolve_num(int num); +const char *x86_64_syscall_iterate_name(unsigned int spot); + #endif ------------------------------------------------------------------------------ Learn Graph Databases - Download FREE O'Reilly Book "Graph Databases" is the definitive new guide to graph databases and their applications. Written by three acclaimed leaders in the field, this first edition is now available. Download your free book today! http://p.sf.net/sfu/NeoTech _______________________________________________ libseccomp-discuss mailing list [email protected] https://lists.sourceforge.net/lists/listinfo/libseccomp-discuss
