diff options
Diffstat (limited to 'src')
62 files changed, 19144 insertions, 0 deletions
diff --git a/src/Makefile.am b/src/Makefile.am new file mode 100644 index 0000000..1e5c092 --- /dev/null +++ b/src/Makefile.am @@ -0,0 +1,77 @@ +#### +# Seccomp Library Source Files +# + +# +# 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>. +# + +SUBDIRS = . +if ENABLE_PYTHON +SUBDIRS += python +endif + +SOURCES_ALL = \ + api.c system.h system.c helper.h helper.c \ + gen_pfc.h gen_pfc.c gen_bpf.h gen_bpf.c \ + hash.h hash.c \ + db.h db.c \ + arch.c arch.h \ + arch-x86.h arch-x86.c \ + arch-x86_64.h arch-x86_64.c \ + arch-x32.h arch-x32.c \ + arch-arm.h arch-arm.c \ + arch-aarch64.h arch-aarch64.c \ + arch-mips.h arch-mips.c \ + arch-mips64.h arch-mips64.c \ + arch-mips64n32.h arch-mips64n32.c \ + arch-parisc.h arch-parisc.c \ + arch-parisc64.h arch-parisc64.c \ + arch-ppc.h arch-ppc.c \ + arch-ppc64.h arch-ppc64.c \ + arch-riscv64.h arch-riscv64.c \ + arch-s390.h arch-s390.c \ + arch-s390x.h arch-s390x.c \ + syscalls.h syscalls.c syscalls.perf.c + +EXTRA_DIST = \ + arch-syscall-validate arch-syscall-check \ + arch-gperf-generate syscalls.csv syscalls.perf.template + +TESTS = arch-syscall-check + +check_PROGRAMS = arch-syscall-dump + +lib_LTLIBRARIES = libseccomp.la + +arch_syscall_dump_SOURCES = arch-syscall-dump.c ${SOURCES_ALL} + +libseccomp_la_SOURCES = ${SOURCES_ALL} +libseccomp_la_CPPFLAGS = ${AM_CPPFLAGS} ${CODE_COVERAGE_CPPFLAGS} +libseccomp_la_CFLAGS = ${AM_CFLAGS} ${CODE_COVERAGE_CFLAGS} ${CFLAGS} \ + -fPIC -DPIC -fvisibility=hidden +libseccomp_la_LDFLAGS = ${AM_LDFLAGS} ${CODE_COVERAGE_LDFLAGS} ${LDFLAGS} \ + -version-number ${VERSION_MAJOR}:${VERSION_MINOR}:${VERSION_MICRO} + +EXTRA_DIST += syscalls.perf.c syscalls.perf +CLEANFILES = syscalls.perf.c syscalls.perf + +syscalls.perf: syscalls.csv syscalls.perf.template + ${AM_V_GEN} ${srcdir}/arch-gperf-generate \ + ${srcdir}/syscalls.csv ${srcdir}/syscalls.perf.template + +syscalls.perf.c: syscalls.perf + ${GPERF} -m 100 --null-strings --pic -tCEG -T -S1 $< > $@ + +check-build: + ${MAKE} ${AM_MAKEFLAGS} ${check_PROGRAMS} diff --git a/src/Makefile.in b/src/Makefile.in new file mode 100644 index 0000000..fa6fe98 --- /dev/null +++ b/src/Makefile.in @@ -0,0 +1,1387 @@ +# Makefile.in generated by automake 1.16.5 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2021 Free Software Foundation, Inc. + +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +#### +# Seccomp Library Source Files +# + +# +# 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>. +# + +VPATH = @srcdir@ +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +@ENABLE_PYTHON_TRUE@am__append_1 = python +check_PROGRAMS = arch-syscall-dump$(EXEEXT) +subdir = src +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/ax_code_coverage.m4 \ + $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ + $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ + $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/configure.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; +am__install_max = 40 +am__nobase_strip_setup = \ + srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` +am__nobase_strip = \ + for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" +am__nobase_list = $(am__nobase_strip_setup); \ + for p in $$list; do echo "$$p $$p"; done | \ + sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ + $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ + if (++n[$$2] == $(am__install_max)) \ + { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ + END { for (dir in files) print dir, files[dir] }' +am__base_list = \ + sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ + sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__uninstall_files_from_dir = { \ + test -z "$$files" \ + || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ + || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ + $(am__cd) "$$dir" && rm -f $$files; }; \ + } +am__installdirs = "$(DESTDIR)$(libdir)" +LTLIBRARIES = $(lib_LTLIBRARIES) +libseccomp_la_LIBADD = +am__objects_1 = libseccomp_la-api.lo libseccomp_la-system.lo \ + libseccomp_la-helper.lo libseccomp_la-gen_pfc.lo \ + libseccomp_la-gen_bpf.lo libseccomp_la-hash.lo \ + libseccomp_la-db.lo libseccomp_la-arch.lo \ + libseccomp_la-arch-x86.lo libseccomp_la-arch-x86_64.lo \ + libseccomp_la-arch-x32.lo libseccomp_la-arch-arm.lo \ + libseccomp_la-arch-aarch64.lo libseccomp_la-arch-mips.lo \ + libseccomp_la-arch-mips64.lo libseccomp_la-arch-mips64n32.lo \ + libseccomp_la-arch-parisc.lo libseccomp_la-arch-parisc64.lo \ + libseccomp_la-arch-ppc.lo libseccomp_la-arch-ppc64.lo \ + libseccomp_la-arch-riscv64.lo libseccomp_la-arch-s390.lo \ + libseccomp_la-arch-s390x.lo libseccomp_la-syscalls.lo \ + libseccomp_la-syscalls.perf.lo +am_libseccomp_la_OBJECTS = $(am__objects_1) +libseccomp_la_OBJECTS = $(am_libseccomp_la_OBJECTS) +AM_V_lt = $(am__v_lt_@AM_V@) +am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) +am__v_lt_0 = --silent +am__v_lt_1 = +libseccomp_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(libseccomp_la_CFLAGS) \ + $(CFLAGS) $(libseccomp_la_LDFLAGS) $(LDFLAGS) -o $@ +am__objects_2 = api.$(OBJEXT) system.$(OBJEXT) helper.$(OBJEXT) \ + gen_pfc.$(OBJEXT) gen_bpf.$(OBJEXT) hash.$(OBJEXT) \ + db.$(OBJEXT) arch.$(OBJEXT) arch-x86.$(OBJEXT) \ + arch-x86_64.$(OBJEXT) arch-x32.$(OBJEXT) arch-arm.$(OBJEXT) \ + arch-aarch64.$(OBJEXT) arch-mips.$(OBJEXT) \ + arch-mips64.$(OBJEXT) arch-mips64n32.$(OBJEXT) \ + arch-parisc.$(OBJEXT) arch-parisc64.$(OBJEXT) \ + arch-ppc.$(OBJEXT) arch-ppc64.$(OBJEXT) arch-riscv64.$(OBJEXT) \ + arch-s390.$(OBJEXT) arch-s390x.$(OBJEXT) syscalls.$(OBJEXT) \ + syscalls.perf.$(OBJEXT) +am_arch_syscall_dump_OBJECTS = arch-syscall-dump.$(OBJEXT) \ + $(am__objects_2) +arch_syscall_dump_OBJECTS = $(am_arch_syscall_dump_OBJECTS) +arch_syscall_dump_LDADD = $(LDADD) +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp +am__maybe_remake_depfiles = depfiles +am__depfiles_remade = ./$(DEPDIR)/api.Po ./$(DEPDIR)/arch-aarch64.Po \ + ./$(DEPDIR)/arch-arm.Po ./$(DEPDIR)/arch-mips.Po \ + ./$(DEPDIR)/arch-mips64.Po ./$(DEPDIR)/arch-mips64n32.Po \ + ./$(DEPDIR)/arch-parisc.Po ./$(DEPDIR)/arch-parisc64.Po \ + ./$(DEPDIR)/arch-ppc.Po ./$(DEPDIR)/arch-ppc64.Po \ + ./$(DEPDIR)/arch-riscv64.Po ./$(DEPDIR)/arch-s390.Po \ + ./$(DEPDIR)/arch-s390x.Po ./$(DEPDIR)/arch-syscall-dump.Po \ + ./$(DEPDIR)/arch-x32.Po ./$(DEPDIR)/arch-x86.Po \ + ./$(DEPDIR)/arch-x86_64.Po ./$(DEPDIR)/arch.Po \ + ./$(DEPDIR)/db.Po ./$(DEPDIR)/gen_bpf.Po \ + ./$(DEPDIR)/gen_pfc.Po ./$(DEPDIR)/hash.Po \ + ./$(DEPDIR)/helper.Po ./$(DEPDIR)/libseccomp_la-api.Plo \ + ./$(DEPDIR)/libseccomp_la-arch-aarch64.Plo \ + ./$(DEPDIR)/libseccomp_la-arch-arm.Plo \ + ./$(DEPDIR)/libseccomp_la-arch-mips.Plo \ + ./$(DEPDIR)/libseccomp_la-arch-mips64.Plo \ + ./$(DEPDIR)/libseccomp_la-arch-mips64n32.Plo \ + ./$(DEPDIR)/libseccomp_la-arch-parisc.Plo \ + ./$(DEPDIR)/libseccomp_la-arch-parisc64.Plo \ + ./$(DEPDIR)/libseccomp_la-arch-ppc.Plo \ + ./$(DEPDIR)/libseccomp_la-arch-ppc64.Plo \ + ./$(DEPDIR)/libseccomp_la-arch-riscv64.Plo \ + ./$(DEPDIR)/libseccomp_la-arch-s390.Plo \ + ./$(DEPDIR)/libseccomp_la-arch-s390x.Plo \ + ./$(DEPDIR)/libseccomp_la-arch-x32.Plo \ + ./$(DEPDIR)/libseccomp_la-arch-x86.Plo \ + ./$(DEPDIR)/libseccomp_la-arch-x86_64.Plo \ + ./$(DEPDIR)/libseccomp_la-arch.Plo \ + ./$(DEPDIR)/libseccomp_la-db.Plo \ + ./$(DEPDIR)/libseccomp_la-gen_bpf.Plo \ + ./$(DEPDIR)/libseccomp_la-gen_pfc.Plo \ + ./$(DEPDIR)/libseccomp_la-hash.Plo \ + ./$(DEPDIR)/libseccomp_la-helper.Plo \ + ./$(DEPDIR)/libseccomp_la-syscalls.Plo \ + ./$(DEPDIR)/libseccomp_la-syscalls.perf.Plo \ + ./$(DEPDIR)/libseccomp_la-system.Plo ./$(DEPDIR)/syscalls.Po \ + ./$(DEPDIR)/syscalls.perf.Po ./$(DEPDIR)/system.Po +am__mv = mv -f +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CFLAGS) $(CFLAGS) +AM_V_CC = $(am__v_CC_@AM_V@) +am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) +am__v_CC_0 = @echo " CC " $@; +am__v_CC_1 = +CCLD = $(CC) +LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CCLD = $(am__v_CCLD_@AM_V@) +am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) +am__v_CCLD_0 = @echo " CCLD " $@; +am__v_CCLD_1 = +SOURCES = $(libseccomp_la_SOURCES) $(arch_syscall_dump_SOURCES) +DIST_SOURCES = $(libseccomp_la_SOURCES) $(arch_syscall_dump_SOURCES) +RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ + ctags-recursive dvi-recursive html-recursive info-recursive \ + install-data-recursive install-dvi-recursive \ + install-exec-recursive install-html-recursive \ + install-info-recursive install-pdf-recursive \ + install-ps-recursive install-recursive installcheck-recursive \ + installdirs-recursive pdf-recursive ps-recursive \ + tags-recursive uninstall-recursive +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ + distclean-recursive maintainer-clean-recursive +am__recursive_targets = \ + $(RECURSIVE_TARGETS) \ + $(RECURSIVE_CLEAN_TARGETS) \ + $(am__extra_recursive_targets) +AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ + distdir distdir-am +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` +am__tty_colors_dummy = \ + mgn= red= grn= lgn= blu= brg= std=; \ + am__color_tests=no +am__tty_colors = { \ + $(am__tty_colors_dummy); \ + if test "X$(AM_COLOR_TESTS)" = Xno; then \ + am__color_tests=no; \ + elif test "X$(AM_COLOR_TESTS)" = Xalways; then \ + am__color_tests=yes; \ + elif test "X$$TERM" != Xdumb && { test -t 1; } 2>/dev/null; then \ + am__color_tests=yes; \ + fi; \ + if test $$am__color_tests = yes; then \ + red='[0;31m'; \ + grn='[0;32m'; \ + lgn='[1;32m'; \ + blu='[1;34m'; \ + mgn='[0;35m'; \ + brg='[1m'; \ + std='[m'; \ + fi; \ +} +DIST_SUBDIRS = . python +am__DIST_COMMON = $(srcdir)/Makefile.in \ + $(top_srcdir)/build-aux/depcomp +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +am__relativize = \ + dir0=`pwd`; \ + sed_first='s,^\([^/]*\)/.*$$,\1,'; \ + sed_rest='s,^[^/]*/*,,'; \ + sed_last='s,^.*/\([^/]*\)$$,\1,'; \ + sed_butlast='s,/*[^/]*$$,,'; \ + while test -n "$$dir1"; do \ + first=`echo "$$dir1" | sed -e "$$sed_first"`; \ + if test "$$first" != "."; then \ + if test "$$first" = ".."; then \ + dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ + dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ + else \ + first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ + if test "$$first2" = "$$first"; then \ + dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ + else \ + dir2="../$$dir2"; \ + fi; \ + dir0="$$dir0"/"$$first"; \ + fi; \ + fi; \ + dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ + done; \ + reldir="$$dir2" +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AM_CFLAGS = @AM_CFLAGS@ +AM_CPPFLAGS = @AM_CPPFLAGS@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AM_LDFLAGS = @AM_LDFLAGS@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CODE_COVERAGE_CFLAGS = @CODE_COVERAGE_CFLAGS@ +CODE_COVERAGE_CPPFLAGS = @CODE_COVERAGE_CPPFLAGS@ +CODE_COVERAGE_CXXFLAGS = @CODE_COVERAGE_CXXFLAGS@ +CODE_COVERAGE_ENABLED = @CODE_COVERAGE_ENABLED@ +CODE_COVERAGE_LDFLAGS = @CODE_COVERAGE_LDFLAGS@ +CODE_COVERAGE_LIBS = @CODE_COVERAGE_LIBS@ +CPPFLAGS = @CPPFLAGS@ +CSCOPE = @CSCOPE@ +CTAGS = @CTAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +ETAGS = @ETAGS@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +FILECMD = @FILECMD@ +GCOV = @GCOV@ +GENHTML = @GENHTML@ +GPERF = @GPERF@ +GREP = @GREP@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LCOV = @LCOV@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PYTHON = @PYTHON@ +PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ +PYTHON_PLATFORM = @PYTHON_PLATFORM@ +PYTHON_PREFIX = @PYTHON_PREFIX@ +PYTHON_VERSION = @PYTHON_VERSION@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +VERSION_MAJOR = @VERSION_MAJOR@ +VERSION_MICRO = @VERSION_MICRO@ +VERSION_MINOR = @VERSION_MINOR@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +cython = @cython@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +have_coverity = @have_coverity@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +pkgpyexecdir = @pkgpyexecdir@ +pkgpythondir = @pkgpythondir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +pyexecdir = @pyexecdir@ +pythondir = @pythondir@ +runstatedir = @runstatedir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +SUBDIRS = . $(am__append_1) +SOURCES_ALL = \ + api.c system.h system.c helper.h helper.c \ + gen_pfc.h gen_pfc.c gen_bpf.h gen_bpf.c \ + hash.h hash.c \ + db.h db.c \ + arch.c arch.h \ + arch-x86.h arch-x86.c \ + arch-x86_64.h arch-x86_64.c \ + arch-x32.h arch-x32.c \ + arch-arm.h arch-arm.c \ + arch-aarch64.h arch-aarch64.c \ + arch-mips.h arch-mips.c \ + arch-mips64.h arch-mips64.c \ + arch-mips64n32.h arch-mips64n32.c \ + arch-parisc.h arch-parisc.c \ + arch-parisc64.h arch-parisc64.c \ + arch-ppc.h arch-ppc.c \ + arch-ppc64.h arch-ppc64.c \ + arch-riscv64.h arch-riscv64.c \ + arch-s390.h arch-s390.c \ + arch-s390x.h arch-s390x.c \ + syscalls.h syscalls.c syscalls.perf.c + +EXTRA_DIST = arch-syscall-validate arch-syscall-check \ + arch-gperf-generate syscalls.csv syscalls.perf.template \ + syscalls.perf.c syscalls.perf +TESTS = arch-syscall-check +lib_LTLIBRARIES = libseccomp.la +arch_syscall_dump_SOURCES = arch-syscall-dump.c ${SOURCES_ALL} +libseccomp_la_SOURCES = ${SOURCES_ALL} +libseccomp_la_CPPFLAGS = ${AM_CPPFLAGS} ${CODE_COVERAGE_CPPFLAGS} +libseccomp_la_CFLAGS = ${AM_CFLAGS} ${CODE_COVERAGE_CFLAGS} ${CFLAGS} \ + -fPIC -DPIC -fvisibility=hidden + +libseccomp_la_LDFLAGS = ${AM_LDFLAGS} ${CODE_COVERAGE_LDFLAGS} ${LDFLAGS} \ + -version-number ${VERSION_MAJOR}:${VERSION_MINOR}:${VERSION_MICRO} + +CLEANFILES = syscalls.perf.c syscalls.perf +all: all-recursive + +.SUFFIXES: +.SUFFIXES: .c .lo .o .obj +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign src/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --foreign src/Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +clean-checkPROGRAMS: + @list='$(check_PROGRAMS)'; test -n "$$list" || exit 0; \ + echo " rm -f" $$list; \ + rm -f $$list || exit $$?; \ + test -n "$(EXEEXT)" || exit 0; \ + list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ + echo " rm -f" $$list; \ + rm -f $$list + +install-libLTLIBRARIES: $(lib_LTLIBRARIES) + @$(NORMAL_INSTALL) + @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ + list2=; for p in $$list; do \ + if test -f $$p; then \ + list2="$$list2 $$p"; \ + else :; fi; \ + done; \ + test -z "$$list2" || { \ + echo " $(MKDIR_P) '$(DESTDIR)$(libdir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(libdir)" || exit 1; \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(libdir)'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(libdir)"; \ + } + +uninstall-libLTLIBRARIES: + @$(NORMAL_UNINSTALL) + @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ + for p in $$list; do \ + $(am__strip_dir) \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$f'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$f"; \ + done + +clean-libLTLIBRARIES: + -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES) + @list='$(lib_LTLIBRARIES)'; \ + locs=`for p in $$list; do echo $$p; done | \ + sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ + sort -u`; \ + test -z "$$locs" || { \ + echo rm -f $${locs}; \ + rm -f $${locs}; \ + } + +libseccomp.la: $(libseccomp_la_OBJECTS) $(libseccomp_la_DEPENDENCIES) $(EXTRA_libseccomp_la_DEPENDENCIES) + $(AM_V_CCLD)$(libseccomp_la_LINK) -rpath $(libdir) $(libseccomp_la_OBJECTS) $(libseccomp_la_LIBADD) $(LIBS) + +arch-syscall-dump$(EXEEXT): $(arch_syscall_dump_OBJECTS) $(arch_syscall_dump_DEPENDENCIES) $(EXTRA_arch_syscall_dump_DEPENDENCIES) + @rm -f arch-syscall-dump$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(arch_syscall_dump_OBJECTS) $(arch_syscall_dump_LDADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/api.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/arch-aarch64.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/arch-arm.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/arch-mips.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/arch-mips64.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/arch-mips64n32.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/arch-parisc.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/arch-parisc64.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/arch-ppc.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/arch-ppc64.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/arch-riscv64.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/arch-s390.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/arch-s390x.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/arch-syscall-dump.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/arch-x32.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/arch-x86.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/arch-x86_64.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/arch.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/db.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gen_bpf.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gen_pfc.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hash.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/helper.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libseccomp_la-api.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libseccomp_la-arch-aarch64.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libseccomp_la-arch-arm.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libseccomp_la-arch-mips.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libseccomp_la-arch-mips64.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libseccomp_la-arch-mips64n32.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libseccomp_la-arch-parisc.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libseccomp_la-arch-parisc64.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libseccomp_la-arch-ppc.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libseccomp_la-arch-ppc64.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libseccomp_la-arch-riscv64.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libseccomp_la-arch-s390.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libseccomp_la-arch-s390x.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libseccomp_la-arch-x32.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libseccomp_la-arch-x86.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libseccomp_la-arch-x86_64.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libseccomp_la-arch.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libseccomp_la-db.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libseccomp_la-gen_bpf.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libseccomp_la-gen_pfc.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libseccomp_la-hash.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libseccomp_la-helper.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libseccomp_la-syscalls.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libseccomp_la-syscalls.perf.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libseccomp_la-system.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/syscalls.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/syscalls.perf.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/system.Po@am__quote@ # am--include-marker + +$(am__depfiles_remade): + @$(MKDIR_P) $(@D) + @echo '# dummy' >$@-t && $(am__mv) $@-t $@ + +am--depfiles: $(am__depfiles_remade) + +.c.o: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< + +.c.obj: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +.c.lo: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ +@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< + +libseccomp_la-api.lo: api.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libseccomp_la_CPPFLAGS) $(CPPFLAGS) $(libseccomp_la_CFLAGS) $(CFLAGS) -MT libseccomp_la-api.lo -MD -MP -MF $(DEPDIR)/libseccomp_la-api.Tpo -c -o libseccomp_la-api.lo `test -f 'api.c' || echo '$(srcdir)/'`api.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libseccomp_la-api.Tpo $(DEPDIR)/libseccomp_la-api.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='api.c' object='libseccomp_la-api.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libseccomp_la_CPPFLAGS) $(CPPFLAGS) $(libseccomp_la_CFLAGS) $(CFLAGS) -c -o libseccomp_la-api.lo `test -f 'api.c' || echo '$(srcdir)/'`api.c + +libseccomp_la-system.lo: system.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libseccomp_la_CPPFLAGS) $(CPPFLAGS) $(libseccomp_la_CFLAGS) $(CFLAGS) -MT libseccomp_la-system.lo -MD -MP -MF $(DEPDIR)/libseccomp_la-system.Tpo -c -o libseccomp_la-system.lo `test -f 'system.c' || echo '$(srcdir)/'`system.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libseccomp_la-system.Tpo $(DEPDIR)/libseccomp_la-system.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='system.c' object='libseccomp_la-system.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libseccomp_la_CPPFLAGS) $(CPPFLAGS) $(libseccomp_la_CFLAGS) $(CFLAGS) -c -o libseccomp_la-system.lo `test -f 'system.c' || echo '$(srcdir)/'`system.c + +libseccomp_la-helper.lo: helper.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libseccomp_la_CPPFLAGS) $(CPPFLAGS) $(libseccomp_la_CFLAGS) $(CFLAGS) -MT libseccomp_la-helper.lo -MD -MP -MF $(DEPDIR)/libseccomp_la-helper.Tpo -c -o libseccomp_la-helper.lo `test -f 'helper.c' || echo '$(srcdir)/'`helper.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libseccomp_la-helper.Tpo $(DEPDIR)/libseccomp_la-helper.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='helper.c' object='libseccomp_la-helper.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libseccomp_la_CPPFLAGS) $(CPPFLAGS) $(libseccomp_la_CFLAGS) $(CFLAGS) -c -o libseccomp_la-helper.lo `test -f 'helper.c' || echo '$(srcdir)/'`helper.c + +libseccomp_la-gen_pfc.lo: gen_pfc.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libseccomp_la_CPPFLAGS) $(CPPFLAGS) $(libseccomp_la_CFLAGS) $(CFLAGS) -MT libseccomp_la-gen_pfc.lo -MD -MP -MF $(DEPDIR)/libseccomp_la-gen_pfc.Tpo -c -o libseccomp_la-gen_pfc.lo `test -f 'gen_pfc.c' || echo '$(srcdir)/'`gen_pfc.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libseccomp_la-gen_pfc.Tpo $(DEPDIR)/libseccomp_la-gen_pfc.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='gen_pfc.c' object='libseccomp_la-gen_pfc.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libseccomp_la_CPPFLAGS) $(CPPFLAGS) $(libseccomp_la_CFLAGS) $(CFLAGS) -c -o libseccomp_la-gen_pfc.lo `test -f 'gen_pfc.c' || echo '$(srcdir)/'`gen_pfc.c + +libseccomp_la-gen_bpf.lo: gen_bpf.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libseccomp_la_CPPFLAGS) $(CPPFLAGS) $(libseccomp_la_CFLAGS) $(CFLAGS) -MT libseccomp_la-gen_bpf.lo -MD -MP -MF $(DEPDIR)/libseccomp_la-gen_bpf.Tpo -c -o libseccomp_la-gen_bpf.lo `test -f 'gen_bpf.c' || echo '$(srcdir)/'`gen_bpf.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libseccomp_la-gen_bpf.Tpo $(DEPDIR)/libseccomp_la-gen_bpf.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='gen_bpf.c' object='libseccomp_la-gen_bpf.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libseccomp_la_CPPFLAGS) $(CPPFLAGS) $(libseccomp_la_CFLAGS) $(CFLAGS) -c -o libseccomp_la-gen_bpf.lo `test -f 'gen_bpf.c' || echo '$(srcdir)/'`gen_bpf.c + +libseccomp_la-hash.lo: hash.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libseccomp_la_CPPFLAGS) $(CPPFLAGS) $(libseccomp_la_CFLAGS) $(CFLAGS) -MT libseccomp_la-hash.lo -MD -MP -MF $(DEPDIR)/libseccomp_la-hash.Tpo -c -o libseccomp_la-hash.lo `test -f 'hash.c' || echo '$(srcdir)/'`hash.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libseccomp_la-hash.Tpo $(DEPDIR)/libseccomp_la-hash.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='hash.c' object='libseccomp_la-hash.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libseccomp_la_CPPFLAGS) $(CPPFLAGS) $(libseccomp_la_CFLAGS) $(CFLAGS) -c -o libseccomp_la-hash.lo `test -f 'hash.c' || echo '$(srcdir)/'`hash.c + +libseccomp_la-db.lo: db.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libseccomp_la_CPPFLAGS) $(CPPFLAGS) $(libseccomp_la_CFLAGS) $(CFLAGS) -MT libseccomp_la-db.lo -MD -MP -MF $(DEPDIR)/libseccomp_la-db.Tpo -c -o libseccomp_la-db.lo `test -f 'db.c' || echo '$(srcdir)/'`db.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libseccomp_la-db.Tpo $(DEPDIR)/libseccomp_la-db.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='db.c' object='libseccomp_la-db.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libseccomp_la_CPPFLAGS) $(CPPFLAGS) $(libseccomp_la_CFLAGS) $(CFLAGS) -c -o libseccomp_la-db.lo `test -f 'db.c' || echo '$(srcdir)/'`db.c + +libseccomp_la-arch.lo: arch.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libseccomp_la_CPPFLAGS) $(CPPFLAGS) $(libseccomp_la_CFLAGS) $(CFLAGS) -MT libseccomp_la-arch.lo -MD -MP -MF $(DEPDIR)/libseccomp_la-arch.Tpo -c -o libseccomp_la-arch.lo `test -f 'arch.c' || echo '$(srcdir)/'`arch.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libseccomp_la-arch.Tpo $(DEPDIR)/libseccomp_la-arch.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='arch.c' object='libseccomp_la-arch.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libseccomp_la_CPPFLAGS) $(CPPFLAGS) $(libseccomp_la_CFLAGS) $(CFLAGS) -c -o libseccomp_la-arch.lo `test -f 'arch.c' || echo '$(srcdir)/'`arch.c + +libseccomp_la-arch-x86.lo: arch-x86.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libseccomp_la_CPPFLAGS) $(CPPFLAGS) $(libseccomp_la_CFLAGS) $(CFLAGS) -MT libseccomp_la-arch-x86.lo -MD -MP -MF $(DEPDIR)/libseccomp_la-arch-x86.Tpo -c -o libseccomp_la-arch-x86.lo `test -f 'arch-x86.c' || echo '$(srcdir)/'`arch-x86.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libseccomp_la-arch-x86.Tpo $(DEPDIR)/libseccomp_la-arch-x86.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='arch-x86.c' object='libseccomp_la-arch-x86.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libseccomp_la_CPPFLAGS) $(CPPFLAGS) $(libseccomp_la_CFLAGS) $(CFLAGS) -c -o libseccomp_la-arch-x86.lo `test -f 'arch-x86.c' || echo '$(srcdir)/'`arch-x86.c + +libseccomp_la-arch-x86_64.lo: arch-x86_64.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libseccomp_la_CPPFLAGS) $(CPPFLAGS) $(libseccomp_la_CFLAGS) $(CFLAGS) -MT libseccomp_la-arch-x86_64.lo -MD -MP -MF $(DEPDIR)/libseccomp_la-arch-x86_64.Tpo -c -o libseccomp_la-arch-x86_64.lo `test -f 'arch-x86_64.c' || echo '$(srcdir)/'`arch-x86_64.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libseccomp_la-arch-x86_64.Tpo $(DEPDIR)/libseccomp_la-arch-x86_64.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='arch-x86_64.c' object='libseccomp_la-arch-x86_64.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libseccomp_la_CPPFLAGS) $(CPPFLAGS) $(libseccomp_la_CFLAGS) $(CFLAGS) -c -o libseccomp_la-arch-x86_64.lo `test -f 'arch-x86_64.c' || echo '$(srcdir)/'`arch-x86_64.c + +libseccomp_la-arch-x32.lo: arch-x32.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libseccomp_la_CPPFLAGS) $(CPPFLAGS) $(libseccomp_la_CFLAGS) $(CFLAGS) -MT libseccomp_la-arch-x32.lo -MD -MP -MF $(DEPDIR)/libseccomp_la-arch-x32.Tpo -c -o libseccomp_la-arch-x32.lo `test -f 'arch-x32.c' || echo '$(srcdir)/'`arch-x32.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libseccomp_la-arch-x32.Tpo $(DEPDIR)/libseccomp_la-arch-x32.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='arch-x32.c' object='libseccomp_la-arch-x32.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libseccomp_la_CPPFLAGS) $(CPPFLAGS) $(libseccomp_la_CFLAGS) $(CFLAGS) -c -o libseccomp_la-arch-x32.lo `test -f 'arch-x32.c' || echo '$(srcdir)/'`arch-x32.c + +libseccomp_la-arch-arm.lo: arch-arm.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libseccomp_la_CPPFLAGS) $(CPPFLAGS) $(libseccomp_la_CFLAGS) $(CFLAGS) -MT libseccomp_la-arch-arm.lo -MD -MP -MF $(DEPDIR)/libseccomp_la-arch-arm.Tpo -c -o libseccomp_la-arch-arm.lo `test -f 'arch-arm.c' || echo '$(srcdir)/'`arch-arm.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libseccomp_la-arch-arm.Tpo $(DEPDIR)/libseccomp_la-arch-arm.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='arch-arm.c' object='libseccomp_la-arch-arm.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libseccomp_la_CPPFLAGS) $(CPPFLAGS) $(libseccomp_la_CFLAGS) $(CFLAGS) -c -o libseccomp_la-arch-arm.lo `test -f 'arch-arm.c' || echo '$(srcdir)/'`arch-arm.c + +libseccomp_la-arch-aarch64.lo: arch-aarch64.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libseccomp_la_CPPFLAGS) $(CPPFLAGS) $(libseccomp_la_CFLAGS) $(CFLAGS) -MT libseccomp_la-arch-aarch64.lo -MD -MP -MF $(DEPDIR)/libseccomp_la-arch-aarch64.Tpo -c -o libseccomp_la-arch-aarch64.lo `test -f 'arch-aarch64.c' || echo '$(srcdir)/'`arch-aarch64.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libseccomp_la-arch-aarch64.Tpo $(DEPDIR)/libseccomp_la-arch-aarch64.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='arch-aarch64.c' object='libseccomp_la-arch-aarch64.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libseccomp_la_CPPFLAGS) $(CPPFLAGS) $(libseccomp_la_CFLAGS) $(CFLAGS) -c -o libseccomp_la-arch-aarch64.lo `test -f 'arch-aarch64.c' || echo '$(srcdir)/'`arch-aarch64.c + +libseccomp_la-arch-mips.lo: arch-mips.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libseccomp_la_CPPFLAGS) $(CPPFLAGS) $(libseccomp_la_CFLAGS) $(CFLAGS) -MT libseccomp_la-arch-mips.lo -MD -MP -MF $(DEPDIR)/libseccomp_la-arch-mips.Tpo -c -o libseccomp_la-arch-mips.lo `test -f 'arch-mips.c' || echo '$(srcdir)/'`arch-mips.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libseccomp_la-arch-mips.Tpo $(DEPDIR)/libseccomp_la-arch-mips.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='arch-mips.c' object='libseccomp_la-arch-mips.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libseccomp_la_CPPFLAGS) $(CPPFLAGS) $(libseccomp_la_CFLAGS) $(CFLAGS) -c -o libseccomp_la-arch-mips.lo `test -f 'arch-mips.c' || echo '$(srcdir)/'`arch-mips.c + +libseccomp_la-arch-mips64.lo: arch-mips64.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libseccomp_la_CPPFLAGS) $(CPPFLAGS) $(libseccomp_la_CFLAGS) $(CFLAGS) -MT libseccomp_la-arch-mips64.lo -MD -MP -MF $(DEPDIR)/libseccomp_la-arch-mips64.Tpo -c -o libseccomp_la-arch-mips64.lo `test -f 'arch-mips64.c' || echo '$(srcdir)/'`arch-mips64.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libseccomp_la-arch-mips64.Tpo $(DEPDIR)/libseccomp_la-arch-mips64.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='arch-mips64.c' object='libseccomp_la-arch-mips64.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libseccomp_la_CPPFLAGS) $(CPPFLAGS) $(libseccomp_la_CFLAGS) $(CFLAGS) -c -o libseccomp_la-arch-mips64.lo `test -f 'arch-mips64.c' || echo '$(srcdir)/'`arch-mips64.c + +libseccomp_la-arch-mips64n32.lo: arch-mips64n32.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libseccomp_la_CPPFLAGS) $(CPPFLAGS) $(libseccomp_la_CFLAGS) $(CFLAGS) -MT libseccomp_la-arch-mips64n32.lo -MD -MP -MF $(DEPDIR)/libseccomp_la-arch-mips64n32.Tpo -c -o libseccomp_la-arch-mips64n32.lo `test -f 'arch-mips64n32.c' || echo '$(srcdir)/'`arch-mips64n32.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libseccomp_la-arch-mips64n32.Tpo $(DEPDIR)/libseccomp_la-arch-mips64n32.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='arch-mips64n32.c' object='libseccomp_la-arch-mips64n32.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libseccomp_la_CPPFLAGS) $(CPPFLAGS) $(libseccomp_la_CFLAGS) $(CFLAGS) -c -o libseccomp_la-arch-mips64n32.lo `test -f 'arch-mips64n32.c' || echo '$(srcdir)/'`arch-mips64n32.c + +libseccomp_la-arch-parisc.lo: arch-parisc.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libseccomp_la_CPPFLAGS) $(CPPFLAGS) $(libseccomp_la_CFLAGS) $(CFLAGS) -MT libseccomp_la-arch-parisc.lo -MD -MP -MF $(DEPDIR)/libseccomp_la-arch-parisc.Tpo -c -o libseccomp_la-arch-parisc.lo `test -f 'arch-parisc.c' || echo '$(srcdir)/'`arch-parisc.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libseccomp_la-arch-parisc.Tpo $(DEPDIR)/libseccomp_la-arch-parisc.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='arch-parisc.c' object='libseccomp_la-arch-parisc.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libseccomp_la_CPPFLAGS) $(CPPFLAGS) $(libseccomp_la_CFLAGS) $(CFLAGS) -c -o libseccomp_la-arch-parisc.lo `test -f 'arch-parisc.c' || echo '$(srcdir)/'`arch-parisc.c + +libseccomp_la-arch-parisc64.lo: arch-parisc64.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libseccomp_la_CPPFLAGS) $(CPPFLAGS) $(libseccomp_la_CFLAGS) $(CFLAGS) -MT libseccomp_la-arch-parisc64.lo -MD -MP -MF $(DEPDIR)/libseccomp_la-arch-parisc64.Tpo -c -o libseccomp_la-arch-parisc64.lo `test -f 'arch-parisc64.c' || echo '$(srcdir)/'`arch-parisc64.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libseccomp_la-arch-parisc64.Tpo $(DEPDIR)/libseccomp_la-arch-parisc64.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='arch-parisc64.c' object='libseccomp_la-arch-parisc64.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libseccomp_la_CPPFLAGS) $(CPPFLAGS) $(libseccomp_la_CFLAGS) $(CFLAGS) -c -o libseccomp_la-arch-parisc64.lo `test -f 'arch-parisc64.c' || echo '$(srcdir)/'`arch-parisc64.c + +libseccomp_la-arch-ppc.lo: arch-ppc.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libseccomp_la_CPPFLAGS) $(CPPFLAGS) $(libseccomp_la_CFLAGS) $(CFLAGS) -MT libseccomp_la-arch-ppc.lo -MD -MP -MF $(DEPDIR)/libseccomp_la-arch-ppc.Tpo -c -o libseccomp_la-arch-ppc.lo `test -f 'arch-ppc.c' || echo '$(srcdir)/'`arch-ppc.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libseccomp_la-arch-ppc.Tpo $(DEPDIR)/libseccomp_la-arch-ppc.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='arch-ppc.c' object='libseccomp_la-arch-ppc.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libseccomp_la_CPPFLAGS) $(CPPFLAGS) $(libseccomp_la_CFLAGS) $(CFLAGS) -c -o libseccomp_la-arch-ppc.lo `test -f 'arch-ppc.c' || echo '$(srcdir)/'`arch-ppc.c + +libseccomp_la-arch-ppc64.lo: arch-ppc64.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libseccomp_la_CPPFLAGS) $(CPPFLAGS) $(libseccomp_la_CFLAGS) $(CFLAGS) -MT libseccomp_la-arch-ppc64.lo -MD -MP -MF $(DEPDIR)/libseccomp_la-arch-ppc64.Tpo -c -o libseccomp_la-arch-ppc64.lo `test -f 'arch-ppc64.c' || echo '$(srcdir)/'`arch-ppc64.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libseccomp_la-arch-ppc64.Tpo $(DEPDIR)/libseccomp_la-arch-ppc64.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='arch-ppc64.c' object='libseccomp_la-arch-ppc64.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libseccomp_la_CPPFLAGS) $(CPPFLAGS) $(libseccomp_la_CFLAGS) $(CFLAGS) -c -o libseccomp_la-arch-ppc64.lo `test -f 'arch-ppc64.c' || echo '$(srcdir)/'`arch-ppc64.c + +libseccomp_la-arch-riscv64.lo: arch-riscv64.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libseccomp_la_CPPFLAGS) $(CPPFLAGS) $(libseccomp_la_CFLAGS) $(CFLAGS) -MT libseccomp_la-arch-riscv64.lo -MD -MP -MF $(DEPDIR)/libseccomp_la-arch-riscv64.Tpo -c -o libseccomp_la-arch-riscv64.lo `test -f 'arch-riscv64.c' || echo '$(srcdir)/'`arch-riscv64.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libseccomp_la-arch-riscv64.Tpo $(DEPDIR)/libseccomp_la-arch-riscv64.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='arch-riscv64.c' object='libseccomp_la-arch-riscv64.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libseccomp_la_CPPFLAGS) $(CPPFLAGS) $(libseccomp_la_CFLAGS) $(CFLAGS) -c -o libseccomp_la-arch-riscv64.lo `test -f 'arch-riscv64.c' || echo '$(srcdir)/'`arch-riscv64.c + +libseccomp_la-arch-s390.lo: arch-s390.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libseccomp_la_CPPFLAGS) $(CPPFLAGS) $(libseccomp_la_CFLAGS) $(CFLAGS) -MT libseccomp_la-arch-s390.lo -MD -MP -MF $(DEPDIR)/libseccomp_la-arch-s390.Tpo -c -o libseccomp_la-arch-s390.lo `test -f 'arch-s390.c' || echo '$(srcdir)/'`arch-s390.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libseccomp_la-arch-s390.Tpo $(DEPDIR)/libseccomp_la-arch-s390.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='arch-s390.c' object='libseccomp_la-arch-s390.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libseccomp_la_CPPFLAGS) $(CPPFLAGS) $(libseccomp_la_CFLAGS) $(CFLAGS) -c -o libseccomp_la-arch-s390.lo `test -f 'arch-s390.c' || echo '$(srcdir)/'`arch-s390.c + +libseccomp_la-arch-s390x.lo: arch-s390x.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libseccomp_la_CPPFLAGS) $(CPPFLAGS) $(libseccomp_la_CFLAGS) $(CFLAGS) -MT libseccomp_la-arch-s390x.lo -MD -MP -MF $(DEPDIR)/libseccomp_la-arch-s390x.Tpo -c -o libseccomp_la-arch-s390x.lo `test -f 'arch-s390x.c' || echo '$(srcdir)/'`arch-s390x.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libseccomp_la-arch-s390x.Tpo $(DEPDIR)/libseccomp_la-arch-s390x.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='arch-s390x.c' object='libseccomp_la-arch-s390x.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libseccomp_la_CPPFLAGS) $(CPPFLAGS) $(libseccomp_la_CFLAGS) $(CFLAGS) -c -o libseccomp_la-arch-s390x.lo `test -f 'arch-s390x.c' || echo '$(srcdir)/'`arch-s390x.c + +libseccomp_la-syscalls.lo: syscalls.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libseccomp_la_CPPFLAGS) $(CPPFLAGS) $(libseccomp_la_CFLAGS) $(CFLAGS) -MT libseccomp_la-syscalls.lo -MD -MP -MF $(DEPDIR)/libseccomp_la-syscalls.Tpo -c -o libseccomp_la-syscalls.lo `test -f 'syscalls.c' || echo '$(srcdir)/'`syscalls.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libseccomp_la-syscalls.Tpo $(DEPDIR)/libseccomp_la-syscalls.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='syscalls.c' object='libseccomp_la-syscalls.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libseccomp_la_CPPFLAGS) $(CPPFLAGS) $(libseccomp_la_CFLAGS) $(CFLAGS) -c -o libseccomp_la-syscalls.lo `test -f 'syscalls.c' || echo '$(srcdir)/'`syscalls.c + +libseccomp_la-syscalls.perf.lo: syscalls.perf.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libseccomp_la_CPPFLAGS) $(CPPFLAGS) $(libseccomp_la_CFLAGS) $(CFLAGS) -MT libseccomp_la-syscalls.perf.lo -MD -MP -MF $(DEPDIR)/libseccomp_la-syscalls.perf.Tpo -c -o libseccomp_la-syscalls.perf.lo `test -f 'syscalls.perf.c' || echo '$(srcdir)/'`syscalls.perf.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libseccomp_la-syscalls.perf.Tpo $(DEPDIR)/libseccomp_la-syscalls.perf.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='syscalls.perf.c' object='libseccomp_la-syscalls.perf.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libseccomp_la_CPPFLAGS) $(CPPFLAGS) $(libseccomp_la_CFLAGS) $(CFLAGS) -c -o libseccomp_la-syscalls.perf.lo `test -f 'syscalls.perf.c' || echo '$(srcdir)/'`syscalls.perf.c + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +# This directory's subdirectories are mostly independent; you can cd +# into them and run 'make' without going through this Makefile. +# To change the values of 'make' variables: instead of editing Makefiles, +# (1) if the variable is set in 'config.status', edit 'config.status' +# (which will cause the Makefiles to be regenerated when you run 'make'); +# (2) otherwise, pass the desired values on the 'make' command line. +$(am__recursive_targets): + @fail=; \ + if $(am__make_keepgoing); then \ + failcom='fail=yes'; \ + else \ + failcom='exit 1'; \ + fi; \ + dot_seen=no; \ + target=`echo $@ | sed s/-recursive//`; \ + case "$@" in \ + distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ + *) list='$(SUBDIRS)' ;; \ + esac; \ + for subdir in $$list; do \ + echo "Making $$target in $$subdir"; \ + if test "$$subdir" = "."; then \ + dot_seen=yes; \ + local_target="$$target-am"; \ + else \ + local_target="$$target"; \ + fi; \ + ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ + || eval $$failcom; \ + done; \ + if test "$$dot_seen" = "no"; then \ + $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ + fi; test -z "$$fail" + +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-recursive +TAGS: tags + +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + set x; \ + here=`pwd`; \ + if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ + include_option=--etags-include; \ + empty_fix=.; \ + else \ + include_option=--include; \ + empty_fix=; \ + fi; \ + list='$(SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + test ! -f $$subdir/TAGS || \ + set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ + fi; \ + done; \ + $(am__define_uniq_tagged_files); \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: ctags-recursive + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" +cscopelist: cscopelist-recursive + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +check-TESTS: $(TESTS) + @failed=0; all=0; xfail=0; xpass=0; skip=0; \ + srcdir=$(srcdir); export srcdir; \ + list=' $(TESTS) '; \ + $(am__tty_colors); \ + if test -n "$$list"; then \ + for tst in $$list; do \ + if test -f ./$$tst; then dir=./; \ + elif test -f $$tst; then dir=; \ + else dir="$(srcdir)/"; fi; \ + if $(TESTS_ENVIRONMENT) $${dir}$$tst $(AM_TESTS_FD_REDIRECT); then \ + all=`expr $$all + 1`; \ + case " $(XFAIL_TESTS) " in \ + *[\ \ ]$$tst[\ \ ]*) \ + xpass=`expr $$xpass + 1`; \ + failed=`expr $$failed + 1`; \ + col=$$red; res=XPASS; \ + ;; \ + *) \ + col=$$grn; res=PASS; \ + ;; \ + esac; \ + elif test $$? -ne 77; then \ + all=`expr $$all + 1`; \ + case " $(XFAIL_TESTS) " in \ + *[\ \ ]$$tst[\ \ ]*) \ + xfail=`expr $$xfail + 1`; \ + col=$$lgn; res=XFAIL; \ + ;; \ + *) \ + failed=`expr $$failed + 1`; \ + col=$$red; res=FAIL; \ + ;; \ + esac; \ + else \ + skip=`expr $$skip + 1`; \ + col=$$blu; res=SKIP; \ + fi; \ + echo "$${col}$$res$${std}: $$tst"; \ + done; \ + if test "$$all" -eq 1; then \ + tests="test"; \ + All=""; \ + else \ + tests="tests"; \ + All="All "; \ + fi; \ + if test "$$failed" -eq 0; then \ + if test "$$xfail" -eq 0; then \ + banner="$$All$$all $$tests passed"; \ + else \ + if test "$$xfail" -eq 1; then failures=failure; else failures=failures; fi; \ + banner="$$All$$all $$tests behaved as expected ($$xfail expected $$failures)"; \ + fi; \ + else \ + if test "$$xpass" -eq 0; then \ + banner="$$failed of $$all $$tests failed"; \ + else \ + if test "$$xpass" -eq 1; then passes=pass; else passes=passes; fi; \ + banner="$$failed of $$all $$tests did not behave as expected ($$xpass unexpected $$passes)"; \ + fi; \ + fi; \ + dashes="$$banner"; \ + skipped=""; \ + if test "$$skip" -ne 0; then \ + if test "$$skip" -eq 1; then \ + skipped="($$skip test was not run)"; \ + else \ + skipped="($$skip tests were not run)"; \ + fi; \ + test `echo "$$skipped" | wc -c` -le `echo "$$banner" | wc -c` || \ + dashes="$$skipped"; \ + fi; \ + report=""; \ + if test "$$failed" -ne 0 && test -n "$(PACKAGE_BUGREPORT)"; then \ + report="Please report to $(PACKAGE_BUGREPORT)"; \ + test `echo "$$report" | wc -c` -le `echo "$$banner" | wc -c` || \ + dashes="$$report"; \ + fi; \ + dashes=`echo "$$dashes" | sed s/./=/g`; \ + if test "$$failed" -eq 0; then \ + col="$$grn"; \ + else \ + col="$$red"; \ + fi; \ + echo "$${col}$$dashes$${std}"; \ + echo "$${col}$$banner$${std}"; \ + test -z "$$skipped" || echo "$${col}$$skipped$${std}"; \ + test -z "$$report" || echo "$${col}$$report$${std}"; \ + echo "$${col}$$dashes$${std}"; \ + test "$$failed" -eq 0; \ + else :; fi +distdir: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) distdir-am + +distdir-am: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done + @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + $(am__make_dryrun) \ + || test -d "$(distdir)/$$subdir" \ + || $(MKDIR_P) "$(distdir)/$$subdir" \ + || exit 1; \ + dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ + $(am__relativize); \ + new_distdir=$$reldir; \ + dir1=$$subdir; dir2="$(top_distdir)"; \ + $(am__relativize); \ + new_top_distdir=$$reldir; \ + echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ + echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ + ($(am__cd) $$subdir && \ + $(MAKE) $(AM_MAKEFLAGS) \ + top_distdir="$$new_top_distdir" \ + distdir="$$new_distdir" \ + am__remove_distdir=: \ + am__skip_length_check=: \ + am__skip_mode_fix=: \ + distdir) \ + || exit 1; \ + fi; \ + done +check-am: all-am + $(MAKE) $(AM_MAKEFLAGS) $(check_PROGRAMS) + $(MAKE) $(AM_MAKEFLAGS) check-TESTS +check: check-recursive +all-am: Makefile $(LTLIBRARIES) +install-checkPROGRAMS: install-libLTLIBRARIES + +installdirs: installdirs-recursive +installdirs-am: + for dir in "$(DESTDIR)$(libdir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +install: install-recursive +install-exec: install-exec-recursive +install-data: install-data-recursive +uninstall: uninstall-recursive + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-recursive +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-recursive + +clean-am: clean-checkPROGRAMS clean-generic clean-libLTLIBRARIES \ + clean-libtool mostlyclean-am + +distclean: distclean-recursive + -rm -f ./$(DEPDIR)/api.Po + -rm -f ./$(DEPDIR)/arch-aarch64.Po + -rm -f ./$(DEPDIR)/arch-arm.Po + -rm -f ./$(DEPDIR)/arch-mips.Po + -rm -f ./$(DEPDIR)/arch-mips64.Po + -rm -f ./$(DEPDIR)/arch-mips64n32.Po + -rm -f ./$(DEPDIR)/arch-parisc.Po + -rm -f ./$(DEPDIR)/arch-parisc64.Po + -rm -f ./$(DEPDIR)/arch-ppc.Po + -rm -f ./$(DEPDIR)/arch-ppc64.Po + -rm -f ./$(DEPDIR)/arch-riscv64.Po + -rm -f ./$(DEPDIR)/arch-s390.Po + -rm -f ./$(DEPDIR)/arch-s390x.Po + -rm -f ./$(DEPDIR)/arch-syscall-dump.Po + -rm -f ./$(DEPDIR)/arch-x32.Po + -rm -f ./$(DEPDIR)/arch-x86.Po + -rm -f ./$(DEPDIR)/arch-x86_64.Po + -rm -f ./$(DEPDIR)/arch.Po + -rm -f ./$(DEPDIR)/db.Po + -rm -f ./$(DEPDIR)/gen_bpf.Po + -rm -f ./$(DEPDIR)/gen_pfc.Po + -rm -f ./$(DEPDIR)/hash.Po + -rm -f ./$(DEPDIR)/helper.Po + -rm -f ./$(DEPDIR)/libseccomp_la-api.Plo + -rm -f ./$(DEPDIR)/libseccomp_la-arch-aarch64.Plo + -rm -f ./$(DEPDIR)/libseccomp_la-arch-arm.Plo + -rm -f ./$(DEPDIR)/libseccomp_la-arch-mips.Plo + -rm -f ./$(DEPDIR)/libseccomp_la-arch-mips64.Plo + -rm -f ./$(DEPDIR)/libseccomp_la-arch-mips64n32.Plo + -rm -f ./$(DEPDIR)/libseccomp_la-arch-parisc.Plo + -rm -f ./$(DEPDIR)/libseccomp_la-arch-parisc64.Plo + -rm -f ./$(DEPDIR)/libseccomp_la-arch-ppc.Plo + -rm -f ./$(DEPDIR)/libseccomp_la-arch-ppc64.Plo + -rm -f ./$(DEPDIR)/libseccomp_la-arch-riscv64.Plo + -rm -f ./$(DEPDIR)/libseccomp_la-arch-s390.Plo + -rm -f ./$(DEPDIR)/libseccomp_la-arch-s390x.Plo + -rm -f ./$(DEPDIR)/libseccomp_la-arch-x32.Plo + -rm -f ./$(DEPDIR)/libseccomp_la-arch-x86.Plo + -rm -f ./$(DEPDIR)/libseccomp_la-arch-x86_64.Plo + -rm -f ./$(DEPDIR)/libseccomp_la-arch.Plo + -rm -f ./$(DEPDIR)/libseccomp_la-db.Plo + -rm -f ./$(DEPDIR)/libseccomp_la-gen_bpf.Plo + -rm -f ./$(DEPDIR)/libseccomp_la-gen_pfc.Plo + -rm -f ./$(DEPDIR)/libseccomp_la-hash.Plo + -rm -f ./$(DEPDIR)/libseccomp_la-helper.Plo + -rm -f ./$(DEPDIR)/libseccomp_la-syscalls.Plo + -rm -f ./$(DEPDIR)/libseccomp_la-syscalls.perf.Plo + -rm -f ./$(DEPDIR)/libseccomp_la-system.Plo + -rm -f ./$(DEPDIR)/syscalls.Po + -rm -f ./$(DEPDIR)/syscalls.perf.Po + -rm -f ./$(DEPDIR)/system.Po + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-recursive + +dvi-am: + +html: html-recursive + +html-am: + +info: info-recursive + +info-am: + +install-data-am: + +install-dvi: install-dvi-recursive + +install-dvi-am: + +install-exec-am: install-libLTLIBRARIES + +install-html: install-html-recursive + +install-html-am: + +install-info: install-info-recursive + +install-info-am: + +install-man: + +install-pdf: install-pdf-recursive + +install-pdf-am: + +install-ps: install-ps-recursive + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-recursive + -rm -f ./$(DEPDIR)/api.Po + -rm -f ./$(DEPDIR)/arch-aarch64.Po + -rm -f ./$(DEPDIR)/arch-arm.Po + -rm -f ./$(DEPDIR)/arch-mips.Po + -rm -f ./$(DEPDIR)/arch-mips64.Po + -rm -f ./$(DEPDIR)/arch-mips64n32.Po + -rm -f ./$(DEPDIR)/arch-parisc.Po + -rm -f ./$(DEPDIR)/arch-parisc64.Po + -rm -f ./$(DEPDIR)/arch-ppc.Po + -rm -f ./$(DEPDIR)/arch-ppc64.Po + -rm -f ./$(DEPDIR)/arch-riscv64.Po + -rm -f ./$(DEPDIR)/arch-s390.Po + -rm -f ./$(DEPDIR)/arch-s390x.Po + -rm -f ./$(DEPDIR)/arch-syscall-dump.Po + -rm -f ./$(DEPDIR)/arch-x32.Po + -rm -f ./$(DEPDIR)/arch-x86.Po + -rm -f ./$(DEPDIR)/arch-x86_64.Po + -rm -f ./$(DEPDIR)/arch.Po + -rm -f ./$(DEPDIR)/db.Po + -rm -f ./$(DEPDIR)/gen_bpf.Po + -rm -f ./$(DEPDIR)/gen_pfc.Po + -rm -f ./$(DEPDIR)/hash.Po + -rm -f ./$(DEPDIR)/helper.Po + -rm -f ./$(DEPDIR)/libseccomp_la-api.Plo + -rm -f ./$(DEPDIR)/libseccomp_la-arch-aarch64.Plo + -rm -f ./$(DEPDIR)/libseccomp_la-arch-arm.Plo + -rm -f ./$(DEPDIR)/libseccomp_la-arch-mips.Plo + -rm -f ./$(DEPDIR)/libseccomp_la-arch-mips64.Plo + -rm -f ./$(DEPDIR)/libseccomp_la-arch-mips64n32.Plo + -rm -f ./$(DEPDIR)/libseccomp_la-arch-parisc.Plo + -rm -f ./$(DEPDIR)/libseccomp_la-arch-parisc64.Plo + -rm -f ./$(DEPDIR)/libseccomp_la-arch-ppc.Plo + -rm -f ./$(DEPDIR)/libseccomp_la-arch-ppc64.Plo + -rm -f ./$(DEPDIR)/libseccomp_la-arch-riscv64.Plo + -rm -f ./$(DEPDIR)/libseccomp_la-arch-s390.Plo + -rm -f ./$(DEPDIR)/libseccomp_la-arch-s390x.Plo + -rm -f ./$(DEPDIR)/libseccomp_la-arch-x32.Plo + -rm -f ./$(DEPDIR)/libseccomp_la-arch-x86.Plo + -rm -f ./$(DEPDIR)/libseccomp_la-arch-x86_64.Plo + -rm -f ./$(DEPDIR)/libseccomp_la-arch.Plo + -rm -f ./$(DEPDIR)/libseccomp_la-db.Plo + -rm -f ./$(DEPDIR)/libseccomp_la-gen_bpf.Plo + -rm -f ./$(DEPDIR)/libseccomp_la-gen_pfc.Plo + -rm -f ./$(DEPDIR)/libseccomp_la-hash.Plo + -rm -f ./$(DEPDIR)/libseccomp_la-helper.Plo + -rm -f ./$(DEPDIR)/libseccomp_la-syscalls.Plo + -rm -f ./$(DEPDIR)/libseccomp_la-syscalls.perf.Plo + -rm -f ./$(DEPDIR)/libseccomp_la-system.Plo + -rm -f ./$(DEPDIR)/syscalls.Po + -rm -f ./$(DEPDIR)/syscalls.perf.Po + -rm -f ./$(DEPDIR)/system.Po + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-recursive + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-recursive + +pdf-am: + +ps: ps-recursive + +ps-am: + +uninstall-am: uninstall-libLTLIBRARIES + +.MAKE: $(am__recursive_targets) check-am install-am install-strip + +.PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am \ + am--depfiles check check-TESTS check-am clean \ + clean-checkPROGRAMS clean-generic clean-libLTLIBRARIES \ + clean-libtool cscopelist-am ctags ctags-am distclean \ + distclean-compile distclean-generic distclean-libtool \ + distclean-tags distdir dvi dvi-am html html-am info info-am \ + install install-am install-data install-data-am install-dvi \ + install-dvi-am install-exec install-exec-am install-html \ + install-html-am install-info install-info-am \ + install-libLTLIBRARIES install-man install-pdf install-pdf-am \ + install-ps install-ps-am install-strip installcheck \ + installcheck-am installdirs installdirs-am maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-compile \ + mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ + tags tags-am uninstall uninstall-am uninstall-libLTLIBRARIES + +.PRECIOUS: Makefile + + +syscalls.perf: syscalls.csv syscalls.perf.template + ${AM_V_GEN} ${srcdir}/arch-gperf-generate \ + ${srcdir}/syscalls.csv ${srcdir}/syscalls.perf.template + +syscalls.perf.c: syscalls.perf + ${GPERF} -m 100 --null-strings --pic -tCEG -T -S1 $< > $@ + +check-build: + ${MAKE} ${AM_MAKEFLAGS} ${check_PROGRAMS} + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/src/api.c b/src/api.c new file mode 100644 index 0000000..5cec088 --- /dev/null +++ b/src/api.c @@ -0,0 +1,733 @@ +/** + * Seccomp Library API + * + * Copyright (c) 2012,2013 Red Hat <pmoore@redhat.com> + * Author: Paul Moore <paul@paul-moore.com> + */ + +/* + * 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 <endian.h> +#include <errno.h> +#include <inttypes.h> +#include <unistd.h> +#include <stdarg.h> +#include <stdlib.h> +#include <string.h> +#include <stdbool.h> +#include <sys/ioctl.h> + +#include <seccomp.h> + +#include "arch.h" +#include "db.h" +#include "gen_pfc.h" +#include "gen_bpf.h" +#include "helper.h" +#include "system.h" + +#define API __attribute__((visibility("default"))) + +const struct scmp_version library_version = { + .major = SCMP_VER_MAJOR, + .minor = SCMP_VER_MINOR, + .micro = SCMP_VER_MICRO, +}; + +unsigned int seccomp_api_level = 0; + +/** + * Filter the error codes we send back to callers + * @param err the error code + * + * We consider error codes part of our API so we want to make sure we don't + * accidentally send an undocumented error code to our callers. This function + * helps with that. + * + */ +static int _rc_filter(int err) +{ + /* pass through success values */ + if (err >= 0) + return err; + + /* filter the error codes */ + switch (err) { + case -EACCES: + /* NOTE: operation is not permitted by libseccomp */ + case -ECANCELED: + /* NOTE: kernel level error that is beyond the control of + * libseccomp */ + case -EDOM: + /* NOTE: failure due to arch/ABI */ + case -EEXIST: + /* NOTE: operation failed due to existing rule or filter */ + case -EINVAL: + /* NOTE: invalid input to the libseccomp API */ + case -ENOENT: + /* NOTE: no matching entry found */ + case -ENOMEM: + /* NOTE: unable to allocate enough memory to perform the + * requested operation */ + case -EOPNOTSUPP: + /* NOTE: operation is not supported */ + case -ESRCH: + /* NOTE: operation failed due to multi-threading */ + return err; + default: + /* NOTE: this is the default "internal libseccomp error" + * error code, it is our catch-all */ + return -EFAULT; + } +} + +/** + * Filter the system error codes we send back to callers + * @param col the filter collection + * @param err the error code + * + * This is similar to _rc_filter(), but it first checks the filter attribute + * to determine if we should be filtering the return codes. + * + */ +static int _rc_filter_sys(struct db_filter_col *col, int err) +{ + /* pass through success values */ + if (err >= 0) + return err; + + /* pass the return code if the SCMP_FLTATR_API_SYSRAWRC is true */ + if (db_col_attr_read(col, SCMP_FLTATR_API_SYSRAWRC)) + return err; + return -ECANCELED; +} + +/** + * Validate a filter context + * @param ctx the filter context + * + * Attempt to validate the provided filter context. Returns zero if the + * context is valid, negative values on failure. + * + */ +static int _ctx_valid(const scmp_filter_ctx *ctx) +{ + return db_col_valid((struct db_filter_col *)ctx); +} + +/** + * Validate a syscall number + * @param syscall the syscall number + * + * Attempt to perform basic syscall number validation. Returns zero of the + * syscall appears valid, negative values on failure. + * + */ +static int _syscall_valid(const struct db_filter_col *col, int syscall) +{ + /* syscall -1 is used by tracers to skip the syscall */ + if (col->attr.api_tskip && syscall == -1) + return 0; + if (syscall <= -1 && syscall >= -99) + return -EINVAL; + return 0; +} + +/** + * Update the API level + * + * This function performs a series of tests to determine what functionality is + * supported given the current running environment (kernel, etc.). It is + * important to note that this function only does meaningful checks the first + * time it is run, the resulting API level is cached after this first run and + * used for all subsequent calls. The API level value is returned. + * + */ +static unsigned int _seccomp_api_update(void) +{ + unsigned int level = 1; + + /* if seccomp_api_level > 0 then it's already been set, we're done */ + if (seccomp_api_level >= 1) + return seccomp_api_level; + + /* NOTE: level 1 is the base level, start checking at 2 */ + + if (sys_chk_seccomp_syscall() && + sys_chk_seccomp_flag(SECCOMP_FILTER_FLAG_TSYNC) == 1) + level = 2; + + if (level == 2 && + sys_chk_seccomp_flag(SECCOMP_FILTER_FLAG_LOG) == 1 && + sys_chk_seccomp_action(SCMP_ACT_LOG) == 1 && + sys_chk_seccomp_action(SCMP_ACT_KILL_PROCESS) == 1) + level = 3; + + if (level == 3 && + sys_chk_seccomp_flag(SECCOMP_FILTER_FLAG_SPEC_ALLOW) == 1) + level = 4; + + if (level == 4 && + sys_chk_seccomp_flag(SECCOMP_FILTER_FLAG_NEW_LISTENER) == 1 && + sys_chk_seccomp_action(SCMP_ACT_NOTIFY) == 1) + level = 5; + + if (level == 5 && + sys_chk_seccomp_flag(SECCOMP_FILTER_FLAG_TSYNC_ESRCH) == 1) + level = 6; + + /* update the stored api level and return */ + seccomp_api_level = level; + return seccomp_api_level; +} + +/* NOTE - function header comment in include/seccomp.h */ +API const struct scmp_version *seccomp_version(void) +{ + return &library_version; +} + +/* NOTE - function header comment in include/seccomp.h */ +API unsigned int seccomp_api_get(void) +{ + /* update the api level, if needed */ + return _seccomp_api_update(); +} + +/* NOTE - function header comment in include/seccomp.h */ +API int seccomp_api_set(unsigned int level) +{ + switch (level) { + case 1: + sys_set_seccomp_syscall(false); + sys_set_seccomp_flag(SECCOMP_FILTER_FLAG_TSYNC, false); + sys_set_seccomp_flag(SECCOMP_FILTER_FLAG_LOG, false); + sys_set_seccomp_action(SCMP_ACT_LOG, false); + sys_set_seccomp_action(SCMP_ACT_KILL_PROCESS, false); + sys_set_seccomp_flag(SECCOMP_FILTER_FLAG_SPEC_ALLOW, false); + sys_set_seccomp_flag(SECCOMP_FILTER_FLAG_NEW_LISTENER, false); + sys_set_seccomp_action(SCMP_ACT_NOTIFY, false); + sys_set_seccomp_flag(SECCOMP_FILTER_FLAG_TSYNC_ESRCH, false); + break; + case 2: + sys_set_seccomp_syscall(true); + sys_set_seccomp_flag(SECCOMP_FILTER_FLAG_TSYNC, true); + sys_set_seccomp_flag(SECCOMP_FILTER_FLAG_LOG, false); + sys_set_seccomp_action(SCMP_ACT_LOG, false); + sys_set_seccomp_action(SCMP_ACT_KILL_PROCESS, false); + sys_set_seccomp_flag(SECCOMP_FILTER_FLAG_SPEC_ALLOW, false); + sys_set_seccomp_flag(SECCOMP_FILTER_FLAG_NEW_LISTENER, false); + sys_set_seccomp_action(SCMP_ACT_NOTIFY, false); + sys_set_seccomp_flag(SECCOMP_FILTER_FLAG_TSYNC_ESRCH, false); + break; + case 3: + sys_set_seccomp_syscall(true); + sys_set_seccomp_flag(SECCOMP_FILTER_FLAG_TSYNC, true); + sys_set_seccomp_flag(SECCOMP_FILTER_FLAG_LOG, true); + sys_set_seccomp_action(SCMP_ACT_LOG, true); + sys_set_seccomp_action(SCMP_ACT_KILL_PROCESS, true); + sys_set_seccomp_flag(SECCOMP_FILTER_FLAG_SPEC_ALLOW, false); + sys_set_seccomp_flag(SECCOMP_FILTER_FLAG_NEW_LISTENER, false); + sys_set_seccomp_action(SCMP_ACT_NOTIFY, false); + sys_set_seccomp_flag(SECCOMP_FILTER_FLAG_TSYNC_ESRCH, false); + break; + case 4: + sys_set_seccomp_syscall(true); + sys_set_seccomp_flag(SECCOMP_FILTER_FLAG_TSYNC, true); + sys_set_seccomp_flag(SECCOMP_FILTER_FLAG_LOG, true); + sys_set_seccomp_action(SCMP_ACT_LOG, true); + sys_set_seccomp_action(SCMP_ACT_KILL_PROCESS, true); + sys_set_seccomp_flag(SECCOMP_FILTER_FLAG_SPEC_ALLOW, true); + sys_set_seccomp_flag(SECCOMP_FILTER_FLAG_NEW_LISTENER, false); + sys_set_seccomp_action(SCMP_ACT_NOTIFY, false); + sys_set_seccomp_flag(SECCOMP_FILTER_FLAG_TSYNC_ESRCH, false); + break; + case 5: + sys_set_seccomp_syscall(true); + sys_set_seccomp_flag(SECCOMP_FILTER_FLAG_TSYNC, true); + sys_set_seccomp_flag(SECCOMP_FILTER_FLAG_LOG, true); + sys_set_seccomp_action(SCMP_ACT_LOG, true); + sys_set_seccomp_action(SCMP_ACT_KILL_PROCESS, true); + sys_set_seccomp_flag(SECCOMP_FILTER_FLAG_SPEC_ALLOW, true); + sys_set_seccomp_flag(SECCOMP_FILTER_FLAG_NEW_LISTENER, true); + sys_set_seccomp_action(SCMP_ACT_NOTIFY, true); + sys_set_seccomp_flag(SECCOMP_FILTER_FLAG_TSYNC_ESRCH, false); + break; + case 6: + sys_set_seccomp_syscall(true); + sys_set_seccomp_flag(SECCOMP_FILTER_FLAG_TSYNC, true); + sys_set_seccomp_flag(SECCOMP_FILTER_FLAG_LOG, true); + sys_set_seccomp_action(SCMP_ACT_LOG, true); + sys_set_seccomp_action(SCMP_ACT_KILL_PROCESS, true); + sys_set_seccomp_flag(SECCOMP_FILTER_FLAG_SPEC_ALLOW, true); + sys_set_seccomp_flag(SECCOMP_FILTER_FLAG_NEW_LISTENER, true); + sys_set_seccomp_action(SCMP_ACT_NOTIFY, true); + sys_set_seccomp_flag(SECCOMP_FILTER_FLAG_TSYNC_ESRCH, true); + break; + default: + return _rc_filter(-EINVAL); + } + + seccomp_api_level = level; + return _rc_filter(0); +} + +/* NOTE - function header comment in include/seccomp.h */ +API scmp_filter_ctx seccomp_init(uint32_t def_action) +{ + /* force a runtime api level detection */ + _seccomp_api_update(); + + if (db_col_action_valid(NULL, def_action) < 0) + return NULL; + + return db_col_init(def_action); +} + +/* NOTE - function header comment in include/seccomp.h */ +API int seccomp_reset(scmp_filter_ctx ctx, uint32_t def_action) +{ + struct db_filter_col *col = (struct db_filter_col *)ctx; + + /* a NULL filter context indicates we are resetting the global state */ + if (ctx == NULL) { + /* reset the global state and redetermine the api level */ + sys_reset_state(); + _seccomp_api_update(); + return _rc_filter(0); + } + /* ensure the default action is valid */ + if (db_col_action_valid(NULL, def_action) < 0) + return _rc_filter(-EINVAL); + + /* reset the filter */ + return _rc_filter(db_col_reset(col, def_action)); +} + +/* NOTE - function header comment in include/seccomp.h */ +API void seccomp_release(scmp_filter_ctx ctx) +{ + db_col_release((struct db_filter_col *)ctx); +} + +/* NOTE - function header comment in include/seccomp.h */ +API int seccomp_merge(scmp_filter_ctx ctx_dst, scmp_filter_ctx ctx_src) +{ + struct db_filter_col *col_dst = (struct db_filter_col *)ctx_dst; + struct db_filter_col *col_src = (struct db_filter_col *)ctx_src; + + if (db_col_valid(col_dst) || db_col_valid(col_src)) + return _rc_filter(-EINVAL); + + /* NOTE: only the default action, NNP, and TSYNC settings must match */ + if ((col_dst->attr.act_default != col_src->attr.act_default) || + (col_dst->attr.nnp_enable != col_src->attr.nnp_enable) || + (col_dst->attr.tsync_enable != col_src->attr.tsync_enable)) + return _rc_filter(-EINVAL); + + return _rc_filter(db_col_merge(col_dst, col_src)); +} + +/* NOTE - function header comment in include/seccomp.h */ +API uint32_t seccomp_arch_resolve_name(const char *arch_name) +{ + const struct arch_def *arch; + + if (arch_name == NULL) + return 0; + + arch = arch_def_lookup_name(arch_name); + if (arch == NULL) + return 0; + + return arch->token; +} + +/* NOTE - function header comment in include/seccomp.h */ +API uint32_t seccomp_arch_native(void) +{ + return arch_def_native->token; +} + +/* NOTE - function header comment in include/seccomp.h */ +API int seccomp_arch_exist(const scmp_filter_ctx ctx, uint32_t arch_token) +{ + struct db_filter_col *col = (struct db_filter_col *)ctx; + + if (arch_token == 0) + arch_token = arch_def_native->token; + + if (arch_valid(arch_token)) + return _rc_filter(-EINVAL); + + return _rc_filter((db_col_arch_exist(col, arch_token) ? 0 : -EEXIST)); +} + +/* NOTE - function header comment in include/seccomp.h */ +API int seccomp_arch_add(scmp_filter_ctx ctx, uint32_t arch_token) +{ + const struct arch_def *arch; + struct db_filter_col *col = (struct db_filter_col *)ctx; + + if (arch_token == 0) + arch_token = arch_def_native->token; + + arch = arch_def_lookup(arch_token); + if (arch == NULL) + return _rc_filter(-EINVAL); + if (db_col_arch_exist(col, arch_token)) + return _rc_filter(-EEXIST); + + return _rc_filter(db_col_db_new(col, arch)); +} + +/* NOTE - function header comment in include/seccomp.h */ +API int seccomp_arch_remove(scmp_filter_ctx ctx, uint32_t arch_token) +{ + struct db_filter_col *col = (struct db_filter_col *)ctx; + + if (arch_token == 0) + arch_token = arch_def_native->token; + + if (arch_valid(arch_token)) + return _rc_filter(-EINVAL); + if (db_col_arch_exist(col, arch_token) != -EEXIST) + return _rc_filter(-EEXIST); + + return _rc_filter(db_col_db_remove(col, arch_token)); +} + +/* NOTE - function header comment in include/seccomp.h */ +API int seccomp_load(const scmp_filter_ctx ctx) +{ + struct db_filter_col *col; + bool rawrc; + + if (_ctx_valid(ctx)) + return _rc_filter(-EINVAL); + col = (struct db_filter_col *)ctx; + + rawrc = db_col_attr_read(col, SCMP_FLTATR_API_SYSRAWRC); + return _rc_filter(sys_filter_load(col, rawrc)); +} + +/* NOTE - function header comment in include/seccomp.h */ +API int seccomp_attr_get(const scmp_filter_ctx ctx, + enum scmp_filter_attr attr, uint32_t *value) +{ + if (_ctx_valid(ctx)) + return _rc_filter(-EINVAL); + + return _rc_filter(db_col_attr_get((const struct db_filter_col *)ctx, + attr, value)); +} + +/* NOTE - function header comment in include/seccomp.h */ +API int seccomp_attr_set(scmp_filter_ctx ctx, + enum scmp_filter_attr attr, uint32_t value) +{ + if (_ctx_valid(ctx)) + return _rc_filter(-EINVAL); + + return _rc_filter(db_col_attr_set((struct db_filter_col *)ctx, + attr, value)); +} + +/* NOTE - function header comment in include/seccomp.h */ +API char *seccomp_syscall_resolve_num_arch(uint32_t arch_token, int num) +{ + const struct arch_def *arch; + const char *name; + + if (arch_token == 0) + arch_token = arch_def_native->token; + if (arch_valid(arch_token)) + return NULL; + arch = arch_def_lookup(arch_token); + if (arch == NULL) + return NULL; + + name = arch_syscall_resolve_num(arch, num); + if (name == NULL) + return NULL; + + return strdup(name); +} + +/* NOTE - function header comment in include/seccomp.h */ +API int seccomp_syscall_resolve_name_arch(uint32_t arch_token, const char *name) +{ + const struct arch_def *arch; + + if (name == NULL) + return __NR_SCMP_ERROR; + + if (arch_token == 0) + arch_token = arch_def_native->token; + if (arch_valid(arch_token)) + return __NR_SCMP_ERROR; + arch = arch_def_lookup(arch_token); + if (arch == NULL) + return __NR_SCMP_ERROR; + + return arch_syscall_resolve_name(arch, name); +} + +/* NOTE - function header comment in include/seccomp.h */ +API int seccomp_syscall_resolve_name_rewrite(uint32_t arch_token, + const char *name) +{ + int rc; + int syscall; + const struct arch_def *arch; + + if (name == NULL) + return __NR_SCMP_ERROR; + + if (arch_token == 0) + arch_token = arch_def_native->token; + if (arch_valid(arch_token)) + return __NR_SCMP_ERROR; + arch = arch_def_lookup(arch_token); + if (arch == NULL) + return __NR_SCMP_ERROR; + + syscall = arch_syscall_resolve_name(arch, name); + if (syscall == __NR_SCMP_ERROR) + return __NR_SCMP_ERROR; + rc = arch_syscall_rewrite(arch, &syscall); + if (rc == -EDOM) + /* if we can't rewrite the syscall, just pass it through */ + return syscall; + else if (rc < 0) + return __NR_SCMP_ERROR; + + return syscall; +} + +/* NOTE - function header comment in include/seccomp.h */ +API int seccomp_syscall_resolve_name(const char *name) +{ + return seccomp_syscall_resolve_name_arch(SCMP_ARCH_NATIVE, name); +} + +/* NOTE - function header comment in include/seccomp.h */ +API int seccomp_syscall_priority(scmp_filter_ctx ctx, + int syscall, uint8_t priority) +{ + struct db_filter_col *col = (struct db_filter_col *)ctx; + + if (db_col_valid(col) || _syscall_valid(col, syscall)) + return _rc_filter(-EINVAL); + + return _rc_filter(db_col_syscall_priority(col, syscall, priority)); +} + +/* NOTE - function header comment in include/seccomp.h */ +API int seccomp_rule_add_array(scmp_filter_ctx ctx, + uint32_t action, int syscall, + unsigned int arg_cnt, + const struct scmp_arg_cmp *arg_array) +{ + int rc; + struct db_filter_col *col = (struct db_filter_col *)ctx; + + if (arg_cnt > ARG_COUNT_MAX) + return _rc_filter(-EINVAL); + if (arg_cnt > 0 && arg_array == NULL) + return _rc_filter(-EINVAL); + + if (db_col_valid(col) || _syscall_valid(col, syscall)) + return _rc_filter(-EINVAL); + + rc = db_col_action_valid(col, action); + if (rc < 0) + return _rc_filter(rc); + if (action == col->attr.act_default) + return _rc_filter(-EACCES); + + return _rc_filter(db_col_rule_add(col, 0, action, + syscall, arg_cnt, arg_array)); +} + +/* NOTE - function header comment in include/seccomp.h */ +API int seccomp_rule_add(scmp_filter_ctx ctx, + uint32_t action, int syscall, + unsigned int arg_cnt, ...) +{ + int rc; + int iter; + struct scmp_arg_cmp arg_array[ARG_COUNT_MAX]; + va_list arg_list; + + /* arg_cnt is unsigned, so no need to check the lower bound */ + if (arg_cnt > ARG_COUNT_MAX) + return _rc_filter(-EINVAL); + + va_start(arg_list, arg_cnt); + for (iter = 0; iter < arg_cnt; ++iter) + arg_array[iter] = va_arg(arg_list, struct scmp_arg_cmp); + rc = seccomp_rule_add_array(ctx, action, syscall, arg_cnt, arg_array); + va_end(arg_list); + + return _rc_filter(rc); +} + +/* NOTE - function header comment in include/seccomp.h */ +API int seccomp_rule_add_exact_array(scmp_filter_ctx ctx, + uint32_t action, int syscall, + unsigned int arg_cnt, + const struct scmp_arg_cmp *arg_array) +{ + int rc; + struct db_filter_col *col = (struct db_filter_col *)ctx; + + if (arg_cnt > ARG_COUNT_MAX) + return _rc_filter(-EINVAL); + if (arg_cnt > 0 && arg_array == NULL) + return _rc_filter(-EINVAL); + + if (db_col_valid(col) || _syscall_valid(col, syscall)) + return _rc_filter(-EINVAL); + + rc = db_col_action_valid(col, action); + if (rc < 0) + return _rc_filter(rc); + if (action == col->attr.act_default) + return _rc_filter(-EACCES); + + if (col->filter_cnt > 1) + return _rc_filter(-EOPNOTSUPP); + + return _rc_filter(db_col_rule_add(col, 1, action, + syscall, arg_cnt, arg_array)); +} + +/* NOTE - function header comment in include/seccomp.h */ +API int seccomp_rule_add_exact(scmp_filter_ctx ctx, + uint32_t action, int syscall, + unsigned int arg_cnt, ...) +{ + int rc; + int iter; + struct scmp_arg_cmp arg_array[ARG_COUNT_MAX]; + va_list arg_list; + + /* arg_cnt is unsigned, so no need to check the lower bound */ + if (arg_cnt > ARG_COUNT_MAX) + return _rc_filter(-EINVAL); + + va_start(arg_list, arg_cnt); + for (iter = 0; iter < arg_cnt; ++iter) + arg_array[iter] = va_arg(arg_list, struct scmp_arg_cmp); + rc = seccomp_rule_add_exact_array(ctx, + action, syscall, arg_cnt, arg_array); + va_end(arg_list); + + return _rc_filter(rc); +} + +/* NOTE - function header comment in include/seccomp.h */ +API int seccomp_notify_alloc(struct seccomp_notif **req, + struct seccomp_notif_resp **resp) +{ + /* force a runtime api level detection */ + _seccomp_api_update(); + + return _rc_filter(sys_notify_alloc(req, resp)); +} + +/* NOTE - function header comment in include/seccomp.h */ +API void seccomp_notify_free(struct seccomp_notif *req, + struct seccomp_notif_resp *resp) +{ + if (req) + free(req); + if (resp) + free(resp); +} + +/* NOTE - function header comment in include/seccomp.h */ +API int seccomp_notify_receive(int fd, struct seccomp_notif *req) +{ + return _rc_filter(sys_notify_receive(fd, req)); +} + +/* NOTE - function header comment in include/seccomp.h */ +API int seccomp_notify_respond(int fd, struct seccomp_notif_resp *resp) +{ + return _rc_filter(sys_notify_respond(fd, resp)); +} + +/* NOTE - function header comment in include/seccomp.h */ +API int seccomp_notify_id_valid(int fd, uint64_t id) +{ + /* force a runtime api level detection */ + _seccomp_api_update(); + + return _rc_filter(sys_notify_id_valid(fd, id)); +} + +/* NOTE - function header comment in include/seccomp.h */ +API int seccomp_notify_fd(const scmp_filter_ctx ctx) +{ + /* NOTE: for historical reasons, and possibly future use, we require a + * valid filter context even though we don't actual use it here; the + * api update is also not strictly necessary, but keep it for now */ + + /* force a runtime api level detection */ + _seccomp_api_update(); + + if (_ctx_valid(ctx)) + return _rc_filter(-EINVAL); + + return _rc_filter(sys_notify_fd()); +} + +/* NOTE - function header comment in include/seccomp.h */ +API int seccomp_export_pfc(const scmp_filter_ctx ctx, int fd) +{ + int rc; + struct db_filter_col *col; + + if (_ctx_valid(ctx)) + return _rc_filter(-EINVAL); + col = (struct db_filter_col *)ctx; + + rc = gen_pfc_generate(col, fd); + return _rc_filter_sys(col, rc); +} + +/* NOTE - function header comment in include/seccomp.h */ +API int seccomp_export_bpf(const scmp_filter_ctx ctx, int fd) +{ + int rc; + struct db_filter_col *col; + struct bpf_program *program; + + if (_ctx_valid(ctx)) + return _rc_filter(-EINVAL); + col = (struct db_filter_col *)ctx; + + rc = gen_bpf_generate(col, &program); + if (rc < 0) + return _rc_filter(rc); + rc = write(fd, program->blks, BPF_PGM_SIZE(program)); + gen_bpf_release(program); + if (rc < 0) + return _rc_filter_sys(col, -errno); + + return 0; +} diff --git a/src/arch-aarch64.c b/src/arch-aarch64.c new file mode 100644 index 0000000..9b12b43 --- /dev/null +++ b/src/arch-aarch64.c @@ -0,0 +1,41 @@ +/** + * Enhanced Seccomp AArch64 Syscall Table + * + * Copyright (c) 2014 Red Hat <mjuszkiewicz@redhat.com> + * Author: Marcin Juszkiewicz <mjuszkiewicz@redhat.com> + */ + +/* + * 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-aarch64.h" +#include "syscalls.h" + +ARCH_DEF(aarch64) + +const struct arch_def arch_def_aarch64 = { + .token = SCMP_ARCH_AARCH64, + .token_bpf = AUDIT_ARCH_AARCH64, + .size = ARCH_SIZE_64, + .endian = ARCH_ENDIAN_LITTLE, + .syscall_resolve_name_raw = aarch64_syscall_resolve_name, + .syscall_resolve_num_raw = aarch64_syscall_resolve_num, + .syscall_rewrite = NULL, + .rule_add = NULL, +}; diff --git a/src/arch-aarch64.h b/src/arch-aarch64.h new file mode 100644 index 0000000..ed1877a --- /dev/null +++ b/src/arch-aarch64.h @@ -0,0 +1,29 @@ +/** + * Enhanced Seccomp AArch64 Syscall Table + * + * Copyright (c) 2014 Red Hat <mjuszkiewicz@redhat.com> + * Author: Marcin Juszkiewicz <mjuszkiewicz@redhat.com> + */ + +/* + * 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>. + */ + +#ifndef _ARCH_AARCH64_H +#define _ARCH_AARCH64_H + +#include "arch.h" + +ARCH_DECL(aarch64) + +#endif diff --git a/src/arch-arm.c b/src/arch-arm.c new file mode 100644 index 0000000..c389815 --- /dev/null +++ b/src/arch-arm.c @@ -0,0 +1,95 @@ +/** + * Enhanced Seccomp ARM Specific Code + * + * Copyright (c) 2013 Red Hat <pmoore@redhat.com> + * Author: Paul Moore <paul@paul-moore.com> + */ + +/* + * 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-arm.h" +#include "syscalls.h" + +#define __SCMP_NR_OABI_SYSCALL_BASE 0x900000 +#define __SCMP_ARM_NR_BASE 0x0f0000 + +/* NOTE: we currently only support the ARM EABI, more info at the URL below: + * -> http://wiki.embeddedarm.com/wiki/EABI_vs_OABI */ +#if 1 +#define __SCMP_NR_BASE 0 +#else +#define __SCMP_NR_BASE __SCMP_NR_OABI_SYSCALL_BASE +#endif + +/** + * Resolve a syscall name to a number + * @param arch the architecture definition + * @param name the syscall name + * + * Resolve the given syscall name to the syscall number using the syscall table. + * Returns the syscall number on success, including negative pseudo syscall + * numbers; returns __NR_SCMP_ERROR on failure. + * + */ +int arm_syscall_resolve_name_munge(const struct arch_def *arch, + const char *name) +{ + int sys; + + /* NOTE: we don't want to modify the pseudo-syscall numbers */ + sys = arch->syscall_resolve_name_raw(name); + if (sys == __NR_SCMP_ERROR || sys < 0) + return sys; + + return (sys | __SCMP_NR_BASE); +} + +/** + * Resolve a syscall number to a name + * @param arch the architecture definition + * @param num the syscall number + * + * Resolve the given syscall number to the syscall name using the syscall table. + * Returns a pointer to the syscall name string on success, including pseudo + * syscall names; returns NULL on failure. + * + */ +const char *arm_syscall_resolve_num_munge(const struct arch_def *arch, int num) +{ + /* NOTE: we don't want to modify the pseudo-syscall numbers */ + if (num >= 0) + num &= ~__SCMP_NR_BASE; + return arch->syscall_resolve_num_raw(num); +} + +ARCH_DEF(arm) + +const struct arch_def arch_def_arm = { + .token = SCMP_ARCH_ARM, + .token_bpf = AUDIT_ARCH_ARM, + .size = ARCH_SIZE_32, + .endian = ARCH_ENDIAN_LITTLE, + .syscall_resolve_name = arm_syscall_resolve_name_munge, + .syscall_resolve_name_raw = arm_syscall_resolve_name, + .syscall_resolve_num = arm_syscall_resolve_num_munge, + .syscall_resolve_num_raw = arm_syscall_resolve_num, + .syscall_rewrite = NULL, + .rule_add = NULL, +}; diff --git a/src/arch-arm.h b/src/arch-arm.h new file mode 100644 index 0000000..34e6c91 --- /dev/null +++ b/src/arch-arm.h @@ -0,0 +1,29 @@ +/** + * Enhanced Seccomp ARM Specific Code + * + * Copyright (c) 2013 Red Hat <pmoore@redhat.com> + * Author: Paul Moore <paul@paul-moore.com> + */ + +/* + * 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>. + */ + +#ifndef _ARCH_ARM_H +#define _ARCH_ARM_H + +#include "arch.h" + +ARCH_DECL(arm) + +#endif diff --git a/src/arch-gperf-generate b/src/arch-gperf-generate new file mode 100755 index 0000000..9e6c000 --- /dev/null +++ b/src/arch-gperf-generate @@ -0,0 +1,40 @@ +#!/bin/bash + +# NOTE: changes to the arch_syscall_table struct in syscalls.h will affect +# this script/gperf - BEWARE! + +### +# helper functions + +function exit_usage() { + echo "usage: $0 <syscall_csv_file> <gperf_template>" + exit 1 +} + +### +# main + +# sanity check +[[ ! -r "$1" || ! -r "$2" ]] && exit_usage +sys_csv=$1 +gperf_tmpl=$2 + +sys_csv_tmp=$(mktemp -t generate_syscalls_XXXXXX) + +# filter and prepare the syscall csv file +cat $sys_csv | grep -v '^#' | nl -ba -s, -v0 | \ + sed -e 's/^[[:space:]]\+\([0-9]\+\),\([^,]\+\),\(.*\)/\2,\1,\3/' \ + -e ':repeat; {s|\([^,]\+\)\(.*\)[^_]PNR|\1\2,__PNR_\1|g;}; t repeat' \ + > $sys_csv_tmp +[[ $? -ne 0 ]] && exit 1 + +# create the gperf file +sed -e "/@@SYSCALLS_TABLE@@/r $sys_csv_tmp" \ + -e '/@@SYSCALLS_TABLE@@/d' \ + $gperf_tmpl > syscalls.perf +[[ $? -ne 0 ]] && exit 1 + +# cleanup +rm -f $sys_csv_tmp + +exit 0 diff --git a/src/arch-mips.c b/src/arch-mips.c new file mode 100644 index 0000000..5a12a11 --- /dev/null +++ b/src/arch-mips.c @@ -0,0 +1,108 @@ +/** + * Enhanced Seccomp MIPS Specific Code + * + * Copyright (c) 2014 Imagination Technologies Ltd. + * Author: Markos Chandras <markos.chandras@imgtec.com> + * + */ + +/* + * 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 <string.h> +#include <linux/audit.h> + +#include "db.h" +#include "syscalls.h" +#include "arch.h" +#include "arch-mips.h" + +/* O32 ABI */ +#define __SCMP_NR_BASE 4000 + +/* mips syscall numbers */ +#define __mips_NR_socketcall (__SCMP_NR_BASE + 102) +#define __mips_NR_ipc (__SCMP_NR_BASE + 117) + +/** + * Resolve a syscall name to a number + * @param name the syscall name + * + * Resolve the given syscall name to the syscall number using the syscall table. + * Returns the syscall number on success, including negative pseudo syscall + * numbers; returns __NR_SCMP_ERROR on failure. + * + */ +int mips_syscall_resolve_name_raw(const char *name) +{ + int sys; + + /* NOTE: we don't want to modify the pseudo-syscall numbers */ + sys = mips_syscall_resolve_name(name); + if (sys == __NR_SCMP_ERROR || sys < 0) + return sys; + + return sys + __SCMP_NR_BASE; +} + +/** + * Resolve a syscall number to a name + * @param num the syscall number + * + * Resolve the given syscall number to the syscall name using the syscall table. + * Returns a pointer to the syscall name string on success, including pseudo + * syscall names; returns NULL on failure. + * + */ +const char *mips_syscall_resolve_num_raw(int num) +{ + /* NOTE: we don't want to modify the pseudo-syscall numbers */ + if (num >= __SCMP_NR_BASE) + num -= __SCMP_NR_BASE; + return mips_syscall_resolve_num(num); +} + +ARCH_DEF(mips) + +const struct arch_def arch_def_mips = { + .token = SCMP_ARCH_MIPS, + .token_bpf = AUDIT_ARCH_MIPS, + .size = ARCH_SIZE_32, + .endian = ARCH_ENDIAN_BIG, + .sys_socketcall = __mips_NR_socketcall, + .sys_ipc = __mips_NR_ipc, + .syscall_resolve_name = abi_syscall_resolve_name_munge, + .syscall_resolve_name_raw = mips_syscall_resolve_name_raw, + .syscall_resolve_num = abi_syscall_resolve_num_munge, + .syscall_resolve_num_raw = mips_syscall_resolve_num_raw, + .syscall_rewrite = abi_syscall_rewrite, + .rule_add = abi_rule_add, +}; + +const struct arch_def arch_def_mipsel = { + .token = SCMP_ARCH_MIPSEL, + .token_bpf = AUDIT_ARCH_MIPSEL, + .size = ARCH_SIZE_32, + .endian = ARCH_ENDIAN_LITTLE, + .sys_socketcall = __mips_NR_socketcall, + .sys_ipc = __mips_NR_ipc, + .syscall_resolve_name = abi_syscall_resolve_name_munge, + .syscall_resolve_name_raw = mips_syscall_resolve_name_raw, + .syscall_resolve_num = abi_syscall_resolve_num_munge, + .syscall_resolve_num_raw = mips_syscall_resolve_num_raw, + .syscall_rewrite = abi_syscall_rewrite, + .rule_add = abi_rule_add, +}; diff --git a/src/arch-mips.h b/src/arch-mips.h new file mode 100644 index 0000000..c8752a8 --- /dev/null +++ b/src/arch-mips.h @@ -0,0 +1,31 @@ +/** + * Enhanced Seccomp MIPS Specific Code + * + * Copyright (c) 2014 Imagination Technologies Ltd. + * Author: Markos Chandras <markos.chandras@imgtec.com> + * + */ + +/* + * 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>. + */ + +#ifndef _ARCH_MIPS_H +#define _ARCH_MIPS_H + +#include "arch.h" + +ARCH_DECL(mips) +ARCH_DECL(mipsel) + +#endif diff --git a/src/arch-mips64.c b/src/arch-mips64.c new file mode 100644 index 0000000..ca7027b --- /dev/null +++ b/src/arch-mips64.c @@ -0,0 +1,100 @@ +/** + * Enhanced Seccomp MIPS64 Specific Code + * + * Copyright (c) 2014 Red Hat <pmoore@redhat.com> + * Author: Paul Moore <paul@paul-moore.com> + * + */ + +/* + * 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 <linux/audit.h> + +#include "arch.h" +#include "arch-mips64.h" +#include "syscalls.h" + +/* 64 ABI */ +#define __SCMP_NR_BASE 5000 + +/** + * Resolve a syscall name to a number + * @param arch the architecture definition + * @param name the syscall name + * + * Resolve the given syscall name to the syscall number using the syscall table. + * Returns the syscall number on success, including negative pseudo syscall + * numbers; returns __NR_SCMP_ERROR on failure. + * + */ +int mips64_syscall_resolve_name_munge(const struct arch_def *arch, + const char *name) +{ + int sys; + + /* NOTE: we don't want to modify the pseudo-syscall numbers */ + sys = arch->syscall_resolve_name_raw(name); + if (sys == __NR_SCMP_ERROR || sys < 0) + return sys; + + return sys + __SCMP_NR_BASE; +} + +/** + * Resolve a syscall number to a name + * @param arch the architecture definition + * @param num the syscall number + * + * Resolve the given syscall number to the syscall name using the syscall table. + * Returns a pointer to the syscall name string on success, including pseudo + * syscall names; returns NULL on failure. + * + */ +const char *mips64_syscall_resolve_num_munge(const struct arch_def *arch, + int num) +{ + /* NOTE: we don't want to modify the pseudo-syscall numbers */ + if (num >= __SCMP_NR_BASE) + num -= __SCMP_NR_BASE; + return arch->syscall_resolve_num_raw(num); +} + +ARCH_DEF(mips64) + +const struct arch_def arch_def_mips64 = { + .token = SCMP_ARCH_MIPS64, + .token_bpf = AUDIT_ARCH_MIPS64, + .size = ARCH_SIZE_64, + .endian = ARCH_ENDIAN_BIG, + .syscall_resolve_name = mips64_syscall_resolve_name_munge, + .syscall_resolve_name_raw = mips64_syscall_resolve_name, + .syscall_resolve_num = mips64_syscall_resolve_num_munge, + .syscall_resolve_num_raw = mips64_syscall_resolve_num, + .syscall_rewrite = NULL, + .rule_add = NULL, +}; + +const struct arch_def arch_def_mipsel64 = { + .token = SCMP_ARCH_MIPSEL64, + .token_bpf = AUDIT_ARCH_MIPSEL64, + .size = ARCH_SIZE_64, + .endian = ARCH_ENDIAN_LITTLE, + .syscall_resolve_name = mips64_syscall_resolve_name_munge, + .syscall_resolve_name_raw = mips64_syscall_resolve_name, + .syscall_resolve_num = mips64_syscall_resolve_num_munge, + .syscall_resolve_num_raw = mips64_syscall_resolve_num, + .syscall_rewrite = NULL, + .rule_add = NULL, +}; diff --git a/src/arch-mips64.h b/src/arch-mips64.h new file mode 100644 index 0000000..c8eaba8 --- /dev/null +++ b/src/arch-mips64.h @@ -0,0 +1,31 @@ +/** + * Enhanced Seccomp MIPS64 Specific Code + * + * Copyright (c) 2014 Red Hat <pmoore@redhat.com> + * Author: Paul Moore <paul@paul-moore.com> + * + */ + +/* + * 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>. + */ + +#ifndef _ARCH_MIPS64_H +#define _ARCH_MIPS64_H + +#include "arch.h" + +ARCH_DECL(mips64) +ARCH_DECL(mipsel64) + +#endif diff --git a/src/arch-mips64n32.c b/src/arch-mips64n32.c new file mode 100644 index 0000000..c23cfc3 --- /dev/null +++ b/src/arch-mips64n32.c @@ -0,0 +1,102 @@ +/** + * Enhanced Seccomp MIPS Specific Code + * + * Copyright (c) 2014 Red Hat <pmoore@redhat.com> + * Author: Paul Moore <paul@paul-moore.com> + * + */ + +/* + * 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-mips64n32.h" +#include "syscalls.h" + +/* N32 ABI */ +#define __SCMP_NR_BASE 6000 + +/** + * Resolve a syscall name to a number + * @param arch the architecture definition + * @param name the syscall name + * + * Resolve the given syscall name to the syscall number using the syscall table. + * Returns the syscall number on success, including negative pseudo syscall + * numbers; returns __NR_SCMP_ERROR on failure. + * + */ +int mips64n32_syscall_resolve_name_munge(const struct arch_def *arch, + const char *name) +{ + int sys; + + /* NOTE: we don't want to modify the pseudo-syscall numbers */ + sys = mips64n32_syscall_resolve_name(name); + if (sys == __NR_SCMP_ERROR || sys < 0) + return sys; + + return sys + __SCMP_NR_BASE; +} + +/** + * Resolve a syscall number to a name + * @param arch the architecture definition + * @param num the syscall number + * + * Resolve the given syscall number to the syscall name using the syscall table. + * Returns a pointer to the syscall name string on success, including pseudo + * syscall names; returns NULL on failure. + * + */ +const char *mips64n32_syscall_resolve_num_munge(const struct arch_def *arch, + int num) +{ + /* NOTE: we don't want to modify the pseudo-syscall numbers */ + if (num >= __SCMP_NR_BASE) + num -= __SCMP_NR_BASE; + return mips64n32_syscall_resolve_num(num); +} + +ARCH_DEF(mips64n32) + +const struct arch_def arch_def_mips64n32 = { + .token = SCMP_ARCH_MIPS64N32, + .token_bpf = AUDIT_ARCH_MIPS64N32, + .size = ARCH_SIZE_32, + .endian = ARCH_ENDIAN_BIG, + .syscall_resolve_name = mips64n32_syscall_resolve_name_munge, + .syscall_resolve_name_raw = mips64n32_syscall_resolve_name, + .syscall_resolve_num = mips64n32_syscall_resolve_num_munge, + .syscall_resolve_num_raw = mips64n32_syscall_resolve_num, + .syscall_rewrite = NULL, + .rule_add = NULL, +}; + +const struct arch_def arch_def_mipsel64n32 = { + .token = SCMP_ARCH_MIPSEL64N32, + .token_bpf = AUDIT_ARCH_MIPSEL64N32, + .size = ARCH_SIZE_32, + .endian = ARCH_ENDIAN_LITTLE, + .syscall_resolve_name = mips64n32_syscall_resolve_name_munge, + .syscall_resolve_name_raw = mips64n32_syscall_resolve_name, + .syscall_resolve_num = mips64n32_syscall_resolve_num_munge, + .syscall_resolve_num_raw = mips64n32_syscall_resolve_num, + .syscall_rewrite = NULL, + .rule_add = NULL, +}; diff --git a/src/arch-mips64n32.h b/src/arch-mips64n32.h new file mode 100644 index 0000000..7f9146a --- /dev/null +++ b/src/arch-mips64n32.h @@ -0,0 +1,31 @@ +/** + * Enhanced Seccomp MIPS Specific Code + * + * Copyright (c) 2014 Red Hat <pmoore@redhat.com> + * Author: Paul Moore <paul@paul-moore.com> + * + */ + +/* + * 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>. + */ + +#ifndef _ARCH_MIPS64N32_H +#define _ARCH_MIPS64N32_H + +#include "arch.h" + +ARCH_DECL(mips64n32) +ARCH_DECL(mipsel64n32) + +#endif diff --git a/src/arch-parisc.c b/src/arch-parisc.c new file mode 100644 index 0000000..9a200fe --- /dev/null +++ b/src/arch-parisc.c @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2016 Helge Deller <deller@gmx.de> + * Author: Helge Deller <deller@gmx.de> + */ + +#include <stdlib.h> +#include <errno.h> +#include <linux/audit.h> + +#include "arch.h" +#include "arch-parisc.h" +#include "syscalls.h" + +ARCH_DEF(parisc) + +const struct arch_def arch_def_parisc = { + .token = SCMP_ARCH_PARISC, + .token_bpf = AUDIT_ARCH_PARISC, + .size = ARCH_SIZE_32, + .endian = ARCH_ENDIAN_BIG, + .syscall_resolve_name_raw = parisc_syscall_resolve_name, + .syscall_resolve_num_raw = parisc_syscall_resolve_num, + .syscall_rewrite = NULL, + .rule_add = NULL, +}; diff --git a/src/arch-parisc.h b/src/arch-parisc.h new file mode 100644 index 0000000..0a2df6a --- /dev/null +++ b/src/arch-parisc.h @@ -0,0 +1,29 @@ +/** + * Enhanced Seccomp PARISC Specific Code + * + * Copyright (c) 2016 Helge Deller <deller@gmx.de> + * + */ + +/* + * 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>. + */ + +#ifndef _ARCH_PARISC_H +#define _ARCH_PARISC_H + +#include "arch.h" + +ARCH_DECL(parisc) + +#endif diff --git a/src/arch-parisc64.c b/src/arch-parisc64.c new file mode 100644 index 0000000..2446407 --- /dev/null +++ b/src/arch-parisc64.c @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2016 Helge Deller <deller@gmx.de> + * Author: Helge Deller <deller@gmx.de> +*/ + +#include <stdlib.h> +#include <errno.h> +#include <linux/audit.h> + +#include "arch.h" +#include "arch-parisc64.h" +#include "syscalls.h" + +ARCH_DEF(parisc64) + +const struct arch_def arch_def_parisc64 = { + .token = SCMP_ARCH_PARISC64, + .token_bpf = AUDIT_ARCH_PARISC64, + .size = ARCH_SIZE_64, + .endian = ARCH_ENDIAN_BIG, + .syscall_resolve_name_raw = parisc64_syscall_resolve_name, + .syscall_resolve_num_raw = parisc64_syscall_resolve_num, + .syscall_rewrite = NULL, + .rule_add = NULL, +}; diff --git a/src/arch-parisc64.h b/src/arch-parisc64.h new file mode 100644 index 0000000..7ec889b --- /dev/null +++ b/src/arch-parisc64.h @@ -0,0 +1,29 @@ +/** + * Enhanced Seccomp PARISC Specific Code + * + * Copyright (c) 2016 Helge Deller <deller@gmx.de> + * + */ + +/* + * 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>. + */ + +#ifndef _ARCH_PARISC64_H +#define _ARCH_PARISC64_H + +#include "arch.h" + +ARCH_DECL(parisc64) + +#endif diff --git a/src/arch-ppc.c b/src/arch-ppc.c new file mode 100644 index 0000000..8fdad6f --- /dev/null +++ b/src/arch-ppc.c @@ -0,0 +1,52 @@ +/** + * Enhanced Seccomp PPC Specific Code + * + * Copyright (c) 2015 Freescale <bogdan.purcareata@freescale.com> + * Author: Bogdan Purcareata <bogdan.purcareata@freescale.com> + * + */ + +/* + * 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 <string.h> +#include <linux/audit.h> + +#include "db.h" +#include "syscalls.h" +#include "arch.h" +#include "arch-ppc.h" + +/* ppc syscall numbers */ +#define __ppc_NR_socketcall 102 +#define __ppc_NR_ipc 117 + +ARCH_DEF(ppc) + +const struct arch_def arch_def_ppc = { + .token = SCMP_ARCH_PPC, + .token_bpf = AUDIT_ARCH_PPC, + .size = ARCH_SIZE_32, + .endian = ARCH_ENDIAN_BIG, + .sys_socketcall = __ppc_NR_socketcall, + .sys_ipc = __ppc_NR_ipc, + .syscall_resolve_name = abi_syscall_resolve_name_munge, + .syscall_resolve_name_raw = ppc_syscall_resolve_name, + .syscall_resolve_num = abi_syscall_resolve_num_munge, + .syscall_resolve_num_raw = ppc_syscall_resolve_num, + .syscall_rewrite = abi_syscall_rewrite, + .rule_add = abi_rule_add, +}; diff --git a/src/arch-ppc.h b/src/arch-ppc.h new file mode 100644 index 0000000..f46aa1d --- /dev/null +++ b/src/arch-ppc.h @@ -0,0 +1,30 @@ +/** + * Enhanced Seccomp PPC Specific Code + * + * Copyright (c) 2015 Freescale <bogdan.purcareata@freescale.com> + * Author: Bogdan Purcareata <bogdan.purcareata@freescale.com> + * + */ + +/* + * 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>. + */ + +#ifndef _ARCH_PPC_H +#define _ARCH_PPC_H + +#include "arch.h" + +ARCH_DECL(ppc) + +#endif diff --git a/src/arch-ppc64.c b/src/arch-ppc64.c new file mode 100644 index 0000000..a2c88b3 --- /dev/null +++ b/src/arch-ppc64.c @@ -0,0 +1,67 @@ +/** + * Enhanced Seccomp PPC64 Specific Code + * + * Copyright (c) 2014 Red Hat <pmoore@redhat.com> + * Author: Paul Moore <paul@paul-moore.com> + * + */ + +/* + * 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 <string.h> +#include <linux/audit.h> + +#include "db.h" +#include "syscalls.h" +#include "arch.h" +#include "arch-ppc64.h" + +/* ppc64 syscall numbers */ +#define __ppc64_NR_socketcall 102 +#define __ppc64_NR_ipc 117 + +ARCH_DEF(ppc64) + +const struct arch_def arch_def_ppc64 = { + .token = SCMP_ARCH_PPC64, + .token_bpf = AUDIT_ARCH_PPC64, + .size = ARCH_SIZE_64, + .endian = ARCH_ENDIAN_BIG, + .sys_socketcall = __ppc64_NR_socketcall, + .sys_ipc = __ppc64_NR_ipc, + .syscall_resolve_name = abi_syscall_resolve_name_munge, + .syscall_resolve_name_raw = ppc64_syscall_resolve_name, + .syscall_resolve_num = abi_syscall_resolve_num_munge, + .syscall_resolve_num_raw = ppc64_syscall_resolve_num, + .syscall_rewrite = abi_syscall_rewrite, + .rule_add = abi_rule_add, +}; + +const struct arch_def arch_def_ppc64le = { + .token = SCMP_ARCH_PPC64LE, + .token_bpf = AUDIT_ARCH_PPC64LE, + .size = ARCH_SIZE_64, + .endian = ARCH_ENDIAN_LITTLE, + .sys_socketcall = __ppc64_NR_socketcall, + .sys_ipc = __ppc64_NR_ipc, + .syscall_resolve_name = abi_syscall_resolve_name_munge, + .syscall_resolve_name_raw = ppc64_syscall_resolve_name, + .syscall_resolve_num = abi_syscall_resolve_num_munge, + .syscall_resolve_num_raw = ppc64_syscall_resolve_num, + .syscall_rewrite = abi_syscall_rewrite, + .rule_add = abi_rule_add, +}; diff --git a/src/arch-ppc64.h b/src/arch-ppc64.h new file mode 100644 index 0000000..a0f7eb1 --- /dev/null +++ b/src/arch-ppc64.h @@ -0,0 +1,31 @@ +/** + * Enhanced Seccomp PPC64 Specific Code + * + * Copyright (c) 2014 Red Hat <pmoore@redhat.com> + * Author: Paul Moore <paul@paul-moore.com> + * + */ + +/* + * 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>. + */ + +#ifndef _ARCH_PPC64_H +#define _ARCH_PPC64_H + +#include "arch.h" + +ARCH_DECL(ppc64) +ARCH_DECL(ppc64le) + +#endif diff --git a/src/arch-riscv64.c b/src/arch-riscv64.c new file mode 100644 index 0000000..eb16b1e --- /dev/null +++ b/src/arch-riscv64.c @@ -0,0 +1,34 @@ +/* + * 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-riscv64.h" +#include "syscalls.h" + +ARCH_DEF(riscv64) + +const struct arch_def arch_def_riscv64 = { + .token = SCMP_ARCH_RISCV64, + .token_bpf = AUDIT_ARCH_RISCV64, + .size = ARCH_SIZE_64, + .endian = ARCH_ENDIAN_LITTLE, + .syscall_resolve_name_raw = riscv64_syscall_resolve_name, + .syscall_resolve_num_raw = riscv64_syscall_resolve_num, + .syscall_rewrite = NULL, + .rule_add = NULL, +}; diff --git a/src/arch-riscv64.h b/src/arch-riscv64.h new file mode 100644 index 0000000..96939f2 --- /dev/null +++ b/src/arch-riscv64.h @@ -0,0 +1,22 @@ +/* + * 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>. + */ + +#ifndef _ARCH_RISCV64_H +#define _ARCH_RISCV64_H + +#include "arch.h" + +ARCH_DECL(riscv64) + +#endif diff --git a/src/arch-s390.c b/src/arch-s390.c new file mode 100644 index 0000000..cbcc769 --- /dev/null +++ b/src/arch-s390.c @@ -0,0 +1,35 @@ +/* + * Copyright 2015 IBM + * Author: Jan Willeke <willeke@linux.vnet.com.com> + */ + +#include <stdlib.h> +#include <errno.h> +#include <string.h> +#include <linux/audit.h> + +#include "db.h" +#include "syscalls.h" +#include "arch.h" +#include "arch-s390.h" + +/* s390 syscall numbers */ +#define __s390_NR_socketcall 102 +#define __s390_NR_ipc 117 + +ARCH_DEF(s390) + +const struct arch_def arch_def_s390 = { + .token = SCMP_ARCH_S390, + .token_bpf = AUDIT_ARCH_S390, + .size = ARCH_SIZE_32, + .endian = ARCH_ENDIAN_BIG, + .sys_socketcall = __s390_NR_socketcall, + .sys_ipc = __s390_NR_ipc, + .syscall_resolve_name = abi_syscall_resolve_name_munge, + .syscall_resolve_name_raw = s390_syscall_resolve_name, + .syscall_resolve_num = abi_syscall_resolve_num_munge, + .syscall_resolve_num_raw = s390_syscall_resolve_num, + .syscall_rewrite = abi_syscall_rewrite, + .rule_add = abi_rule_add, +}; diff --git a/src/arch-s390.h b/src/arch-s390.h new file mode 100644 index 0000000..3881ef3 --- /dev/null +++ b/src/arch-s390.h @@ -0,0 +1,13 @@ +/* + * Copyright 2015 IBM + * Author: Jan Willeke <willeke@linux.vnet.com.com> + */ + +#ifndef _ARCH_S390_H +#define _ARCH_S390_H + +#include "arch.h" + +ARCH_DECL(s390) + +#endif diff --git a/src/arch-s390x.c b/src/arch-s390x.c new file mode 100644 index 0000000..0f0f619 --- /dev/null +++ b/src/arch-s390x.c @@ -0,0 +1,35 @@ +/* + * Copyright 2015 IBM + * Author: Jan Willeke <willeke@linux.vnet.com.com> + */ + +#include <stdlib.h> +#include <errno.h> +#include <string.h> +#include <linux/audit.h> + +#include "db.h" +#include "syscalls.h" +#include "arch.h" +#include "arch-s390x.h" + +/* s390x syscall numbers */ +#define __s390x_NR_socketcall 102 +#define __s390x_NR_ipc 117 + +ARCH_DEF(s390x) + +const struct arch_def arch_def_s390x = { + .token = SCMP_ARCH_S390X, + .token_bpf = AUDIT_ARCH_S390X, + .size = ARCH_SIZE_64, + .endian = ARCH_ENDIAN_BIG, + .sys_socketcall = __s390x_NR_socketcall, + .sys_ipc = __s390x_NR_ipc, + .syscall_resolve_name = abi_syscall_resolve_name_munge, + .syscall_resolve_name_raw = s390x_syscall_resolve_name, + .syscall_resolve_num = abi_syscall_resolve_num_munge, + .syscall_resolve_num_raw = s390x_syscall_resolve_num, + .syscall_rewrite = abi_syscall_rewrite, + .rule_add = abi_rule_add, +}; diff --git a/src/arch-s390x.h b/src/arch-s390x.h new file mode 100644 index 0000000..9592ec9 --- /dev/null +++ b/src/arch-s390x.h @@ -0,0 +1,13 @@ +/* + * Copyright 2015 IBM + * Author: Jan Willeke <willeke@linux.vnet.com.com> + */ + +#ifndef _ARCH_S390X_H +#define _ARCH_S390X_H + +#include "arch.h" + +ARCH_DECL(s390x) + +#endif diff --git a/src/arch-syscall-check b/src/arch-syscall-check new file mode 100755 index 0000000..ae67daa --- /dev/null +++ b/src/arch-syscall-check @@ -0,0 +1,60 @@ +#!/bin/bash + +# +# libseccomp syscall build-time checking script +# +# Copyright (c) 2021 Microsoft Corporation. <paulmoore@microsoft.com> +# +# Author: Paul Moore <paul@paul-moore.com> +# + +# +# 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>. +# + +SYSCALL_CSV="./syscalls.csv" +SYSCALL_HDR="../include/seccomp-syscalls.h" + +function check_snr() { + (export LC_ALL=C; diff \ + --label "CSV ($SYSCALL_CSV)" --label "HDR ($SYSCALL_HDR)" -u \ + <(tail -n+2 $SYSCALL_CSV | cut -d',' -f1 | sort -u) \ + <(grep __SNR_ $SYSCALL_HDR | awk '{ print $2 }' | \ + sed -e 's/^__SNR_//' | sort -u)) + return $? +} + +function check_pnr() { + # NOTE: we don't care if we have __PNR_ define that isn't needed, we + # likely want to preserve those values so they aren't mistakenly + # reused by a new __PNR_ in the future + (export LC_ALL=C; diff \ + <(tail -n+2 $SYSCALL_CSV | grep "PNR" | cut -d',' -f1 | \ + sort -u) \ + <(grep "#define __PNR_" $SYSCALL_HDR | awk '{ print $2 }' | \ + sed -e 's/^__PNR_//' | sort -u) | \ + grep "^<") + [[ $? -eq 1 ]] && return 0 || return 1 +} + +rc=0 + +echo ">>> CHECKING FOR MISSING __SNR_syscall VALUES" +check_snr +rc=$(( $rc + $? )) + +echo ">>> CHECKING FOR MISSING __PNR_syscall VALUES" +check_pnr +rc=$(( $rc + $? )) + +exit $rc diff --git a/src/arch-syscall-dump.c b/src/arch-syscall-dump.c new file mode 100644 index 0000000..2055d34 --- /dev/null +++ b/src/arch-syscall-dump.c @@ -0,0 +1,162 @@ +/** + * Enhanced Seccomp Architecture Sycall Checker + * + * Copyright (c) 2014 Red Hat <pmoore@redhat.com> + * Author: Paul Moore <paul@paul-moore.com> + * + */ + +/* + * 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 <errno.h> +#include <stdlib.h> +#include <stdio.h> +#include <ctype.h> +#include <string.h> +#include <unistd.h> + +#include <seccomp.h> + +#include "arch.h" +#include "arch-x86.h" +#include "arch-x86_64.h" +#include "arch-x32.h" +#include "arch-arm.h" +#include "arch-mips.h" +#include "arch-mips64.h" +#include "arch-mips64n32.h" +#include "arch-aarch64.h" +#include "arch-parisc.h" +#include "arch-parisc64.h" +#include "arch-ppc.h" +#include "arch-ppc64.h" +#include "arch-riscv64.h" +#include "arch-s390.h" +#include "arch-s390x.h" + +/** + * Print the usage information to stderr and exit + * @param program the name of the current program being invoked + * + * Print the usage information and exit with EINVAL. + * + */ +static void exit_usage(const char *program) +{ + fprintf(stderr, "usage: %s [-h] [-a <arch>] [-o <offset>]\n", program); + exit(EINVAL); +} + +/** + * main + */ +int main(int argc, char *argv[]) +{ + int opt; + const struct arch_def *arch = arch_def_native; + int offset = 0; + int iter; + const struct arch_syscall_def *sys; + + /* parse the command line */ + while ((opt = getopt(argc, argv, "a:o:h")) > 0) { + switch (opt) { + case 'a': + arch = arch_def_lookup_name(optarg); + if (arch == 0) + exit_usage(argv[0]); + break; + case 'o': + offset = atoi(optarg); + break; + case 'h': + default: + /* usage information */ + exit_usage(argv[0]); + } + } + + iter = 0; + do { + switch (arch->token) { + case SCMP_ARCH_X86: + sys = x86_syscall_iterate(iter); + break; + case SCMP_ARCH_X86_64: + sys = x86_64_syscall_iterate(iter); + break; + case SCMP_ARCH_X32: + sys = x32_syscall_iterate(iter); + break; + case SCMP_ARCH_ARM: + sys = arm_syscall_iterate(iter); + break; + case SCMP_ARCH_AARCH64: + sys = aarch64_syscall_iterate(iter); + break; + case SCMP_ARCH_MIPS: + case SCMP_ARCH_MIPSEL: + sys = mips_syscall_iterate(iter); + break; + case SCMP_ARCH_MIPS64: + case SCMP_ARCH_MIPSEL64: + sys = mips64_syscall_iterate(iter); + break; + case SCMP_ARCH_MIPS64N32: + case SCMP_ARCH_MIPSEL64N32: + sys = mips64n32_syscall_iterate(iter); + break; + case SCMP_ARCH_PARISC: + sys = parisc_syscall_iterate(iter); + break; + case SCMP_ARCH_PARISC64: + sys = parisc64_syscall_iterate(iter); + break; + case SCMP_ARCH_PPC: + sys = ppc_syscall_iterate(iter); + break; + case SCMP_ARCH_PPC64: + case SCMP_ARCH_PPC64LE: + sys = ppc64_syscall_iterate(iter); + break; + case SCMP_ARCH_RISCV64: + sys = riscv64_syscall_iterate(iter); + break; + case SCMP_ARCH_S390: + sys = s390_syscall_iterate(iter); + break; + case SCMP_ARCH_S390X: + sys = s390x_syscall_iterate(iter); + break; + default: + /* invalid arch */ + exit_usage(argv[0]); + } + if (sys->name != NULL) { + int sys_num = sys->num; + + if (offset > 0 && sys_num > 0) + sys_num -= offset; + + /* output the results */ + printf("%s\t%d\n", sys->name, sys_num); + + /* next */ + iter++; + } + } while (sys->name != NULL); + + return 0; +} diff --git a/src/arch-syscall-validate b/src/arch-syscall-validate new file mode 100755 index 0000000..3b69e9b --- /dev/null +++ b/src/arch-syscall-validate @@ -0,0 +1,867 @@ +#!/bin/bash + +# +# libseccomp syscall validation script +# +# Copyright (c) 2014 Red Hat <pmoore@redhat.com> +# Copyright (c) 2020 Cisco Systems, Inc. <pmoore2@cisco.com> +# +# Author: Paul Moore <paul@paul-moore.com> +# + +# +# 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>. +# + +LIB_SYS_DUMP="./arch-syscall-dump" + +#### +# functions + +# +# Dependency check +# +# Arguments: +# 1 Dependency to check for +# +function check_deps() { + [[ -z "$1" ]] && return + which "$1" >& /dev/null + return $? +} + +# +# Dependency verification +# +# Arguments: +# 1 Dependency to check for +# +function verify_deps() { + [[ -z "$1" ]] && return + if ! check_deps "$1"; then + echo "error: install \"$1\" and include it in your \$PATH" + exit 1 + fi +} + +# +# Print out script usage details +# +function usage() { +cat << EOF +usage: arch-syscall-validate [-h] [-c] [-a <arch>] <kernel_directory> + +libseccomp syscall validation script +optional arguments: + -h show this help message and exit + -a architecture + -l output the library's syscall definitions + -s output the kernel's syscall definitions + -c generate a CSV of the kernel's syscall definitions +EOF +} + +# +# Dump the kernel version +# +# Arguments: +# 1 path to the kernel source +# +# Dump the kernel's version information to stdout. +# +function kernel_version() { + local maj=$(cat $1/Makefile | \ + grep "^VERSION =" | awk -F "= " '{ print $2 }') + local min=$(cat $1/Makefile | \ + grep "^PATCHLEVEL =" | awk -F "= " '{ print $2 }') + local sub=$(cat $1/Makefile | \ + grep "^SUBLEVEL =" | awk -F "= " '{ print $2 }') + local xtr=$(cat $1/Makefile | \ + grep "^EXTRAVERSION =" | awk -F "= " '{ print $2 }') + echo "${maj}.${min}.${sub}${xtr}" +} + +# +# Dump the library syscall table for a given architecture +# +# Arguments: +# 1 architecture +# 2 offset (optional) +# +# +# Dump the library's syscall table to stdout. +# +function dump_lib_arch() { + local offset_str="" + + [[ -z $1 ]] && return + + [[ -n $2 ]] && offset_str="-o $2" + $LIB_SYS_DUMP -a $1 $offset_str | sed 's/\t/,/' | sort +} + +# +# Mangle the library pseudo syscall values +# +# Arguments: +# 1 architecture +# +# Mangle the supplied pseudo syscall to match the system values +# +function mangle_lib_syscall() { + local sed_filter="" + + sed_filter+='s/accept4,-118/accept4,364/;' + sed_filter+='s/bind,-102/bind,361/;' + sed_filter+='s/connect,-103/connect,362/;' + sed_filter+='s/getpeername,-107/getpeername,368/;' + sed_filter+='s/getsockname,-106/getsockname,367/;' + sed_filter+='s/getsockopt,-115/getsockopt,365/;' + sed_filter+='s/listen,-104/listen,363/;' + sed_filter+='s/msgctl,-214/msgctl,402/;' + sed_filter+='s/msgget,-213/msgget,399/;' + sed_filter+='s/msgrcv,-212/msgrcv,401/;' + sed_filter+='s/msgsnd,-211/msgsnd,400/;' + sed_filter+='s/recvfrom,-112/recvfrom,371/;' + sed_filter+='s/recvmsg,-117/recvmsg,372/;' + sed_filter+='s/semctl,-203/semctl,394/;' + sed_filter+='s/semget,-202/semget,393/;' + sed_filter+='s/sendmsg,-116/sendmsg,370/;' + sed_filter+='s/sendto,-111/sendto,369/;' + sed_filter+='s/setsockopt,-114/setsockopt,366/;' + sed_filter+='s/shmat,-221/shmat,397/;' + sed_filter+='s/shmctl,-224/shmctl,396/;' + sed_filter+='s/shmdt,-222/shmdt,398/;' + sed_filter+='s/shmget,-223/shmget,395/;' + sed_filter+='s/shutdown,-113/shutdown,373/;' + sed_filter+='s/socket,-101/socket,359/;' + sed_filter+='s/socketpair,-108/socketpair,360/;' + + case $1 in + s390|s390x) + sed_filter+='s/recvmmsg,-119/recvmmsg,357/;' + sed_filter+='s/sendmmsg,-120/sendmmsg,358/;' + ;; + *) + sed_filter+='s/recvmmsg,-119/recvmmsg,337/;' + sed_filter+='s/sendmmsg,-120/sendmmsg,345/;' + ;; + esac + + sed $sed_filter | sed '/,-[0-9]\+$/d' +} + +# +# Dump the x86 system syscall table +# +# Arguments: +# 1 path to the kernel source +# +# Dump the architecture's syscall table to stdout. +# +function dump_sys_x86() { + cat $1/arch/x86/entry/syscalls/syscall_32.tbl | \ + grep -v "^#" | awk '{ print $3","$1 }' | \ + sort +} + +# +# Dump the x86 library syscall table +# +# Dump the library's syscall table to stdout. +# +function dump_lib_x86() { + dump_lib_arch x86 | mangle_lib_syscall x86 +} + +# +# Dump the x86_64 system syscall table +# +# Arguments: +# 1 path to the kernel source +# +# Dump the architecture's syscall table to stdout. +# +function dump_sys_x86_64() { + cat $1/arch/x86/entry/syscalls/syscall_64.tbl | \ + grep -v "^#" | sed '/^$/d' | awk '{ print $2,$3,$1 }' | \ + sed '/^x32/d' | awk '{ print $2","$3 }' | sort +} + +# +# Dump the x86_64 library syscall table +# +# Dump the library's syscall table to stdout. +# +function dump_lib_x86_64() { + dump_lib_arch x86_64 | mangle_lib_syscall x86_64 +} + +# +# Dump the x32 system syscall table +# +# Arguments: +# 1 path to the kernel source +# +# Dump the architecture's syscall table to stdout. +# +function dump_sys_x32() { + cat $1/arch/x86/entry/syscalls/syscall_64.tbl | \ + grep -v "^#" | sed '/^$/d' | awk '{ print $2,$3,$1 }' | \ + sed '/^64/d' | awk '{ print $2","$3 }' | sort +} + +# +# Dump the x32 library syscall table +# +# Dump the library's syscall table to stdout. +# +function dump_lib_x32() { + dump_lib_arch x32 | mangle_lib_syscall x32 +} + +# +# Dump the arm system syscall table +# +# Arguments: +# 1 path to the kernel source +# +# Dump the architecture's syscall table to stdout. +# +function dump_sys_arm() { + cat $1/arch/arm/tools/syscall.tbl | grep -v "^#" | \ + sed -n "/[0-9]\+[ \t]\+\(common\|eabi\)/p" | \ + awk '{ print $3","$1 }' | sort | (cat -; \ + (cat $1/arch/arm/include/uapi/asm/unistd.h | \ + grep "^#define __ARM_NR_" | \ + grep -v "^#define __ARM_NR_BASE" | \ + sed 's/#define __ARM_NR_\([a-z0-9_]*\)[ \t]\+(__ARM_NR_BASE+\(.*\))/\1 983040 + \2/' | \ + awk '{ print $1","$2+$4 }')) | sort +} + +# +# Dump the arm library syscall table +# +# Dump the library's syscall table to stdout. +# +function dump_lib_arm() { + # NOTE: arm_sync_file_range() and sync_file_range2() share values + dump_lib_arch arm | sed '/sync_file_range2,\+341/d' | \ + mangle_lib_syscall arm +} + +# +# Dump the aarch64 system syscall table +# +# Arguments: +# 1 path to the kernel source +# +# Dump the architecture's syscall table to stdout. +# +function dump_sys_aarch64() { + local sed_filter="" + + sed_filter+='s/__NR3264_statfs/43/;' + sed_filter+='s/__NR3264_ftruncate/46/;' + sed_filter+='s/__NR3264_truncate/45/;' + sed_filter+='s/__NR3264_lseek/62/;' + sed_filter+='s/__NR3264_sendfile/71/;' + sed_filter+='s/__NR3264_fstatat/79/;' + sed_filter+='s/__NR3264_fstatfs/44/;' + sed_filter+='s/__NR3264_fcntl/25/;' + sed_filter+='s/__NR3264_fadvise64/223/;' + sed_filter+='s/__NR3264_mmap/222/;' + sed_filter+='s/__NR3264_fstat/80/;' + sed_filter+='s/__NR3264_lstat/1039/;' + sed_filter+='s/__NR3264_stat/1038/;' + + gcc -E -dM -I$1/include/uapi \ + -D__BITS_PER_LONG=64 -D__ARCH_WANT_RENAMEAT \ + -D__ARCH_WANT_NEW_STAT \ + $1/arch/arm64/include/uapi/asm/unistd.h | \ + grep "^#define __NR_" | \ + sed '/__NR_syscalls/d' | \ + sed '/__NR_arch_specific_syscall/d' | \ + sed 's/#define[ \t]\+__NR_\([^ \t]\+\)[ \t]\+\(.*\)/\1,\2/' | \ + sed $sed_filter | sort +} + +# +# Dump the aarch64 library syscall table +# +# Dump the library's syscall table to stdout. +# +function dump_lib_aarch64() { + dump_lib_arch aarch64 | mangle_lib_syscall aarch64 +} + +# +# Dump the mips system syscall table +# +# Arguments: +# 1 path to the kernel source +# +# Dump the architecture's syscall table to stdout. +# +function dump_sys_mips() { + cat $1/arch/mips/kernel/syscalls/syscall_o32.tbl | \ + grep -v "^#" | \ + sed -e '/[ \t]\+reserved[0-9]\+[ \t]\+/d;' | \ + sed -e '/[ \t]\+unused[0-9]\+[ \t]\+/d;' | \ + awk '{ print $3","$1 }' | sort +} + +# +# Dump the mips library syscall table +# +# Dump the library's syscall table to stdout. +# +function dump_lib_mips() { + dump_lib_arch mips | mangle_lib_syscall mips +} + +# +# Dump the mips64 system syscall table +# +# Arguments: +# 1 path to the kernel source +# +# Dump the architecture's syscall table to stdout. +# +function dump_sys_mips64() { + cat $1/arch/mips/kernel/syscalls/syscall_n64.tbl | \ + grep -v "^#" | \ + sed -e '/[ \t]\+reserved[0-9]\+[ \t]\+/d;' | \ + sed -e '/[ \t]\+unused[0-9]\+[ \t]\+/d;' | \ + awk '{ print $3","$1 }' | sort +} + +# +# Dump the mips64 library syscall table +# +# Dump the library's syscall table to stdout. +# +function dump_lib_mips64() { + dump_lib_arch mips64 | mangle_lib_syscall mips64 +} + +# +# Dump the mips64n32 system syscall table +# +# Arguments: +# 1 path to the kernel source +# +# Dump the architecture's syscall table to stdout. +# +function dump_sys_mips64n32() { + cat $1/arch/mips/kernel/syscalls/syscall_n32.tbl | \ + grep -v "^#" | \ + sed -e '/[ \t]\+reserved[0-9]\+[ \t]\+/d;' | \ + sed -e '/[ \t]\+unused[0-9]\+[ \t]\+/d;' | \ + awk '{ print $3","$1 }' | sort +} + +# +# Dump the mips64n32 library syscall table +# +# Dump the library's syscall table to stdout. +# +function dump_lib_mips64n32() { + dump_lib_arch mips64n32 | mangle_lib_syscall mips64n32 +} + +# +# Dump the parisc system syscall table +# +# Arguments: +# 1 path to the kernel source +# +# Dump the architecture's syscall table to stdout. +# +function dump_sys_parisc() { + cat $1/arch/parisc/kernel/syscalls/syscall.tbl | \ + grep -v "^#" | \ + sed -n "/[0-9]\+[ \t]\+\(common\|32\)/p" | \ + awk '{ print $3","$1 }' | \ + sort +} + +# +# Dump the parisc library syscall table +# +# Dump the library's syscall table to stdout. +# +function dump_lib_parisc() { + dump_lib_arch parisc | mangle_lib_syscall parisc +} + +# +# Dump the parisc64 system syscall table +# +# Arguments: +# 1 path to the kernel source +# +# Dump the architecture's syscall table to stdout. +# +function dump_sys_parisc64() { + cat $1/arch/parisc/kernel/syscalls/syscall.tbl | \ + grep -v "^#" | \ + sed -n "/[0-9]\+[ \t]\+\(common\|64\)/p" | \ + awk '{ print $3","$1 }' | \ + sort +} + +# +# Dump the parisc64 library syscall table +# +# Dump the library's syscall table to stdout. +# +function dump_lib_parisc64() { + dump_lib_arch parisc64 | mangle_lib_syscall parisc64 +} + +# +# Dump the ppc system syscall table +# +# Arguments: +# 1 path to the kernel source +# +# Dump the architecture's syscall table to stdout. +# +function dump_sys_ppc() { + cat $1/arch/powerpc/kernel/syscalls/syscall.tbl | grep -v "^#" | \ + sed -ne "/[0-9]\+[ \t]\+\(common\|nospu\|32\)/p" | \ + awk '{ print $3","$1 }' | sort +} + +# +# Dump the ppc library syscall table +# +# Dump the library's syscall table to stdout. +# +function dump_lib_ppc() { + dump_lib_arch ppc | mangle_lib_syscall ppc +} + +# +# Dump the ppc64 system syscall table +# +# Arguments: +# 1 path to the kernel source +# +# Dump the architecture's syscall table to stdout. +# +function dump_sys_ppc64() { + cat $1/arch/powerpc/kernel/syscalls/syscall.tbl | grep -v "^#" | \ + sed -ne "/[0-9]\+[ \t]\+\(common\|nospu\|64\)/p" | \ + awk '{ print $3","$1 }' | sort +} + +# +# Dump the ppc64 library syscall table +# +# Dump the library's syscall table to stdout. +# +function dump_lib_ppc64() { + dump_lib_arch ppc64 | mangle_lib_syscall ppc64 +} + +# +# Dump the riscv64 system syscall table +# +# Arguments: +# 1 path to the kernel source +# +# Dump the architecture's syscall table to stdout. +# +function dump_sys_riscv64() { + local sed_filter="" + + sed_filter+='s/__NR3264_fadvise64/223/;' + sed_filter+='s/__NR3264_fcntl/25/;' + sed_filter+='s/__NR3264_fstatat/79/;' + sed_filter+='s/__NR3264_fstatfs/44/;' + sed_filter+='s/__NR3264_ftruncate/46/;' + sed_filter+='s/__NR3264_lseek/62/;' + sed_filter+='s/__NR3264_mmap/222/;' + sed_filter+='s/__NR3264_sendfile/71/;' + sed_filter+='s/__NR3264_statfs/43/;' + sed_filter+='s/__NR3264_truncate/45/;' + sed_filter+='s/__NR3264_fstat/80/;' + + gcc -E -dM -I$1/include/uapi \ + -D__BITS_PER_LONG=64 -D__ARCH_WANT_NEW_STAT \ + $1/arch/riscv/include/uapi/asm/unistd.h | \ + grep "^#define __NR_" | \ + sed '/__NR_syscalls/d' | \ + sed 's/(__NR_arch_specific_syscall + 15)/259/' | \ + sed '/__NR_arch_specific_syscall/d' | \ + sed 's/#define[ \t]\+__NR_\([^ \t]\+\)[ \t]\+\(.*\)/\1,\2/' | \ + sed $sed_filter | sort +} + +# +# Dump the riscv64 library syscall table +# +# Dump the library's syscall table to stdout. +# +function dump_lib_riscv64() { + dump_lib_arch riscv64 | mangle_lib_syscall riscv64 +} + +# +# Dump the s390 system syscall table +# +# Arguments: +# 1 path to the kernel source +# +# Dump the architecture's syscall table to stdout. +# +function dump_sys_s390() { + cat $1/arch/s390/kernel/syscalls/syscall.tbl | grep -v "^#" | \ + sed -ne "/[0-9]\+[ \t]\+\(common\|32\)/p" | \ + awk '{ print $3","$1 }' | \ + sort +} + +# +# Dump the s390 library syscall table +# +# Dump the library's syscall table to stdout. +# +function dump_lib_s390() { + dump_lib_arch s390 | mangle_lib_syscall s390 +} + +# +# Dump the s390x system syscall table +# +# Arguments: +# 1 path to the kernel source +# +# Dump the architecture's syscall table to stdout. +# +function dump_sys_s390x() { + cat $1/arch/s390/kernel/syscalls/syscall.tbl | grep -v "^#" | \ + sed -ne "/[0-9]\+[ \t]\+\(common\|64\)/p" | \ + awk '{ print $3","$1 }' | \ + sort +} + +# +# Dump the s390x library syscall table +# +# Dump the library's syscall table to stdout. +# +function dump_lib_s390x() { + dump_lib_arch s390x | mangle_lib_syscall s390x +} + +# +# Dump the system syscall table +# +# Arguments: +# 1 architecture +# 2 path to the kernel source +# +# Dump the system's syscall table to stdout using the given architecture. +# +function dump_sys() { + case $1 in + x86) + dump_sys_x86 "$2" + ;; + x86_64) + dump_sys_x86_64 "$2" + ;; + x32) + dump_sys_x32 "$2" + ;; + arm) + dump_sys_arm "$2" + ;; + aarch64) + dump_sys_aarch64 "$2" + ;; + mips) + dump_sys_mips "$2" + ;; + mips64) + dump_sys_mips64 "$2" + ;; + mips64n32) + dump_sys_mips64n32 "$2" + ;; + parisc) + dump_sys_parisc "$2" + ;; + parisc64) + dump_sys_parisc64 "$2" + ;; + ppc) + dump_sys_ppc "$2" + ;; + ppc64) + dump_sys_ppc64 "$2" + ;; + riscv64) + dump_sys_riscv64 "$2" + ;; + s390) + dump_sys_s390 "$2" + ;; + s390x) + dump_sys_s390x "$2" + ;; + *) + echo "" + return 1 + ;; + esac + + return 0 +} + +# +# Dump the library syscall table +# +# Arguments: +# 1 architecture +# +# Dump the library's syscall table to stdout using the given architecture. +# +function dump_lib() { + case $1 in + x86) + dump_lib_x86 + ;; + x86_64) + dump_lib_x86_64 + ;; + x32) + dump_lib_x32 + ;; + arm) + dump_lib_arm + ;; + aarch64) + dump_lib_aarch64 + ;; + mips) + dump_lib_mips + ;; + mips64) + dump_lib_mips64 + ;; + mips64n32) + dump_lib_mips64n32 + ;; + parisc) + dump_lib_parisc + ;; + parisc64) + dump_lib_parisc64 + ;; + ppc) + dump_lib_ppc + ;; + ppc64) + dump_lib_ppc64 + ;; + riscv64) + dump_lib_riscv64 + ;; + s390) + dump_lib_s390 + ;; + s390x) + dump_lib_s390x + ;; + *) + echo "" + return 1 + ;; + esac + + return 0 +} + +# +# Generate the syscall csv file +# +# Arguments: +# 1 path to the kernel source +# 2 "sys" or "lib" depending on the syscall list to use +# +# Generare a syscall csv file from the given kernel sources. +# +function gen_csv() { + + # sanity checks + [[ -z $1 ]] && return + [[ $2 != "sys" && $2 != "lib" ]] && return + + # abi list + # NOTE: the ordering here is dependent on the layout of the + # arch_syscall_table struct in syscalls.h - BEWARE! + abi_list="" + abi_list+=" x86 x86_64 x32" + abi_list+=" arm aarch64" + abi_list+=" mips mips64 mips64n32" + abi_list+=" parisc parisc64" + abi_list+=" ppc ppc64" + abi_list+=" riscv64" + abi_list+=" s390 s390x" + + # get the full syscall list + for abi in $abi_list; do + eval output_$abi=$(mktemp -t syscall_validate_XXXXXX) + dump_$2_$abi "$1" > $(eval echo $`eval echo output_$abi`) + done + sc_list=$((for abi in $abi_list; do + cat $(eval echo $`eval echo output_$abi`); + done) | awk -F "," '{ print $1 }' | sort -u) + + # output a simple header + printf "#syscall (v%s %s)" \ + "$(kernel_version "$1")" "$(TZ=UTC date "+%Y-%m-%d")" + for abi in $abi_list; do + printf ",%s" $abi + done + printf "\n" + + # output the syscall csv details + for sc in $sc_list; do + printf "%s" $sc + for abi in $abi_list; do + num=$(grep "^$sc," \ + $(eval echo $`eval echo output_$abi`) | \ + awk -F "," '{ print $2 }' ) + [[ -z $num ]] && num="PNR" + printf ",%s" $num + done + printf "\n" + done + + # cleanup + for abi in $abi_list; do + rm -f $(eval echo $`eval echo output_$abi`) + done +} + +#### +# main + +verify_deps diff +verify_deps gcc +verify_deps grep +verify_deps mktemp +verify_deps sed +if [[ ! -x $LIB_SYS_DUMP ]]; then + echo "error: \"$LIB_SYS_DUMP\" is not in the current working directory" + exit 1 +fi + +opt_arches="" +opt_csv=0 +opt_sys=0 +opt_lib=0 + +while getopts "a:cslh" opt; do + case $opt in + a) + opt_arches+="$OPTARG " + ;; + c) + opt_csv=1 + ;; + s) + opt_sys=1 + opt_lib=0 + ;; + l) + opt_sys=0 + opt_lib=1 + ;; + h|*) + usage + exit 1 + ;; + esac +done +shift $(($OPTIND - 1)) + +# defaults +if [[ $opt_arches == "" ]]; then + opt_arches=" \ + x86 x86_64 x32 \ + arm aarch64 \ + mips mips64 mips64n32 \ + parisc parisc64 \ + ppc ppc64 \ + s390 s390x" +fi + +# sanity checks +kernel_dir="$1" +if [[ -z $kernel_dir ]]; then + usage + exit 1 +fi +if [[ ! -d $kernel_dir ]]; then + echo "error: \"$1\" is not a valid directory" + exit 1 +fi + +# generate some temp files +tmp_lib=$(mktemp -t syscall_validate_XXXXXX) +tmp_sys=$(mktemp -t syscall_validate_XXXXXX) + +if [[ $opt_csv -eq 1 ]]; then + # generate the syscall csv file + if [[ $opt_lib -eq 1 ]]; then + gen_csv $kernel_dir "lib" + else + gen_csv $kernel_dir "sys" + fi +else + # loop through the architectures and compare + for i in $opt_arches; do + # dump the syscall tables + dump_lib $i > $tmp_lib + if [[ $? -ne 0 ]]; then + echo "error: unknown arch $i" + exit 1 + fi + dump_sys $i "$kernel_dir" > $tmp_sys + if [[ $? -ne 0 ]]; then + echo "error: unknown arch $i" + exit 1 + fi + + if [[ $opt_lib -eq 1 ]]; then + cat $tmp_lib + elif [[ $opt_sys -eq 1 ]]; then + cat $tmp_sys + else + # compare the lib and sys output + diff -u --label="$i [library]" $tmp_lib \ + --label "$i [system]" $tmp_sys + fi + done +fi + +# cleanup and exit +rm -f $tmp_lib $tmp_sys + +exit 0 diff --git a/src/arch-x32.c b/src/arch-x32.c new file mode 100644 index 0000000..cca6940 --- /dev/null +++ b/src/arch-x32.c @@ -0,0 +1,86 @@ +/** + * Enhanced Seccomp x32 Specific Code + * + * Copyright (c) 2013 Red Hat <pmoore@redhat.com> + * Author: Paul Moore <paul@paul-moore.com> + */ + +/* + * 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-x32.h" +#include "syscalls.h" + +/** + * Resolve a syscall name to a number + * @param arch the architecture definition + * @param name the syscall name + * + * Resolve the given syscall name to the syscall number using the syscall table. + * Returns the syscall number on success, including negative pseudo syscall + * numbers; returns __NR_SCMP_ERROR on failure. + * + */ +int x32_syscall_resolve_name_munge(const struct arch_def *arch, + const char *name) +{ + int sys; + + /* NOTE: we don't want to modify the pseudo-syscall numbers */ + sys = arch->syscall_resolve_name_raw(name); + if (sys == __NR_SCMP_ERROR || sys < 0) + return sys; + + return (sys | X32_SYSCALL_BIT); +} + +/** + * Resolve a syscall number to a name + * @param arch the architecture definition + * @param num the syscall number + * + * Resolve the given syscall number to the syscall name using the syscall table. + * Returns a pointer to the syscall name string on success, including pseudo + * syscall names; returns NULL on failure. + * + */ +const char *x32_syscall_resolve_num_munge(const struct arch_def *arch, + int num) +{ + /* NOTE: we don't want to modify the pseudo-syscall numbers */ + if (num >= 0) + num &= ~X32_SYSCALL_BIT; + return arch->syscall_resolve_num_raw(num); +} + +ARCH_DEF(x32) + +const struct arch_def arch_def_x32 = { + .token = SCMP_ARCH_X32, + /* NOTE: this seems odd but the kernel treats x32 like x86_64 here */ + .token_bpf = AUDIT_ARCH_X86_64, + .size = ARCH_SIZE_32, + .endian = ARCH_ENDIAN_LITTLE, + .syscall_resolve_name = x32_syscall_resolve_name_munge, + .syscall_resolve_name_raw = x32_syscall_resolve_name, + .syscall_resolve_num = x32_syscall_resolve_num_munge, + .syscall_resolve_num_raw = x32_syscall_resolve_num, + .syscall_rewrite = NULL, + .rule_add = NULL, +}; diff --git a/src/arch-x32.h b/src/arch-x32.h new file mode 100644 index 0000000..639fd20 --- /dev/null +++ b/src/arch-x32.h @@ -0,0 +1,31 @@ +/** + * Enhanced Seccomp x32 Specific Code + * + * Copyright (c) 2013 Red Hat <pmoore@redhat.com> + * Author: Paul Moore <paul@paul-moore.com> + */ + +/* + * 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>. + */ + +#ifndef _ARCH_X32_H +#define _ARCH_X32_H + +#include "arch.h" + +#define X32_SYSCALL_BIT 0x40000000 + +ARCH_DECL(x32) + +#endif diff --git a/src/arch-x86.c b/src/arch-x86.c new file mode 100644 index 0000000..f086ab0 --- /dev/null +++ b/src/arch-x86.c @@ -0,0 +1,51 @@ +/** + * Enhanced Seccomp x86 Specific Code + * + * Copyright (c) 2012,2016 Red Hat <pmoore@redhat.com> + * Author: Paul Moore <paul@paul-moore.com> + */ + +/* + * 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 <string.h> +#include <linux/audit.h> + +#include "db.h" +#include "syscalls.h" +#include "arch.h" +#include "arch-x86.h" + +/* x86 syscall numbers */ +#define __x86_NR_socketcall 102 +#define __x86_NR_ipc 117 + +ARCH_DEF(x86) + +const struct arch_def arch_def_x86 = { + .token = SCMP_ARCH_X86, + .token_bpf = AUDIT_ARCH_I386, + .size = ARCH_SIZE_32, + .endian = ARCH_ENDIAN_LITTLE, + .sys_socketcall = __x86_NR_socketcall, + .sys_ipc = __x86_NR_ipc, + .syscall_resolve_name = abi_syscall_resolve_name_munge, + .syscall_resolve_name_raw = x86_syscall_resolve_name, + .syscall_resolve_num = abi_syscall_resolve_num_munge, + .syscall_resolve_num_raw = x86_syscall_resolve_num, + .syscall_rewrite = abi_syscall_rewrite, + .rule_add = abi_rule_add, +}; diff --git a/src/arch-x86.h b/src/arch-x86.h new file mode 100644 index 0000000..a2e0b12 --- /dev/null +++ b/src/arch-x86.h @@ -0,0 +1,29 @@ +/** + * Enhanced Seccomp x86 Specific Code + * + * Copyright (c) 2012 Red Hat <pmoore@redhat.com> + * Author: Paul Moore <paul@paul-moore.com> + */ + +/* + * 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>. + */ + +#ifndef _ARCH_X86_H +#define _ARCH_X86_H + +#include "arch.h" + +ARCH_DECL(x86) + +#endif diff --git a/src/arch-x86_64.c b/src/arch-x86_64.c new file mode 100644 index 0000000..5825612 --- /dev/null +++ b/src/arch-x86_64.c @@ -0,0 +1,41 @@ +/** + * Enhanced Seccomp x86_64 Specific Code + * + * Copyright (c) 2012 Red Hat <pmoore@redhat.com> + * Author: Paul Moore <paul@paul-moore.com> + */ + +/* + * 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" +#include "syscalls.h" + +ARCH_DEF(x86_64) + +const struct arch_def arch_def_x86_64 = { + .token = SCMP_ARCH_X86_64, + .token_bpf = AUDIT_ARCH_X86_64, + .size = ARCH_SIZE_64, + .endian = ARCH_ENDIAN_LITTLE, + .syscall_resolve_name_raw = x86_64_syscall_resolve_name, + .syscall_resolve_num_raw = x86_64_syscall_resolve_num, + .syscall_rewrite = NULL, + .rule_add = NULL, +}; diff --git a/src/arch-x86_64.h b/src/arch-x86_64.h new file mode 100644 index 0000000..fcba125 --- /dev/null +++ b/src/arch-x86_64.h @@ -0,0 +1,29 @@ +/** + * Enhanced Seccomp x86_64 Specific Code + * + * Copyright (c) 2012 Red Hat <pmoore@redhat.com> + * Author: Paul Moore <paul@paul-moore.com> + */ + +/* + * 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>. + */ + +#ifndef _ARCH_x86_64_H +#define _ARCH_x86_64_H + +#include "arch.h" + +ARCH_DECL(x86_64) + +#endif diff --git a/src/arch.c b/src/arch.c new file mode 100644 index 0000000..8ef77b1 --- /dev/null +++ b/src/arch.c @@ -0,0 +1,450 @@ +/** + * Enhanced Seccomp Architecture/Machine Specific Code + * + * Copyright (c) 2012,2018 Red Hat <pmoore@redhat.com> + * Author: Paul Moore <paul@paul-moore.com> + */ + +/* + * 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 <elf.h> +#include <errno.h> +#include <stdlib.h> +#include <string.h> +#include <asm/bitsperlong.h> +#include <linux/audit.h> +#include <stdbool.h> + +#include <seccomp.h> + +#include "arch.h" +#include "arch-x86.h" +#include "arch-x86_64.h" +#include "arch-x32.h" +#include "arch-arm.h" +#include "arch-aarch64.h" +#include "arch-mips.h" +#include "arch-mips64.h" +#include "arch-mips64n32.h" +#include "arch-parisc.h" +#include "arch-parisc64.h" +#include "arch-ppc.h" +#include "arch-ppc64.h" +#include "arch-riscv64.h" +#include "arch-s390.h" +#include "arch-s390x.h" +#include "db.h" +#include "system.h" + +#define default_arg_offset(x) (offsetof(struct seccomp_data, args[x])) + +#if __i386__ +const struct arch_def *arch_def_native = &arch_def_x86; +#elif __x86_64__ +#ifdef __ILP32__ +const struct arch_def *arch_def_native = &arch_def_x32; +#else +const struct arch_def *arch_def_native = &arch_def_x86_64; +#endif /* __ILP32__ */ +#elif __arm__ +const struct arch_def *arch_def_native = &arch_def_arm; +#elif __aarch64__ +const struct arch_def *arch_def_native = &arch_def_aarch64; +#elif __mips__ && _MIPS_SIM == _MIPS_SIM_ABI32 +#if __MIPSEB__ +const struct arch_def *arch_def_native = &arch_def_mips; +#elif __MIPSEL__ +const struct arch_def *arch_def_native = &arch_def_mipsel; +#endif /* _MIPS_SIM_ABI32 */ +#elif __mips__ && _MIPS_SIM == _MIPS_SIM_ABI64 +#if __MIPSEB__ +const struct arch_def *arch_def_native = &arch_def_mips64; +#elif __MIPSEL__ +const struct arch_def *arch_def_native = &arch_def_mipsel64; +#endif /* _MIPS_SIM_ABI64 */ +#elif __mips__ && _MIPS_SIM == _MIPS_SIM_NABI32 +#if __MIPSEB__ +const struct arch_def *arch_def_native = &arch_def_mips64n32; +#elif __MIPSEL__ +const struct arch_def *arch_def_native = &arch_def_mipsel64n32; +#endif /* _MIPS_SIM_NABI32 */ +#elif __hppa64__ /* hppa64 must be checked before hppa */ +const struct arch_def *arch_def_native = &arch_def_parisc64; +#elif __hppa__ +const struct arch_def *arch_def_native = &arch_def_parisc; +#elif __PPC64__ +#ifdef __BIG_ENDIAN__ +const struct arch_def *arch_def_native = &arch_def_ppc64; +#else +const struct arch_def *arch_def_native = &arch_def_ppc64le; +#endif +#elif __PPC__ +const struct arch_def *arch_def_native = &arch_def_ppc; +#elif __s390x__ /* s390x must be checked before s390 */ +const struct arch_def *arch_def_native = &arch_def_s390x; +#elif __s390__ +const struct arch_def *arch_def_native = &arch_def_s390; +#elif __riscv && __riscv_xlen == 64 +const struct arch_def *arch_def_native = &arch_def_riscv64; +#else +#error the arch code needs to know about your machine type +#endif /* machine type guess */ + +/** + * Validate the architecture token + * @param arch the architecture token + * + * Verify the given architecture token; return zero if valid, -EINVAL if not. + * + */ +int arch_valid(uint32_t arch) +{ + return (arch_def_lookup(arch) ? 0 : -EINVAL); +} + +/** + * Lookup the architecture definition + * @param token the architecure token + * + * Return the matching architecture definition, returns NULL on failure. + * + */ +const struct arch_def *arch_def_lookup(uint32_t token) +{ + switch (token) { + case SCMP_ARCH_X86: + return &arch_def_x86; + case SCMP_ARCH_X86_64: + return &arch_def_x86_64; + case SCMP_ARCH_X32: + return &arch_def_x32; + case SCMP_ARCH_ARM: + return &arch_def_arm; + case SCMP_ARCH_AARCH64: + return &arch_def_aarch64; + case SCMP_ARCH_MIPS: + return &arch_def_mips; + case SCMP_ARCH_MIPSEL: + return &arch_def_mipsel; + case SCMP_ARCH_MIPS64: + return &arch_def_mips64; + case SCMP_ARCH_MIPSEL64: + return &arch_def_mipsel64; + case SCMP_ARCH_MIPS64N32: + return &arch_def_mips64n32; + case SCMP_ARCH_MIPSEL64N32: + return &arch_def_mipsel64n32; + case SCMP_ARCH_PARISC: + return &arch_def_parisc; + case SCMP_ARCH_PARISC64: + return &arch_def_parisc64; + case SCMP_ARCH_PPC: + return &arch_def_ppc; + case SCMP_ARCH_PPC64: + return &arch_def_ppc64; + case SCMP_ARCH_PPC64LE: + return &arch_def_ppc64le; + case SCMP_ARCH_S390: + return &arch_def_s390; + case SCMP_ARCH_S390X: + return &arch_def_s390x; + case SCMP_ARCH_RISCV64: + return &arch_def_riscv64; + } + + return NULL; +} + +/** + * Lookup the architecture definition by name + * @param arch_name the architecure name + * + * Return the matching architecture definition, returns NULL on failure. + * + */ +const struct arch_def *arch_def_lookup_name(const char *arch_name) +{ + if (strcmp(arch_name, "x86") == 0) + return &arch_def_x86; + else if (strcmp(arch_name, "x86_64") == 0) + return &arch_def_x86_64; + else if (strcmp(arch_name, "x32") == 0) + return &arch_def_x32; + else if (strcmp(arch_name, "arm") == 0) + return &arch_def_arm; + else if (strcmp(arch_name, "aarch64") == 0) + return &arch_def_aarch64; + else if (strcmp(arch_name, "mips") == 0) + return &arch_def_mips; + else if (strcmp(arch_name, "mipsel") == 0) + return &arch_def_mipsel; + else if (strcmp(arch_name, "mips64") == 0) + return &arch_def_mips64; + else if (strcmp(arch_name, "mipsel64") == 0) + return &arch_def_mipsel64; + else if (strcmp(arch_name, "mips64n32") == 0) + return &arch_def_mips64n32; + else if (strcmp(arch_name, "mipsel64n32") == 0) + return &arch_def_mipsel64n32; + else if (strcmp(arch_name, "parisc64") == 0) + return &arch_def_parisc64; + else if (strcmp(arch_name, "parisc") == 0) + return &arch_def_parisc; + else if (strcmp(arch_name, "ppc") == 0) + return &arch_def_ppc; + else if (strcmp(arch_name, "ppc64") == 0) + return &arch_def_ppc64; + else if (strcmp(arch_name, "ppc64le") == 0) + return &arch_def_ppc64le; + else if (strcmp(arch_name, "s390") == 0) + return &arch_def_s390; + else if (strcmp(arch_name, "s390x") == 0) + return &arch_def_s390x; + else if (strcmp(arch_name, "riscv64") == 0) + return &arch_def_riscv64; + + return NULL; +} + +/** + * Determine the argument offset for the lower 32 bits + * @param arch the architecture definition + * @param arg the argument number + * + * Determine the correct offset for the low 32 bits of the given argument based + * on the architecture definition. Returns the offset on success, negative + * values on failure. + * + */ +int arch_arg_offset_lo(const struct arch_def *arch, unsigned int arg) +{ + if (arch_valid(arch->token) < 0) + return -EDOM; + + switch (arch->endian) { + case ARCH_ENDIAN_LITTLE: + return default_arg_offset(arg); + break; + case ARCH_ENDIAN_BIG: + return default_arg_offset(arg) + 4; + break; + default: + return -EDOM; + } +} + +/** + * Determine the argument offset for the high 32 bits + * @param arch the architecture definition + * @param arg the argument number + * + * Determine the correct offset for the high 32 bits of the given argument + * based on the architecture definition. Returns the offset on success, + * negative values on failure. + * + */ +int arch_arg_offset_hi(const struct arch_def *arch, unsigned int arg) +{ + if (arch_valid(arch->token) < 0 || arch->size != ARCH_SIZE_64) + return -EDOM; + + switch (arch->endian) { + case ARCH_ENDIAN_LITTLE: + return default_arg_offset(arg) + 4; + break; + case ARCH_ENDIAN_BIG: + return default_arg_offset(arg); + break; + default: + return -EDOM; + } +} + +/** + * Determine the argument offset + * @param arch the architecture definition + * @param arg the argument number + * + * Determine the correct offset for the given argument based on the + * architecture definition. Returns the offset on success, negative values on + * failure. + * + */ +int arch_arg_offset(const struct arch_def *arch, unsigned int arg) +{ + return arch_arg_offset_lo(arch, arg); +} + +/** + * Resolve a syscall name to a number + * @param arch the architecture definition + * @param name the syscall name + * + * Resolve the given syscall name to the syscall number based on the given + * architecture. Returns the syscall number on success, including negative + * pseudo syscall numbers; returns __NR_SCMP_ERROR on failure. + * + */ +int arch_syscall_resolve_name(const struct arch_def *arch, const char *name) +{ + if (arch->syscall_resolve_name) + return (*arch->syscall_resolve_name)(arch, name); + if (arch->syscall_resolve_name_raw) + return (*arch->syscall_resolve_name_raw)(name); + + return __NR_SCMP_ERROR; +} + +/** + * Resolve a syscall number to a name + * @param arch the architecture definition + * @param num the syscall number + * + * Resolve the given syscall number to the syscall name based on the given + * architecture. Returns a pointer to the syscall name string on success, + * including pseudo syscall names; returns NULL on failure. + * + */ +const char *arch_syscall_resolve_num(const struct arch_def *arch, int num) +{ + if (arch->syscall_resolve_num) + return (*arch->syscall_resolve_num)(arch, num); + if (arch->syscall_resolve_num_raw) + return (*arch->syscall_resolve_num_raw)(num); + + return NULL; +} + +/** + * 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; + + /* special handling for syscall -1 */ + if (*syscall == -1) + return 0; + + 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 + * + * Syscalls can vary across different architectures so this function rewrites + * the syscall into the correct value for the specified architecture. Returns + * zero on success, -EDOM if the syscall is not defined for @arch, and negative + * values on failure. + * + */ +int arch_syscall_rewrite(const struct arch_def *arch, int *syscall) +{ + int sys = *syscall; + + if (sys >= -1) { + /* we shouldn't be here - no rewrite needed */ + return 0; + } else if (sys > -100) { + /* -2 to -99 are reserved values */ + return -EINVAL; + } else if (sys > -10000) { + /* rewritable syscalls */ + if (arch->syscall_rewrite) + (*arch->syscall_rewrite)(arch, syscall); + } + + /* syscalls not defined on this architecture */ + if ((*syscall) < 0) + return -EDOM; + return 0; +} + +/** + * Add a new rule to the specified filter + * @param db the seccomp filter db + * @param strict the rule + * + * This function adds a new argument/comparison/value to the seccomp filter for + * a syscall; multiple arguments can be specified and they will be chained + * together (essentially AND'd together) in the filter. When the strict flag + * is true the function will fail if the exact rule can not be added to the + * filter, if the strict flag is false the function will not fail if the + * function needs to adjust the rule due to architecture specifics. Returns + * zero on success, negative values on failure. + * + * It is important to note that in the case of failure the db may be corrupted, + * the caller must use the transaction mechanism if the db integrity is + * important. + * + */ +int arch_filter_rule_add(struct db_filter *db, + const struct db_api_rule_list *rule) +{ + int rc = 0; + int syscall; + struct db_api_rule_list *rule_dup = NULL; + + /* create our own rule that we can munge */ + rule_dup = db_rule_dup(rule); + if (rule_dup == NULL) + return -ENOMEM; + + /* translate the syscall */ + rc = arch_syscall_translate(db->arch, &rule_dup->syscall); + if (rc < 0) + goto rule_add_return; + syscall = rule_dup->syscall; + + /* add the new rule to the existing filter */ + if (syscall == -1 || db->arch->rule_add == NULL) { + /* syscalls < -1 require a db->arch->rule_add() function */ + if (syscall < -1 && rule_dup->strict) { + rc = -EDOM; + goto rule_add_return; + } + rc = db_rule_add(db, rule_dup); + } else + rc = (db->arch->rule_add)(db, rule_dup); + +rule_add_return: + /* NOTE: another reminder that we don't do any db error recovery here, + * use the transaction mechanism as previously mentioned */ + if (rule_dup != NULL) + free(rule_dup); + return rc; +} diff --git a/src/arch.h b/src/arch.h new file mode 100644 index 0000000..9816274 --- /dev/null +++ b/src/arch.h @@ -0,0 +1,122 @@ +/** + * Enhanced Seccomp Architecture/Machine Specific Code + * + * Copyright (c) 2012 Red Hat <pmoore@redhat.com> + * Author: Paul Moore <paul@paul-moore.com> + */ + +/* + * 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>. + */ + +#ifndef _ARCH_H +#define _ARCH_H + +#include <inttypes.h> +#include <stddef.h> +#include <stdbool.h> + +#include <seccomp.h> + +#include "system.h" + +struct db_filter; +struct db_api_arg; +struct db_api_rule_list; + +struct arch_def { + /* arch definition */ + uint32_t token; + uint32_t token_bpf; + enum { + ARCH_SIZE_UNSPEC = 0, + ARCH_SIZE_32 = 32, + ARCH_SIZE_64 = 64, + } size; + enum { + ARCH_ENDIAN_UNSPEC = 0, + ARCH_ENDIAN_LITTLE, + ARCH_ENDIAN_BIG, + } endian; + + /* arch specific constants */ + int sys_socketcall; + int sys_ipc; + + /* arch specific functions */ + int (*syscall_resolve_name)(const struct arch_def *arch, + const char *name); + int (*syscall_resolve_name_raw)(const char *name); + const char *(*syscall_resolve_num)(const struct arch_def *arch, + int num); + const char *(*syscall_resolve_num_raw)(int num); + int (*syscall_rewrite)(const struct arch_def *arch, int *syscall); + int (*rule_add)(struct db_filter *db, struct db_api_rule_list *rule); +}; + +/* arch_def for the current architecture */ +extern const struct arch_def *arch_def_native; + +/* macro to declare the arch specific structures and functions */ +#define ARCH_DECL(NAME) \ + extern const struct arch_def arch_def_##NAME; \ + int NAME##_syscall_resolve_name(const char *name); \ + const char *NAME##_syscall_resolve_num(int num); \ + const struct arch_syscall_def *NAME##_syscall_iterate(unsigned int spot); + +/* macro to define the arch specific structures and functions */ +#define ARCH_DEF(NAME) \ + int NAME##_syscall_resolve_name(const char *name) \ + { \ + return syscall_resolve_name(name, OFFSET_ARCH(NAME)); \ + } \ + const char *NAME##_syscall_resolve_num(int num) \ + { \ + return syscall_resolve_num(num, OFFSET_ARCH(NAME)); \ + } \ + const struct arch_syscall_def *NAME##_syscall_iterate(unsigned int spot) \ + { \ + return syscall_iterate(spot, OFFSET_ARCH(NAME)); \ + } + +/* syscall name/num mapping */ +struct arch_syscall_def { + const char *name; + unsigned int num; +}; + +#define DATUM_MAX ((scmp_datum_t)-1) +#define D64_LO(x) ((uint32_t)((uint64_t)(x) & 0x00000000ffffffff)) +#define D64_HI(x) ((uint32_t)((uint64_t)(x) >> 32)) + +#define ARG_COUNT_MAX 6 + +int arch_valid(uint32_t arch); + +const struct arch_def *arch_def_lookup(uint32_t token); +const struct arch_def *arch_def_lookup_name(const char *arch_name); + +int arch_arg_offset_lo(const struct arch_def *arch, unsigned int arg); +int arch_arg_offset_hi(const struct arch_def *arch, unsigned int arg); +int arch_arg_offset(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_rule_add(struct db_filter *db, + const struct db_api_rule_list *rule); + +#endif diff --git a/src/db.c b/src/db.c new file mode 100644 index 0000000..836171a --- /dev/null +++ b/src/db.c @@ -0,0 +1,2620 @@ +/** + * Enhanced Seccomp Filter DB + * + * Copyright (c) 2012,2016,2018 Red Hat <pmoore@redhat.com> + * Copyright (c) 2019 Cisco Systems, Inc. <pmoore2@cisco.com> + * Author: Paul Moore <paul@paul-moore.com> + */ + +/* + * 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 <assert.h> +#include <errno.h> +#include <inttypes.h> +#include <stdlib.h> +#include <string.h> +#include <stdarg.h> + +#include <seccomp.h> + +#include "arch.h" +#include "db.h" +#include "system.h" +#include "helper.h" + +/* state values */ +#define _DB_STA_VALID 0xA1B2C3D4 +#define _DB_STA_FREED 0x1A2B3C4D + +/* the priority field is fairly simple - without any user hints, or in the case + * of a hint "tie", we give higher priority to syscalls with less chain nodes + * (filter is easier to evaluate) */ +#define _DB_PRI_MASK_CHAIN 0x0000FFFF +#define _DB_PRI_MASK_USER 0x00FF0000 +#define _DB_PRI_USER(x) (((x) << 16) & _DB_PRI_MASK_USER) + +/* prove information about the sub-tree check results */ +struct db_iter_state { +#define _DB_IST_NONE 0x00000000 +#define _DB_IST_MATCH 0x00000001 +#define _DB_IST_MATCH_ONCE 0x00000002 +#define _DB_IST_X_FINISHED 0x00000010 +#define _DB_IST_N_FINISHED 0x00000020 +#define _DB_IST_X_PREFIX 0x00000100 +#define _DB_IST_N_PREFIX 0x00000200 +#define _DB_IST_M_MATCHSET (_DB_IST_MATCH|_DB_IST_MATCH_ONCE) +#define _DB_IST_M_REDUNDANT (_DB_IST_MATCH| \ + _DB_IST_X_FINISHED| \ + _DB_IST_N_PREFIX) + unsigned int flags; + uint32_t action; + struct db_sys_list *sx; +}; + +static unsigned int _db_node_put(struct db_arg_chain_tree **node); + +/** + * Define the syscall argument priority for nodes on the same level of the tree + * @param a tree node + * + * Prioritize the syscall argument value, taking into account hi/lo words. + * Should only ever really be called by _db_chain_{lt,eq}(). Returns an + * arbitrary value indicating priority. + * + */ +static unsigned int __db_chain_arg_priority(const struct db_arg_chain_tree *a) +{ + return (a->arg << 1) + (a->arg_h_flg ? 1 : 0); +} + +/** + * Define the "op" priority for nodes on the same level of the tree + * @param op the argument operator + * + * Prioritize the syscall argument comparison operator. Should only ever + * really be called by _db_chain_{lt,eq}(). Returns an arbitrary value + * indicating priority. + * + */ +static unsigned int __db_chain_op_priority(enum scmp_compare op) +{ + /* the distinction between LT/LT and GT/GE is mostly to make the + * ordering as repeatable as possible regardless of the order in which + * the rules are added */ + switch (op) { + case SCMP_CMP_MASKED_EQ: + case SCMP_CMP_EQ: + case SCMP_CMP_NE: + return 3; + case SCMP_CMP_LE: + case SCMP_CMP_LT: + return 2; + case SCMP_CMP_GE: + case SCMP_CMP_GT: + return 1; + default: + return 0; + } +} + +/** + * Determine if node "a" is less than node "b" + * @param a tree node + * @param b tree node + * + * The logic is best explained by looking at the comparison code in the + * function. + * + */ +static bool _db_chain_lt(const struct db_arg_chain_tree *a, + const struct db_arg_chain_tree *b) +{ + unsigned int a_arg, b_arg; + unsigned int a_op, b_op; + + a_arg = __db_chain_arg_priority(a); + b_arg = __db_chain_arg_priority(b); + if (a_arg < b_arg) + return true; + else if (a_arg > b_arg) + return false; + + a_op = __db_chain_op_priority(a->op_orig); + b_op = __db_chain_op_priority(b->op_orig); + if (a_op < b_op) + return true; + else if (a_op > b_op) + return false; + + /* NOTE: at this point the arg and op priorities are equal */ + + switch (a->op_orig) { + case SCMP_CMP_LE: + case SCMP_CMP_LT: + /* in order to ensure proper ordering for LT/LE comparisons we + * need to invert the argument value so smaller values come + * first */ + if (a->datum > b->datum) + return true; + break; + default: + if (a->datum < b->datum) + return true; + break; + } + + return false; +} + +/** + * Determine if two nodes have equal argument datum values + * @param a tree node + * @param b tree node + * + * In order to return true the nodes must have the same datum and mask for the + * same argument. + * + */ +static bool _db_chain_eq(const struct db_arg_chain_tree *a, + const struct db_arg_chain_tree *b) +{ + unsigned int a_arg, b_arg; + + a_arg = __db_chain_arg_priority(a); + b_arg = __db_chain_arg_priority(b); + + return ((a_arg == b_arg) && (a->op == b->op) && + (a->datum == b->datum) && (a->mask == b->mask)); +} + +/** + * Determine if a given tree node is a leaf node + * @param iter the node to test + * + * A leaf node is a node with no other nodes beneath it. + * + */ +static bool _db_chain_leaf(const struct db_arg_chain_tree *iter) +{ + return (iter->nxt_t == NULL && iter->nxt_f == NULL); +} + +/** + * Determine if a given tree node is a zombie node + * @param iter the node to test + * + * A zombie node is a leaf node that also has no true or false actions. + * + */ +static bool _db_chain_zombie(const struct db_arg_chain_tree *iter) +{ + return (_db_chain_leaf(iter) && + !(iter->act_t_flg) && !(iter->act_f_flg)); +} + +/** + * Get a node reference + * @param node pointer to a node + * + * This function gets a reference to an individual node. Returns a pointer + * to the node. + * + */ +static struct db_arg_chain_tree *_db_node_get(struct db_arg_chain_tree *node) +{ + if (node != NULL) + node->refcnt++; + return node; +} + +/** + * Garbage collect a level of the tree + * @param node tree node + * + * Check the entire level on which @node resides, if there is no other part of + * the tree which points to a node on this level, remove the entire level. + * Returns the number of nodes removed. + * + */ +static unsigned int _db_level_clean(struct db_arg_chain_tree *node) +{ + int cnt = 0; + unsigned int links; + struct db_arg_chain_tree *n = node; + struct db_arg_chain_tree *start; + + while (n->lvl_prv) + n = n->lvl_prv; + start = n; + + while (n != NULL) { + links = 0; + if (n->lvl_prv) + links++; + if (n->lvl_nxt) + links++; + + if (n->refcnt > links) + return cnt; + + n = n->lvl_nxt; + } + + n = start; + while (n != NULL) + cnt += _db_node_put(&n); + + return cnt; +} + +/** + * Free a syscall filter argument chain tree + * @param tree the argument chain list + * + * This function drops a reference to the tree pointed to by @tree and garbage + * collects the top level. Returns the number of nodes removed. + * + */ +static unsigned int _db_tree_put(struct db_arg_chain_tree **tree) +{ + unsigned int cnt; + + cnt = _db_node_put(tree); + if (*tree) + cnt += _db_level_clean(*tree); + + return cnt; +} + +/** + * Release a node reference + * @param node pointer to a node + * + * This function drops a reference to an individual node, unless this is the + * last reference in which the entire sub-tree is affected. Returns the number + * of nodes freed. + * + */ +static unsigned int _db_node_put(struct db_arg_chain_tree **node) +{ + unsigned int cnt = 0; + struct db_arg_chain_tree *n = *node; + struct db_arg_chain_tree *lvl_p, *lvl_n, *nxt_t, *nxt_f; + + if (n == NULL) + return 0; + + if (--(n->refcnt) == 0) { + lvl_p = n->lvl_prv; + lvl_n = n->lvl_nxt; + nxt_t = n->nxt_t; + nxt_f = n->nxt_f; + + /* split the current level */ + /* NOTE: we still hold a ref for both lvl_p and lvl_n */ + if (lvl_p) + lvl_p->lvl_nxt = NULL; + if (lvl_n) + lvl_n->lvl_prv = NULL; + + /* drop refcnts on the current level */ + if (lvl_p) + cnt += _db_node_put(&lvl_p); + if (lvl_n) + cnt += _db_node_put(&lvl_n); + + /* re-link current level if it still exists */ + if (lvl_p) + lvl_p->lvl_nxt = _db_node_get(lvl_n); + if (lvl_n) + lvl_n->lvl_prv = _db_node_get(lvl_p); + + /* update caller's pointer */ + if (lvl_p) + *node = lvl_p; + else if (lvl_n) + *node = lvl_n; + else + *node = NULL; + + /* drop the next level(s) */ + cnt += _db_tree_put(&nxt_t); + cnt += _db_tree_put(&nxt_f); + + /* cleanup and accounting */ + free(n); + cnt++; + } + + return cnt; +} + +/** + * Remove a node from an argument chain tree + * @param tree the pointer to the tree + * @param node the node to remove + * + * This function searches the tree looking for the node and removes it as well + * as any sub-trees beneath it. Returns the number of nodes freed. + * + */ +static unsigned int _db_tree_remove(struct db_arg_chain_tree **tree, + struct db_arg_chain_tree *node) +{ + int cnt = 0; + struct db_arg_chain_tree *c_iter; + + if (tree == NULL || *tree == NULL || node == NULL) + return 0; + + c_iter = *tree; + while (c_iter->lvl_prv != NULL) + c_iter = c_iter->lvl_prv; + + do { + /* current node? */ + if (c_iter == node) + goto remove; + + /* check the sub-trees */ + cnt += _db_tree_remove(&(c_iter->nxt_t), node); + cnt += _db_tree_remove(&(c_iter->nxt_f), node); + + /* check for empty/zombie nodes */ + if (_db_chain_zombie(c_iter)) + goto remove; + + /* next node on this level */ + c_iter = c_iter->lvl_nxt; + } while (c_iter != NULL && cnt == 0); + + return cnt; + +remove: + /* reset the tree pointer if needed */ + if (c_iter == *tree) { + if (c_iter->lvl_prv != NULL) + *tree = c_iter->lvl_prv; + else + *tree = c_iter->lvl_nxt; + } + + /* remove the node from the current level */ + if (c_iter->lvl_prv) + c_iter->lvl_prv->lvl_nxt = c_iter->lvl_nxt; + if (c_iter->lvl_nxt) + c_iter->lvl_nxt->lvl_prv = c_iter->lvl_prv; + c_iter->lvl_prv = NULL; + c_iter->lvl_nxt = NULL; + + /* free the node and any sub-trees */ + cnt += _db_node_put(&c_iter); + + return cnt; +} + +/** + * Traverse a tree checking the action values + * @param tree the pointer to the tree + * @param action the action + * + * Traverse the tree inspecting each action to see if it matches the given + * action. Returns zero if all actions match the given action, negative values + * on failure. + * + */ +static int _db_tree_act_check(struct db_arg_chain_tree *tree, uint32_t action) +{ + int rc; + struct db_arg_chain_tree *c_iter; + + if (tree == NULL) + return 0; + + c_iter = tree; + while (c_iter->lvl_prv != NULL) + c_iter = c_iter->lvl_prv; + + do { + if (c_iter->act_t_flg && c_iter->act_t != action) + return -EEXIST; + if (c_iter->act_f_flg && c_iter->act_f != action) + return -EEXIST; + + rc = _db_tree_act_check(c_iter->nxt_t, action); + if (rc < 0) + return rc; + rc = _db_tree_act_check(c_iter->nxt_f, action); + if (rc < 0) + return rc; + + c_iter = c_iter->lvl_nxt; + } while (c_iter != NULL); + + return 0; +} + +/** + * Checks for a sub-tree match in an existing tree and prunes the tree + * @param existing pointer to the existing tree + * @param new pointer to the new tree + * @param state pointer to a state structure + * + * This function searches the existing tree trying to prune it based on the + * new tree. Returns the number of nodes removed from the tree on success, + * zero if no changes were made. + * + */ +static int _db_tree_prune(struct db_arg_chain_tree **existing, + struct db_arg_chain_tree *new, + struct db_iter_state *state) +{ + int cnt = 0; + struct db_iter_state state_nxt; + struct db_iter_state state_new = *state; + struct db_arg_chain_tree *x_iter_next; + struct db_arg_chain_tree *x_iter = *existing; + struct db_arg_chain_tree *n_iter = new; + + /* check if either tree is finished */ + if (n_iter == NULL || x_iter == NULL) + goto prune_return; + + /* bail out if we have a broken match */ + if ((state->flags & _DB_IST_M_MATCHSET) == _DB_IST_MATCH_ONCE) + goto prune_return; + + /* get to the start of the existing level */ + while (x_iter->lvl_prv) + x_iter = x_iter->lvl_prv; + + /* NOTE: a few comments on the code below ... + * 1) we need to take a reference before we go down a level in case + * we end up dropping the sub-tree (see the _db_node_get() calls) + * 2) since the new tree really only has one branch, we can only ever + * match on one branch in the existing tree, if we "hit" then we + * can bail on the other branches */ + + do { + /* store this now in case we remove x_iter */ + x_iter_next = x_iter->lvl_nxt; + + /* compare the two nodes */ + if (_db_chain_eq(x_iter, n_iter)) { + /* we have a match */ + state_new.flags |= _DB_IST_M_MATCHSET; + + /* check if either tree is finished */ + if (_db_chain_leaf(n_iter)) + state_new.flags |= _DB_IST_N_FINISHED; + if (_db_chain_leaf(x_iter)) + state_new.flags |= _DB_IST_X_FINISHED; + + /* don't remove nodes if we have more actions/levels */ + if ((x_iter->act_t_flg || x_iter->nxt_t) && + !(n_iter->act_t_flg || n_iter->nxt_t)) + goto prune_return; + if ((x_iter->act_f_flg || x_iter->nxt_f) && + !(n_iter->act_f_flg || n_iter->nxt_f)) + goto prune_return; + + /* if finished, compare actions */ + if ((state_new.flags & _DB_IST_N_FINISHED) && + (state_new.flags & _DB_IST_X_FINISHED)) { + if (n_iter->act_t_flg != x_iter->act_t_flg) + goto prune_return; + if (n_iter->act_t != x_iter->act_t) + goto prune_return; + + if (n_iter->act_f_flg != x_iter->act_f_flg) + goto prune_return; + if (n_iter->act_f != x_iter->act_f) + goto prune_return; + } + + /* check next level */ + if (n_iter->nxt_t) { + _db_node_get(x_iter); + state_nxt = *state; + state_nxt.flags |= _DB_IST_M_MATCHSET; + cnt += _db_tree_prune(&x_iter->nxt_t, + n_iter->nxt_t, + &state_nxt); + cnt += _db_node_put(&x_iter); + if (state_nxt.flags & _DB_IST_MATCH) { + state_new.flags |= state_nxt.flags; + /* don't return yet, we need to check + * the current node */ + } + if (x_iter == NULL) + goto prune_next_node; + } + if (n_iter->nxt_f) { + _db_node_get(x_iter); + state_nxt = *state; + state_nxt.flags |= _DB_IST_M_MATCHSET; + cnt += _db_tree_prune(&x_iter->nxt_f, + n_iter->nxt_f, + &state_nxt); + cnt += _db_node_put(&x_iter); + if (state_nxt.flags & _DB_IST_MATCH) { + state_new.flags |= state_nxt.flags; + /* don't return yet, we need to check + * the current node */ + } + if (x_iter == NULL) + goto prune_next_node; + } + + /* remove the node? */ + if (!_db_tree_act_check(x_iter, state_new.action) && + (state_new.flags & _DB_IST_MATCH) && + (state_new.flags & _DB_IST_N_FINISHED) && + (state_new.flags & _DB_IST_X_PREFIX)) { + /* yes - the new tree is "shorter" */ + cnt += _db_tree_remove(&state->sx->chains, + x_iter); + if (state->sx->chains == NULL) + goto prune_return; + } else if (!_db_tree_act_check(x_iter, state_new.action) + && (state_new.flags & _DB_IST_MATCH) && + (state_new.flags & _DB_IST_X_FINISHED) && + (state_new.flags & _DB_IST_N_PREFIX)) { + /* no - the new tree is "longer" */ + goto prune_return; + } + } else if (_db_chain_lt(x_iter, n_iter)) { + /* bail if we have a prefix on the new tree */ + if (state->flags & _DB_IST_N_PREFIX) + goto prune_return; + + /* check the next level in the existing tree */ + if (x_iter->nxt_t) { + _db_node_get(x_iter); + state_nxt = *state; + state_nxt.flags &= ~_DB_IST_MATCH; + state_nxt.flags |= _DB_IST_X_PREFIX; + cnt += _db_tree_prune(&x_iter->nxt_t, n_iter, + &state_nxt); + cnt += _db_node_put(&x_iter); + if (state_nxt.flags & _DB_IST_MATCH) { + state_new.flags |= state_nxt.flags; + goto prune_return; + } + if (x_iter == NULL) + goto prune_next_node; + } + if (x_iter->nxt_f) { + _db_node_get(x_iter); + state_nxt = *state; + state_nxt.flags &= ~_DB_IST_MATCH; + state_nxt.flags |= _DB_IST_X_PREFIX; + cnt += _db_tree_prune(&x_iter->nxt_f, n_iter, + &state_nxt); + cnt += _db_node_put(&x_iter); + if (state_nxt.flags & _DB_IST_MATCH) { + state_new.flags |= state_nxt.flags; + goto prune_return; + } + if (x_iter == NULL) + goto prune_next_node; + } + } else { + /* bail if we have a prefix on the existing tree */ + if (state->flags & _DB_IST_X_PREFIX) + goto prune_return; + + /* check the next level in the new tree */ + if (n_iter->nxt_t) { + _db_node_get(x_iter); + state_nxt = *state; + state_nxt.flags &= ~_DB_IST_MATCH; + state_nxt.flags |= _DB_IST_N_PREFIX; + cnt += _db_tree_prune(&x_iter, n_iter->nxt_t, + &state_nxt); + cnt += _db_node_put(&x_iter); + if (state_nxt.flags & _DB_IST_MATCH) { + state_new.flags |= state_nxt.flags; + goto prune_return; + } + if (x_iter == NULL) + goto prune_next_node; + } + if (n_iter->nxt_f) { + _db_node_get(x_iter); + state_nxt = *state; + state_nxt.flags &= ~_DB_IST_MATCH; + state_nxt.flags |= _DB_IST_N_PREFIX; + cnt += _db_tree_prune(&x_iter, n_iter->nxt_f, + &state_nxt); + cnt += _db_node_put(&x_iter); + if (state_nxt.flags & _DB_IST_MATCH) { + state_new.flags |= state_nxt.flags; + goto prune_return; + } + if (x_iter == NULL) + goto prune_next_node; + } + } + +prune_next_node: + /* check next node on this level */ + x_iter = x_iter_next; + } while (x_iter); + + // if we are falling through, we clearly didn't match on anything + state_new.flags &= ~_DB_IST_MATCH; + +prune_return: + /* no more nodes on this level, return to the level above */ + if (state_new.flags & _DB_IST_MATCH) + state->flags |= state_new.flags; + else + state->flags &= ~_DB_IST_MATCH; + return cnt; +} + +/** + * Add a new tree into an existing tree + * @param existing pointer to the existing tree + * @param new pointer to the new tree + * @param state pointer to a state structure + * + * This function adds the new tree into the existing tree, fetching additional + * references as necessary. Returns zero on success, negative values on + * failure. + * + */ +static int _db_tree_add(struct db_arg_chain_tree **existing, + struct db_arg_chain_tree *new, + struct db_iter_state *state) +{ + int rc; + struct db_arg_chain_tree *x_iter = *existing; + struct db_arg_chain_tree *n_iter = new; + + do { + if (_db_chain_eq(x_iter, n_iter)) { + if (n_iter->act_t_flg) { + if (!x_iter->act_t_flg) { + /* new node has a true action */ + + /* do the actions match? */ + rc = _db_tree_act_check(x_iter->nxt_t, + n_iter->act_t); + if (rc != 0) + return rc; + + /* update with the new action */ + rc = _db_node_put(&x_iter->nxt_t); + x_iter->nxt_t = NULL; + x_iter->act_t = n_iter->act_t; + x_iter->act_t_flg = true; + state->sx->node_cnt -= rc; + } else if (n_iter->act_t != x_iter->act_t) { + /* if we are dealing with a 64-bit + * comparison, we need to adjust our + * action based on the full 64-bit + * value to ensure we handle GT/GE + * comparisons correctly */ + if (n_iter->arg_h_flg && + (n_iter->datum_full > + x_iter->datum_full)) + x_iter->act_t = n_iter->act_t; + if (_db_chain_leaf(x_iter) || + _db_chain_leaf(n_iter)) + return -EEXIST; + } + } + if (n_iter->act_f_flg) { + if (!x_iter->act_f_flg) { + /* new node has a false action */ + + /* do the actions match? */ + rc = _db_tree_act_check(x_iter->nxt_f, + n_iter->act_f); + if (rc != 0) + return rc; + + /* update with the new action */ + rc = _db_node_put(&x_iter->nxt_f); + x_iter->nxt_f = NULL; + x_iter->act_f = n_iter->act_f; + x_iter->act_f_flg = true; + state->sx->node_cnt -= rc; + } else if (n_iter->act_f != x_iter->act_f) { + /* if we are dealing with a 64-bit + * comparison, we need to adjust our + * action based on the full 64-bit + * value to ensure we handle LT/LE + * comparisons correctly */ + if (n_iter->arg_h_flg && + (n_iter->datum_full < + x_iter->datum_full)) + x_iter->act_t = n_iter->act_t; + if (_db_chain_leaf(x_iter) || + _db_chain_leaf(n_iter)) + return -EEXIST; + } + } + + if (n_iter->nxt_t) { + if (x_iter->nxt_t) { + /* compare the next level */ + rc = _db_tree_add(&x_iter->nxt_t, + n_iter->nxt_t, + state); + if (rc != 0) + return rc; + } else if (!x_iter->act_t_flg) { + /* add a new sub-tree */ + x_iter->nxt_t = _db_node_get(n_iter->nxt_t); + } else + /* done - existing tree is "shorter" */ + return 0; + } + if (n_iter->nxt_f) { + if (x_iter->nxt_f) { + /* compare the next level */ + rc = _db_tree_add(&x_iter->nxt_f, + n_iter->nxt_f, + state); + if (rc != 0) + return rc; + } else if (!x_iter->act_f_flg) { + /* add a new sub-tree */ + x_iter->nxt_f = _db_node_get(n_iter->nxt_f); + } else + /* done - existing tree is "shorter" */ + return 0; + } + + return 0; + } else if (!_db_chain_lt(x_iter, n_iter)) { + /* try to move along the current level */ + if (x_iter->lvl_nxt == NULL) { + /* add to the end of this level */ + n_iter->lvl_prv = _db_node_get(x_iter); + x_iter->lvl_nxt = _db_node_get(n_iter); + return 0; + } else + /* next */ + x_iter = x_iter->lvl_nxt; + } else { + /* add before the existing node on this level*/ + if (x_iter->lvl_prv != NULL) { + x_iter->lvl_prv->lvl_nxt = _db_node_get(n_iter); + n_iter->lvl_prv = x_iter->lvl_prv; + x_iter->lvl_prv = _db_node_get(n_iter); + n_iter->lvl_nxt = x_iter; + } else { + x_iter->lvl_prv = _db_node_get(n_iter); + n_iter->lvl_nxt = _db_node_get(x_iter); + } + if (*existing == x_iter) { + *existing = _db_node_get(n_iter); + _db_node_put(&x_iter); + } + return 0; + } + } while (x_iter); + + return 0; +} + +/** + * Free and reset the seccomp filter DB + * @param db the seccomp filter DB + * + * This function frees any existing filters and resets the filter DB to a + * default state; only the DB architecture is preserved. + * + */ +static void _db_reset(struct db_filter *db) +{ + struct db_sys_list *s_iter; + struct db_api_rule_list *r_iter; + + if (db == NULL) + return; + + /* free any filters */ + if (db->syscalls != NULL) { + s_iter = db->syscalls; + while (s_iter != NULL) { + db->syscalls = s_iter->next; + _db_tree_put(&s_iter->chains); + free(s_iter); + s_iter = db->syscalls; + } + db->syscalls = NULL; + } + db->syscall_cnt = 0; + + /* free any rules */ + if (db->rules != NULL) { + /* split the loop first then loop and free */ + db->rules->prev->next = NULL; + r_iter = db->rules; + while (r_iter != NULL) { + db->rules = r_iter->next; + free(r_iter); + r_iter = db->rules; + } + db->rules = NULL; + } +} + +/** + * Intitalize a seccomp filter DB + * @param arch the architecture definition + * + * This function initializes a seccomp filter DB and readies it for use. + * Returns a pointer to the DB on success, NULL on failure. + * + */ +static struct db_filter *_db_init(const struct arch_def *arch) +{ + struct db_filter *db; + + db = zmalloc(sizeof(*db)); + if (db == NULL) + return NULL; + + /* set the arch and reset the DB to a known state */ + db->arch = arch; + _db_reset(db); + + return db; +} + +/** + * Destroy a seccomp filter DB + * @param db the seccomp filter DB + * + * This function destroys a seccomp filter DB. After calling this function, + * the filter should no longer be referenced. + * + */ +static void _db_release(struct db_filter *db) +{ + if (db == NULL) + return; + + /* free and reset the DB */ + _db_reset(db); + free(db); +} + +/** + * Destroy a seccomp filter snapshot + * @param snap the seccomp filter snapshot + * + * This function destroys a seccomp filter snapshot. After calling this + * function, the snapshot should no longer be referenced. + * + */ +static void _db_snap_release(struct db_filter_snap *snap) +{ + unsigned int iter; + + if (snap == NULL) + return; + + if (snap->filter_cnt > 0) { + for (iter = 0; iter < snap->filter_cnt; iter++) { + if (snap->filters[iter]) + _db_release(snap->filters[iter]); + } + free(snap->filters); + } + free(snap); +} + +/** + * Update the user specified portion of the syscall priority + * @param db the seccomp filter db + * @param syscall the syscall number + * @param priority the syscall priority + * + * This function sets, or updates, the syscall priority; the highest priority + * value between the existing and specified value becomes the new syscall + * priority. If the syscall entry does not already exist, a new phantom + * syscall entry is created as a placeholder. Returns zero on success, + * negative values on failure. + * + */ +static int _db_syscall_priority(struct db_filter *db, + int syscall, uint8_t priority) +{ + unsigned int sys_pri = _DB_PRI_USER(priority); + struct db_sys_list *s_new, *s_iter, *s_prev = NULL; + + assert(db != NULL); + + s_iter = db->syscalls; + while (s_iter != NULL && s_iter->num < syscall) { + s_prev = s_iter; + s_iter = s_iter->next; + } + + /* matched an existing syscall entry */ + if (s_iter != NULL && s_iter->num == syscall) { + if (sys_pri > (s_iter->priority & _DB_PRI_MASK_USER)) { + s_iter->priority &= (~_DB_PRI_MASK_USER); + s_iter->priority |= sys_pri; + } + return 0; + } + + /* no existing syscall entry - create a phantom entry */ + s_new = zmalloc(sizeof(*s_new)); + if (s_new == NULL) + return -ENOMEM; + s_new->num = syscall; + s_new->priority = sys_pri; + s_new->valid = false; + + /* add it before s_iter */ + if (s_prev != NULL) { + s_new->next = s_prev->next; + s_prev->next = s_new; + } else { + s_new->next = db->syscalls; + db->syscalls = s_new; + } + + return 0; +} + +/** + * Create a new rule + * @param strict the strict value + * @param action the rule's action + * @param syscall the syscall number + * @param chain the syscall argument filter + * + * This function creates a new rule structure based on the given arguments. + * Returns a pointer to the new rule on success, NULL on failure. + * + */ +static struct db_api_rule_list *_db_rule_new(bool strict, + uint32_t action, int syscall, + struct db_api_arg *chain) +{ + struct db_api_rule_list *rule; + + rule = zmalloc(sizeof(*rule)); + if (rule == NULL) + return NULL; + rule->action = action; + rule->syscall = syscall; + rule->strict = strict; + memcpy(rule->args, chain, sizeof(*chain) * ARG_COUNT_MAX); + + return rule; +} + +/** + * Duplicate an existing filter rule + * @param src the rule to duplicate + * + * This function makes an exact copy of the given rule, but does not add it + * to any lists. Returns a pointer to the new rule on success, NULL on + * failure. + * + */ +struct db_api_rule_list *db_rule_dup(const struct db_api_rule_list *src) +{ + struct db_api_rule_list *dest; + + dest = malloc(sizeof(*dest)); + if (dest == NULL) + return NULL; + memcpy(dest, src, sizeof(*dest)); + dest->prev = NULL; + dest->next = NULL; + + return dest; +} + +/** + * Free and reset the seccomp filter collection + * @param col the seccomp filter collection + * @param def_action the default filter action + * + * This function frees any existing filter DBs and resets the collection to a + * default state. In the case of failure the filter collection may be in an + * unknown state and should be released. Returns zero on success, negative + * values on failure. + * + */ +int db_col_reset(struct db_filter_col *col, uint32_t def_action) +{ + unsigned int iter; + struct db_filter *db; + struct db_filter_snap *snap; + + if (col == NULL) + return -EINVAL; + + /* free any filters */ + for (iter = 0; iter < col->filter_cnt; iter++) + _db_release(col->filters[iter]); + col->filter_cnt = 0; + if (col->filters) + free(col->filters); + col->filters = NULL; + + /* set the endianess to undefined */ + col->endian = 0; + + /* set the default attribute values */ + col->attr.act_default = def_action; + col->attr.act_badarch = SCMP_ACT_KILL; + col->attr.nnp_enable = 1; + col->attr.tsync_enable = 0; + col->attr.api_tskip = 0; + col->attr.log_enable = 0; + col->attr.spec_allow = 0; + col->attr.optimize = 1; + col->attr.api_sysrawrc = 0; + + /* set the state */ + col->state = _DB_STA_VALID; + if (def_action == SCMP_ACT_NOTIFY) + col->notify_used = true; + else + col->notify_used = false; + + /* reset the initial db */ + db = _db_init(arch_def_native); + if (db == NULL) + return -ENOMEM; + if (db_col_db_add(col, db) < 0) { + _db_release(db); + return -ENOMEM; + } + + /* reset the transactions */ + while (col->snapshots) { + snap = col->snapshots; + col->snapshots = snap->next; + for (iter = 0; iter < snap->filter_cnt; iter++) + _db_release(snap->filters[iter]); + free(snap->filters); + free(snap); + } + + return 0; +} + +/** + * Intitalize a seccomp filter collection + * @param def_action the default filter action + * + * This function initializes a seccomp filter collection and readies it for + * use. Returns a pointer to the collection on success, NULL on failure. + * + */ +struct db_filter_col *db_col_init(uint32_t def_action) +{ + struct db_filter_col *col; + + col = zmalloc(sizeof(*col)); + if (col == NULL) + return NULL; + + /* reset the DB to a known state */ + if (db_col_reset(col, def_action) < 0) + goto init_failure; + + return col; + +init_failure: + db_col_release(col); + return NULL; +} + +/** + * Destroy a seccomp filter collection + * @param col the seccomp filter collection + * + * This function destroys a seccomp filter collection. After calling this + * function, the filter should no longer be referenced. + * + */ +void db_col_release(struct db_filter_col *col) +{ + unsigned int iter; + struct db_filter_snap *snap; + + if (col == NULL) + return; + + /* set the state, just in case */ + col->state = _DB_STA_FREED; + + /* free any snapshots */ + while (col->snapshots != NULL) { + snap = col->snapshots; + col->snapshots = snap->next; + _db_snap_release(snap); + } + + /* free any filters */ + for (iter = 0; iter < col->filter_cnt; iter++) + _db_release(col->filters[iter]); + col->filter_cnt = 0; + if (col->filters) + free(col->filters); + col->filters = NULL; + + /* free the collection */ + free(col); +} + +/** + * Validate a filter collection + * @param col the seccomp filter collection + * + * This function validates a seccomp filter collection. Returns zero if the + * collection is valid, negative values on failure. + * + */ +int db_col_valid(struct db_filter_col *col) +{ + if (col != NULL && col->state == _DB_STA_VALID && col->filter_cnt > 0) + return 0; + return -EINVAL; +} + +/** + * Validate the seccomp action + * @param col the seccomp filter collection + * @param action the seccomp action + * + * Verify that the given action is a valid seccomp action; return zero if + * valid, -EINVAL if invalid. + */ +int db_col_action_valid(const struct db_filter_col *col, uint32_t action) +{ + if (col != NULL) { + /* NOTE: in some cases we don't have a filter collection yet, + * but when we do we need to do the following checks */ + + /* kernel disallows TSYNC and NOTIFY in one filter unless we + * have the TSYNC_ESRCH flag */ + if (sys_chk_seccomp_flag(SECCOMP_FILTER_FLAG_TSYNC_ESRCH) < 1 && + col->attr.tsync_enable && action == SCMP_ACT_NOTIFY) + return -EINVAL; + } + + if (sys_chk_seccomp_action(action) == 1) + return 0; + return -EINVAL; +} + +/** + * Merge two filter collections + * @param col_dst the destination filter collection + * @param col_src the source filter collection + * + * This function merges two filter collections into the given destination + * collection. The source filter collection is no longer valid if the function + * returns successfully. Returns zero on success, negative values on failure. + * + */ +int db_col_merge(struct db_filter_col *col_dst, struct db_filter_col *col_src) +{ + unsigned int iter_a, iter_b; + struct db_filter **dbs; + + /* verify that the endianess is a match */ + if (col_dst->endian != col_src->endian) + return -EDOM; + + /* make sure we don't have any arch/filter collisions */ + for (iter_a = 0; iter_a < col_dst->filter_cnt; iter_a++) { + for (iter_b = 0; iter_b < col_src->filter_cnt; iter_b++) { + if (col_dst->filters[iter_a]->arch->token == + col_src->filters[iter_b]->arch->token) + return -EEXIST; + } + } + + /* expand the destination */ + dbs = realloc(col_dst->filters, + sizeof(struct db_filter *) * + (col_dst->filter_cnt + col_src->filter_cnt)); + if (dbs == NULL) + return -ENOMEM; + col_dst->filters = dbs; + + /* transfer the architecture filters */ + for (iter_a = col_dst->filter_cnt, iter_b = 0; + iter_b < col_src->filter_cnt; iter_a++, iter_b++) { + col_dst->filters[iter_a] = col_src->filters[iter_b]; + col_dst->filter_cnt++; + } + + /* free the source */ + col_src->filter_cnt = 0; + db_col_release(col_src); + + return 0; +} + +/** + * Check to see if an architecture filter exists in the filter collection + * @param col the seccomp filter collection + * @param arch_token the architecture token + * + * Iterate through the given filter collection checking to see if a filter + * exists for the specified architecture. Returns -EEXIST if a filter is found, + * zero if a matching filter does not exist. + * + */ +int db_col_arch_exist(struct db_filter_col *col, uint32_t arch_token) +{ + unsigned int iter; + + for (iter = 0; iter < col->filter_cnt; iter++) + if (col->filters[iter]->arch->token == arch_token) + return -EEXIST; + + return 0; +} + +/** + * Get a filter attribute + * @param col the seccomp filter collection + * @param attr the filter attribute + * @param value the filter attribute value + * + * Get the requested filter attribute and provide it via @value. Returns zero + * on success, negative values on failure. + * + */ +int db_col_attr_get(const struct db_filter_col *col, + enum scmp_filter_attr attr, uint32_t *value) +{ + int rc = 0; + + switch (attr) { + case SCMP_FLTATR_ACT_DEFAULT: + *value = col->attr.act_default; + break; + case SCMP_FLTATR_ACT_BADARCH: + *value = col->attr.act_badarch; + break; + case SCMP_FLTATR_CTL_NNP: + *value = col->attr.nnp_enable; + break; + case SCMP_FLTATR_CTL_TSYNC: + *value = col->attr.tsync_enable; + break; + case SCMP_FLTATR_API_TSKIP: + *value = col->attr.api_tskip; + break; + case SCMP_FLTATR_CTL_LOG: + *value = col->attr.log_enable; + break; + case SCMP_FLTATR_CTL_SSB: + *value = col->attr.spec_allow; + break; + case SCMP_FLTATR_CTL_OPTIMIZE: + *value = col->attr.optimize; + break; + case SCMP_FLTATR_API_SYSRAWRC: + *value = col->attr.api_sysrawrc; + break; + default: + rc = -EINVAL; + break; + } + + return rc; +} + +/** + * Get a filter attribute + * @param col the seccomp filter collection + * @param attr the filter attribute + * + * Returns the requested filter attribute value with zero on any error. + * Special care must be given with this function as error conditions can be + * hidden from the caller. + * + */ +uint32_t db_col_attr_read(const struct db_filter_col *col, + enum scmp_filter_attr attr) +{ + uint32_t value = 0; + + db_col_attr_get(col, attr, &value); + return value; +} + +/** + * Set a filter attribute + * @param col the seccomp filter collection + * @param attr the filter attribute + * @param value the filter attribute value + * + * Set the requested filter attribute with the given value. Returns zero on + * success, negative values on failure. + * + */ +int db_col_attr_set(struct db_filter_col *col, + enum scmp_filter_attr attr, uint32_t value) +{ + int rc = 0; + + switch (attr) { + case SCMP_FLTATR_ACT_DEFAULT: + /* read only */ + return -EACCES; + break; + case SCMP_FLTATR_ACT_BADARCH: + if (db_col_action_valid(col, value) == 0) + col->attr.act_badarch = value; + else + return -EINVAL; + break; + case SCMP_FLTATR_CTL_NNP: + col->attr.nnp_enable = (value ? 1 : 0); + break; + case SCMP_FLTATR_CTL_TSYNC: + rc = sys_chk_seccomp_flag(SECCOMP_FILTER_FLAG_TSYNC); + if (rc == 1) { + /* supported */ + rc = 0; + /* kernel disallows TSYNC and NOTIFY in one filter + * unless we have TSYNC_ESRCH */ + if (sys_chk_seccomp_flag(SECCOMP_FILTER_FLAG_TSYNC_ESRCH) < 1 && + value && col->notify_used) + return -EINVAL; + col->attr.tsync_enable = (value ? 1 : 0); + } else if (rc == 0) + /* unsupported */ + rc = -EOPNOTSUPP; + break; + case SCMP_FLTATR_API_TSKIP: + col->attr.api_tskip = (value ? 1 : 0); + break; + case SCMP_FLTATR_CTL_LOG: + rc = sys_chk_seccomp_flag(SECCOMP_FILTER_FLAG_LOG); + if (rc == 1) { + /* supported */ + rc = 0; + col->attr.log_enable = (value ? 1 : 0); + } else if (rc == 0) { + /* unsupported */ + rc = -EOPNOTSUPP; + } + break; + case SCMP_FLTATR_CTL_SSB: + rc = sys_chk_seccomp_flag(SECCOMP_FILTER_FLAG_SPEC_ALLOW); + if (rc == 1) { + /* supported */ + rc = 0; + col->attr.spec_allow = (value ? 1 : 0); + } else if (rc == 0) { + /* unsupported */ + rc = -EOPNOTSUPP; + } + break; + case SCMP_FLTATR_CTL_OPTIMIZE: + switch (value) { + case 1: + case 2: + col->attr.optimize = value; + break; + default: + rc = -EOPNOTSUPP; + break; + } + break; + case SCMP_FLTATR_API_SYSRAWRC: + col->attr.api_sysrawrc = (value ? 1 : 0); + break; + default: + rc = -EINVAL; + break; + } + + return rc; +} + +/** + * Add a new architecture filter to a filter collection + * @param col the seccomp filter collection + * @param arch the architecture + * + * This function adds a new architecture filter DB to an existing seccomp + * filter collection assuming there isn't a filter DB already present with the + * same architecture. Returns zero on success, negative values on failure. + * + */ +int db_col_db_new(struct db_filter_col *col, const struct arch_def *arch) +{ + int rc; + struct db_filter *db; + + db = _db_init(arch); + if (db == NULL) + return -ENOMEM; + rc = db_col_db_add(col, db); + if (rc < 0) + _db_release(db); + + return rc; +} + +/** + * Add a new filter DB to a filter collection + * @param col the seccomp filter collection + * @param db the seccomp filter DB + * + * This function adds an existing seccomp filter DB to an existing seccomp + * filter collection assuming there isn't a filter DB already present with the + * same architecture. Returns zero on success, negative values on failure. + * + */ +int db_col_db_add(struct db_filter_col *col, struct db_filter *db) +{ + struct db_filter **dbs; + + if (col->endian != 0 && col->endian != db->arch->endian) + return -EDOM; + + if (db_col_arch_exist(col, db->arch->token)) + return -EEXIST; + + dbs = realloc(col->filters, + sizeof(struct db_filter *) * (col->filter_cnt + 1)); + if (dbs == NULL) + return -ENOMEM; + col->filters = dbs; + col->filter_cnt++; + col->filters[col->filter_cnt - 1] = db; + if (col->endian == 0) + col->endian = db->arch->endian; + + return 0; +} + +/** + * Remove a filter DB from a filter collection + * @param col the seccomp filter collection + * @param arch_token the architecture token + * + * This function removes an existing seccomp filter DB from an existing seccomp + * filter collection. Returns zero on success, negative values on failure. + * + */ +int db_col_db_remove(struct db_filter_col *col, uint32_t arch_token) +{ + unsigned int iter; + unsigned int found; + struct db_filter **dbs; + + if ((col->filter_cnt <= 0) || (db_col_arch_exist(col, arch_token) == 0)) + return -EINVAL; + + for (found = 0, iter = 0; iter < col->filter_cnt; iter++) { + if (found) + col->filters[iter - 1] = col->filters[iter]; + else if (col->filters[iter]->arch->token == arch_token) { + _db_release(col->filters[iter]); + found = 1; + } + } + col->filters[--col->filter_cnt] = NULL; + + if (col->filter_cnt > 0) { + /* NOTE: if we can't do the realloc it isn't fatal, we just + * have some extra space allocated */ + dbs = realloc(col->filters, + sizeof(struct db_filter *) * col->filter_cnt); + if (dbs != NULL) + col->filters = dbs; + } else { + /* this was the last filter so free all the associated memory + * and reset the endian token */ + free(col->filters); + col->filters = NULL; + col->endian = 0; + } + + return 0; +} + +/** + * Test if the argument filter can be skipped because it's a tautology + * @param arg argument filter + * + * If this argument filter applied to the lower 32 bit can be skipped this + * function returns false. + * + */ +static bool _db_arg_cmp_need_lo(const struct db_api_arg *arg) +{ + if (arg->op == SCMP_CMP_MASKED_EQ && D64_LO(arg->mask) == 0) + return false; + + return true; +} + +/** + * Test if the argument filter can be skipped because it's a tautology + * @param arg argument filter + * + * If this argument filter applied to the upper 32 bit can be skipped this + * function returns false. + * + */ +static bool _db_arg_cmp_need_hi(const struct db_api_arg *arg) +{ + if (arg->op == SCMP_CMP_MASKED_EQ && D64_HI(arg->mask) == 0) + return false; + + return true; +} + +/** + * Fixup the node based on the op/mask + * @param node the chain node + * + * Ensure the datum is masked as well. + * + */ +static void _db_node_mask_fixup(struct db_arg_chain_tree *node) +{ + node->datum &= node->mask; +} + +/** + * Generate a new filter rule for a 64 bit system + * @param arch the architecture definition + * @param rule the new filter rule + * + * This function generates a new syscall filter for a 64 bit system. Returns + * zero on success, negative values on failure. + * + */ +static struct db_sys_list *_db_rule_gen_64(const struct arch_def *arch, + const struct db_api_rule_list *rule) +{ + unsigned int iter; + struct db_sys_list *s_new; + const struct db_api_arg *chain = rule->args; + struct db_arg_chain_tree *c_iter[3] = { NULL, NULL, NULL }; + struct db_arg_chain_tree *c_prev[3] = { NULL, NULL, NULL }; + enum scmp_compare op_prev = _SCMP_CMP_MIN; + unsigned int arg; + scmp_datum_t mask; + scmp_datum_t datum; + + s_new = zmalloc(sizeof(*s_new)); + if (s_new == NULL) + return NULL; + s_new->num = rule->syscall; + s_new->valid = true; + /* run through the argument chain */ + for (iter = 0; iter < ARG_COUNT_MAX; iter++) { + if (chain[iter].valid == 0) + continue; + + /* TODO: handle the case were either hi or lo isn't needed */ + + /* skip generating instruction which are no-ops */ + if (!_db_arg_cmp_need_hi(&chain[iter]) && + !_db_arg_cmp_need_lo(&chain[iter])) + continue; + + c_iter[0] = zmalloc(sizeof(*c_iter[0])); + if (c_iter[0] == NULL) + goto gen_64_failure; + c_iter[1] = zmalloc(sizeof(*c_iter[1])); + if (c_iter[1] == NULL) { + free(c_iter[0]); + goto gen_64_failure; + } + c_iter[2] = NULL; + + arg = chain[iter].arg; + mask = chain[iter].mask; + datum = chain[iter].datum; + + /* NOTE: with the idea that a picture is worth a thousand + * words, i'm presenting the following diagrams which + * show how we should compare 64-bit syscall arguments + * using 32-bit comparisons. + * + * in the diagrams below "A(x)" is the syscall argument + * being evaluated and "R(x)" is the syscall argument + * value specified in the libseccomp rule. the "ACCEPT" + * verdict indicates a rule match and processing should + * continue on to the rest of the rule, or the final rule + * action should be triggered. the "REJECT" verdict + * indicates that the rule does not match and processing + * should continue to the next rule or the default + * action. + * + * SCMP_CMP_GT: + * +------------------+ + * +--| Ah(x) > Rh(x) |------+ + * | +------------------+ | + * FALSE TRUE A + * | | C + * +-----------+ +----> C + * v +----> E + * +------------------+ | P + * +--| Ah(x) == Rh(x) |--+ | T + * R | +------------------+ | | + * E FALSE TRUE | + * J <----+ | | + * E <----+ +------------+ | + * C FALSE v | + * T | +------------------+ | + * +--| Al(x) > Rl(x) |------+ + * +------------------+ + * + * SCMP_CMP_GE: + * +------------------+ + * +--| Ah(x) > Rh(x) |------+ + * | +------------------+ | + * FALSE TRUE A + * | | C + * +-----------+ +----> C + * v +----> E + * +------------------+ | P + * +--| Ah(x) == Rh(x) |--+ | T + * R | +------------------+ | | + * E FALSE TRUE | + * J <----+ | | + * E <----+ +------------+ | + * C FALSE v | + * T | +------------------+ | + * +--| Al(x) >= Rl(x) |------+ + * +------------------+ + * + * SCMP_CMP_LT: + * +------------------+ + * +--| Ah(x) > Rh(x) |------+ + * | +------------------+ | + * FALSE TRUE R + * | | E + * +-----------+ +----> J + * v +----> E + * +------------------+ | C + * +--| Ah(x) == Rh(x) |--+ | T + * A | +------------------+ | | + * C FALSE TRUE | + * C <----+ | | + * E <----+ +------------+ | + * P FALSE v | + * T | +------------------+ | + * +--| Al(x) >= Rl(x) |------+ + * +------------------+ + * + * SCMP_CMP_LE: + * +------------------+ + * +--| Ah(x) > Rh(x) |------+ + * | +------------------+ | + * FALSE TRUE R + * | | E + * +-----------+ +----> J + * v +----> E + * +------------------+ | C + * +--| Ah(x) == Rh(x) |--+ | T + * A | +------------------+ | | + * C FALSE TRUE | + * C <----+ | | + * E <----+ +------------+ | + * P FALSE v | + * T | +------------------+ | + * +--| Al(x) > Rl(x) |------+ + * +------------------+ + * + * SCMP_CMP_EQ: + * +------------------+ + * +--| Ah(x) == Rh(x) |--+ + * R | +------------------+ | A + * E FALSE TRUE C + * J <----+ | C + * E <----+ +------------+ +----> E + * C FALSE v | P + * T | +------------------+ | T + * +--| Al(x) == Rl(x) |------+ + * +------------------+ + * + * SCMP_CMP_NE: + * +------------------+ + * +--| Ah(x) == Rh(x) |--+ + * A | +------------------+ | R + * C FALSE TRUE E + * C <----+ | J + * E <----+ +------------+ +----> E + * P FALSE v | C + * T | +------------------+ | T + * +--| Al(x) == Rl(x) |------+ + * +------------------+ + * + */ + + /* setup the level */ + switch (chain[iter].op) { + case SCMP_CMP_GT: + case SCMP_CMP_GE: + case SCMP_CMP_LE: + case SCMP_CMP_LT: + c_iter[2] = zmalloc(sizeof(*c_iter[2])); + if (c_iter[2] == NULL) { + free(c_iter[0]); + free(c_iter[1]); + goto gen_64_failure; + } + + c_iter[0]->arg = arg; + c_iter[1]->arg = arg; + c_iter[2]->arg = arg; + c_iter[0]->arg_h_flg = true; + c_iter[1]->arg_h_flg = true; + c_iter[2]->arg_h_flg = false; + c_iter[0]->arg_offset = arch_arg_offset_hi(arch, arg); + c_iter[1]->arg_offset = arch_arg_offset_hi(arch, arg); + c_iter[2]->arg_offset = arch_arg_offset_lo(arch, arg); + + c_iter[0]->mask = D64_HI(mask); + c_iter[1]->mask = D64_HI(mask); + c_iter[2]->mask = D64_LO(mask); + c_iter[0]->datum = D64_HI(datum); + c_iter[1]->datum = D64_HI(datum); + c_iter[2]->datum = D64_LO(datum); + c_iter[0]->datum_full = datum; + c_iter[1]->datum_full = datum; + c_iter[2]->datum_full = datum; + + _db_node_mask_fixup(c_iter[0]); + _db_node_mask_fixup(c_iter[1]); + _db_node_mask_fixup(c_iter[2]); + + c_iter[0]->op = SCMP_CMP_GT; + c_iter[1]->op = SCMP_CMP_EQ; + switch (chain[iter].op) { + case SCMP_CMP_GT: + case SCMP_CMP_LE: + c_iter[2]->op = SCMP_CMP_GT; + break; + case SCMP_CMP_GE: + case SCMP_CMP_LT: + c_iter[2]->op = SCMP_CMP_GE; + break; + default: + /* we should never get here */ + goto gen_64_failure; + } + c_iter[0]->op_orig = chain[iter].op; + c_iter[1]->op_orig = chain[iter].op; + c_iter[2]->op_orig = chain[iter].op; + + c_iter[0]->nxt_f = _db_node_get(c_iter[1]); + c_iter[1]->nxt_t = _db_node_get(c_iter[2]); + break; + case SCMP_CMP_EQ: + case SCMP_CMP_MASKED_EQ: + case SCMP_CMP_NE: + c_iter[0]->arg = arg; + c_iter[1]->arg = arg; + c_iter[0]->arg_h_flg = true; + c_iter[1]->arg_h_flg = false; + c_iter[0]->arg_offset = arch_arg_offset_hi(arch, arg); + c_iter[1]->arg_offset = arch_arg_offset_lo(arch, arg); + + c_iter[0]->mask = D64_HI(mask); + c_iter[1]->mask = D64_LO(mask); + c_iter[0]->datum = D64_HI(datum); + c_iter[1]->datum = D64_LO(datum); + c_iter[0]->datum_full = datum; + c_iter[1]->datum_full = datum; + + _db_node_mask_fixup(c_iter[0]); + _db_node_mask_fixup(c_iter[1]); + + switch (chain[iter].op) { + case SCMP_CMP_MASKED_EQ: + c_iter[0]->op = SCMP_CMP_MASKED_EQ; + c_iter[1]->op = SCMP_CMP_MASKED_EQ; + break; + default: + c_iter[0]->op = SCMP_CMP_EQ; + c_iter[1]->op = SCMP_CMP_EQ; + } + c_iter[0]->op_orig = chain[iter].op; + c_iter[1]->op_orig = chain[iter].op; + + c_iter[0]->nxt_t = _db_node_get(c_iter[1]); + break; + default: + /* we should never get here */ + goto gen_64_failure; + } + + /* link this level to the previous level */ + if (c_prev[0] != NULL) { + switch (op_prev) { + case SCMP_CMP_GT: + case SCMP_CMP_GE: + c_prev[0]->nxt_t = _db_node_get(c_iter[0]); + c_prev[2]->nxt_t = _db_node_get(c_iter[0]); + break; + case SCMP_CMP_EQ: + case SCMP_CMP_MASKED_EQ: + c_prev[1]->nxt_t = _db_node_get(c_iter[0]); + break; + case SCMP_CMP_LE: + case SCMP_CMP_LT: + c_prev[1]->nxt_f = _db_node_get(c_iter[0]); + c_prev[2]->nxt_f = _db_node_get(c_iter[0]); + break; + case SCMP_CMP_NE: + c_prev[0]->nxt_f = _db_node_get(c_iter[0]); + c_prev[1]->nxt_f = _db_node_get(c_iter[0]); + break; + default: + /* we should never get here */ + goto gen_64_failure; + } + } else + s_new->chains = _db_node_get(c_iter[0]); + + /* update the node count */ + switch (chain[iter].op) { + case SCMP_CMP_NE: + case SCMP_CMP_EQ: + case SCMP_CMP_MASKED_EQ: + s_new->node_cnt += 2; + break; + default: + s_new->node_cnt += 3; + } + + /* keep pointers to this level */ + c_prev[0] = c_iter[0]; + c_prev[1] = c_iter[1]; + c_prev[2] = c_iter[2]; + op_prev = chain[iter].op; + } + if (c_iter[0] != NULL) { + /* set the actions on the last layer */ + switch (op_prev) { + case SCMP_CMP_GT: + case SCMP_CMP_GE: + c_iter[0]->act_t_flg = true; + c_iter[0]->act_t = rule->action; + c_iter[2]->act_t_flg = true; + c_iter[2]->act_t = rule->action; + break; + case SCMP_CMP_LE: + case SCMP_CMP_LT: + c_iter[1]->act_f_flg = true; + c_iter[1]->act_f = rule->action; + c_iter[2]->act_f_flg = true; + c_iter[2]->act_f = rule->action; + break; + case SCMP_CMP_EQ: + case SCMP_CMP_MASKED_EQ: + c_iter[1]->act_t_flg = true; + c_iter[1]->act_t = rule->action; + break; + case SCMP_CMP_NE: + c_iter[0]->act_f_flg = true; + c_iter[0]->act_f = rule->action; + c_iter[1]->act_f_flg = true; + c_iter[1]->act_f = rule->action; + break; + default: + /* we should never get here */ + goto gen_64_failure; + } + } else + s_new->action = rule->action; + + return s_new; + +gen_64_failure: + /* free the new chain and its syscall struct */ + _db_tree_put(&s_new->chains); + free(s_new); + return NULL; +} + +/** + * Generate a new filter rule for a 32 bit system + * @param arch the architecture definition + * @param rule the new filter rule + * + * This function generates a new syscall filter for a 32 bit system. Returns + * zero on success, negative values on failure. + * + */ +static struct db_sys_list *_db_rule_gen_32(const struct arch_def *arch, + const struct db_api_rule_list *rule) +{ + unsigned int iter; + struct db_sys_list *s_new; + const struct db_api_arg *chain = rule->args; + struct db_arg_chain_tree *c_iter = NULL, *c_prev = NULL; + bool tf_flag; + + s_new = zmalloc(sizeof(*s_new)); + if (s_new == NULL) + return NULL; + s_new->num = rule->syscall; + s_new->valid = true; + /* run through the argument chain */ + for (iter = 0; iter < ARG_COUNT_MAX; iter++) { + if (chain[iter].valid == 0) + continue; + + /* skip generating instructions which are no-ops */ + if (!_db_arg_cmp_need_lo(&chain[iter])) + continue; + + c_iter = zmalloc(sizeof(*c_iter)); + if (c_iter == NULL) + goto gen_32_failure; + c_iter->arg = chain[iter].arg; + c_iter->arg_h_flg = false; + c_iter->arg_offset = arch_arg_offset(arch, c_iter->arg); + c_iter->op = chain[iter].op; + c_iter->op_orig = chain[iter].op; + /* implicitly strips off the upper 32 bit */ + c_iter->mask = chain[iter].mask; + c_iter->datum = chain[iter].datum; + c_iter->datum_full = chain[iter].datum; + + /* link in the new node and update the chain */ + if (c_prev != NULL) { + if (tf_flag) + c_prev->nxt_t = _db_node_get(c_iter); + else + c_prev->nxt_f = _db_node_get(c_iter); + } else + s_new->chains = _db_node_get(c_iter); + s_new->node_cnt++; + + /* rewrite the op to reduce the op/datum combos */ + switch (c_iter->op) { + case SCMP_CMP_NE: + c_iter->op = SCMP_CMP_EQ; + tf_flag = false; + break; + case SCMP_CMP_LT: + c_iter->op = SCMP_CMP_GE; + tf_flag = false; + break; + case SCMP_CMP_LE: + c_iter->op = SCMP_CMP_GT; + tf_flag = false; + break; + default: + tf_flag = true; + } + + /* fixup the mask/datum */ + _db_node_mask_fixup(c_iter); + + c_prev = c_iter; + } + if (c_iter != NULL) { + /* set the leaf node */ + if (tf_flag) { + c_iter->act_t_flg = true; + c_iter->act_t = rule->action; + } else { + c_iter->act_f_flg = true; + c_iter->act_f = rule->action; + } + } else + s_new->action = rule->action; + + return s_new; + +gen_32_failure: + /* free the new chain and its syscall struct */ + _db_tree_put(&s_new->chains); + free(s_new); + return NULL; +} + +/** + * Add a new rule to the seccomp filter DB + * @param db the seccomp filter db + * @param rule the filter rule + * + * This function adds a new syscall filter to the seccomp filter DB, adding to + * the existing filters for the syscall, unless no argument specific filters + * are present (filtering only on the syscall). When adding new chains, the + * shortest chain, or most inclusive filter match, will be entered into the + * filter DB. Returns zero on success, negative values on failure. + * + * It is important to note that in the case of failure the db may be corrupted, + * the caller must use the transaction mechanism if the db integrity is + * important. + * + */ +int db_rule_add(struct db_filter *db, const struct db_api_rule_list *rule) +{ + int rc = -ENOMEM; + struct db_sys_list *s_new, *s_iter, *s_prev = NULL; + struct db_iter_state state; + bool rm_flag = false; + + assert(db != NULL); + + /* do all our possible memory allocation up front so we don't have to + * worry about failure once we get to the point where we start updating + * the filter db */ + if (db->arch->size == ARCH_SIZE_64) + s_new = _db_rule_gen_64(db->arch, rule); + else if (db->arch->size == ARCH_SIZE_32) + s_new = _db_rule_gen_32(db->arch, rule); + else + return -EFAULT; + if (s_new == NULL) + return -ENOMEM; + + /* find a matching syscall/chain or insert a new one */ + s_iter = db->syscalls; + while (s_iter != NULL && s_iter->num < rule->syscall) { + s_prev = s_iter; + s_iter = s_iter->next; + } + s_new->priority = _DB_PRI_MASK_CHAIN - s_new->node_cnt; +add_reset: + if (s_iter == NULL || s_iter->num != rule->syscall) { + /* new syscall, add before s_iter */ + if (s_prev != NULL) { + s_new->next = s_prev->next; + s_prev->next = s_new; + } else { + s_new->next = db->syscalls; + db->syscalls = s_new; + } + db->syscall_cnt++; + return 0; + } else if (s_iter->chains == NULL) { + if (rm_flag || !s_iter->valid) { + /* we are here because our previous pass cleared the + * entire syscall chain when searching for a subtree + * match or the existing syscall entry is a phantom, + * so either way add the new chain */ + s_iter->chains = s_new->chains; + s_iter->action = s_new->action; + s_iter->node_cnt = s_new->node_cnt; + if (s_iter->valid) + s_iter->priority = s_new->priority; + s_iter->valid = true; + free(s_new); + rc = 0; + goto add_priority_update; + } else { + /* syscall exists without any chains - existing filter + * is at least as large as the new entry so cleanup and + * exit */ + _db_tree_put(&s_new->chains); + free(s_new); + goto add_free_ok; + } + } else if (s_iter->chains != NULL && s_new->chains == NULL) { + /* syscall exists with chains but the new filter has no chains + * so we need to clear the existing chains and exit */ + _db_tree_put(&s_iter->chains); + s_iter->chains = NULL; + s_iter->node_cnt = 0; + s_iter->action = rule->action; + + /* cleanup the new tree and return */ + _db_tree_put(&s_new->chains); + free(s_new); + goto add_free_ok; + } + + /* prune any sub-trees that are no longer required */ + memset(&state, 0, sizeof(state)); + state.sx = s_iter; + state.action = rule->action; + rc = _db_tree_prune(&s_iter->chains, s_new->chains, &state); + if (rc > 0) { + /* we pruned at least some of the existing tree */ + rm_flag = true; + s_iter->node_cnt -= rc; + if (s_iter->chains == NULL) + /* we pruned the entire tree */ + goto add_reset; + } else if ((state.flags & _DB_IST_M_REDUNDANT) == _DB_IST_M_REDUNDANT) { + /* the existing tree is "shorter", drop the new one */ + _db_tree_put(&s_new->chains); + free(s_new); + goto add_free_ok; + } + + /* add the new rule to the existing filter and cleanup */ + memset(&state, 0, sizeof(state)); + state.sx = s_iter; + rc = _db_tree_add(&s_iter->chains, s_new->chains, &state); + if (rc < 0) + goto add_failure; + s_iter->node_cnt += s_new->node_cnt; + s_iter->node_cnt -= _db_tree_put(&s_new->chains); + free(s_new); + +add_free_ok: + rc = 0; +add_priority_update: + /* update the priority */ + if (s_iter != NULL) { + s_iter->priority &= (~_DB_PRI_MASK_CHAIN); + s_iter->priority |= (_DB_PRI_MASK_CHAIN - s_iter->node_cnt); + } + return rc; + +add_failure: + /* NOTE: another reminder that we don't do any db error recovery here, + * use the transaction mechanism as previously mentioned */ + _db_tree_put(&s_new->chains); + free(s_new); + return rc; +} + +/** + * Set the priority of a given syscall + * @param col the filter collection + * @param syscall the syscall number + * @param priority priority value, higher value == higher priority + * + * This function sets the priority of the given syscall; this value is used + * when generating the seccomp filter code such that higher priority syscalls + * will incur less filter code overhead than the lower priority syscalls in the + * filter. Returns zero on success, negative values on failure. + * + */ +int db_col_syscall_priority(struct db_filter_col *col, + int syscall, uint8_t priority) +{ + int rc = 0, rc_tmp; + unsigned int iter; + int sc_tmp; + struct db_filter *filter; + + for (iter = 0; iter < col->filter_cnt; iter++) { + filter = col->filters[iter]; + sc_tmp = syscall; + + rc_tmp = arch_syscall_translate(filter->arch, &sc_tmp); + if (rc_tmp < 0) + goto priority_failure; + + /* if this is a pseudo syscall then we need to rewrite the + * syscall for some arch specific reason, don't forget the + * special handling for syscall -1 */ + if (sc_tmp < -1) { + /* 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, &sc_tmp); + if (rc_tmp == -EDOM) + continue; + if (rc_tmp < 0) + goto priority_failure; + } + + rc_tmp = _db_syscall_priority(filter, sc_tmp, priority); + +priority_failure: + if (rc == 0 && rc_tmp < 0) + rc = rc_tmp; + } + + return rc; +} + +/** + * Add a new rule to a single filter + * @param filter the filter + * @param rule the filter rule + * + * This is a helper function for db_col_rule_add() and similar functions, it + * isn't generally useful. Returns zero on success, negative values on error. + * + */ +static int _db_col_rule_add(struct db_filter *filter, + struct db_api_rule_list *rule) +{ + int rc; + struct db_api_rule_list *iter; + + /* add the rule to the filter */ + rc = arch_filter_rule_add(filter, rule); + if (rc != 0) + return rc; + + /* insert the chain to the end of the rule list */ + iter = rule; + while (iter->next) + iter = iter->next; + if (filter->rules != NULL) { + rule->prev = filter->rules->prev; + iter->next = filter->rules; + filter->rules->prev->next = rule; + filter->rules->prev = iter; + } else { + rule->prev = iter; + iter->next = rule; + filter->rules = rule; + } + + return 0; +} + +/** + * Add a new rule to the current filter + * @param col the filter collection + * @param strict the strict flag + * @param action the filter action + * @param syscall the syscall number + * @param arg_cnt the number of argument filters in the argument filter chain + * @param arg_array the argument filter chain, (uint, enum scmp_compare, ulong) + * + * This function adds a new argument/comparison/value to the seccomp filter for + * a syscall; multiple arguments can be specified and they will be chained + * together (essentially AND'd together) in the filter. When the strict flag + * is true the function will fail if the exact rule can not be added to the + * filter, if the strict flag is false the function will not fail if the + * function needs to adjust the rule due to architecture specifics. Returns + * zero on success, negative values on failure. + * + */ +int db_col_rule_add(struct db_filter_col *col, + bool strict, uint32_t action, int syscall, + unsigned int arg_cnt, const struct scmp_arg_cmp *arg_array) +{ + int rc = 0, rc_tmp; + unsigned int iter; + unsigned int arg_num; + size_t chain_size; + struct db_api_arg *chain = NULL; + struct scmp_arg_cmp arg_data; + struct db_api_rule_list *rule; + struct db_filter *db; + + /* collect the arguments for the filter rule */ + chain_size = sizeof(*chain) * ARG_COUNT_MAX; + chain = zmalloc(chain_size); + if (chain == NULL) + return -ENOMEM; + for (iter = 0; iter < arg_cnt; iter++) { + arg_data = arg_array[iter]; + arg_num = arg_data.arg; + if (arg_num < ARG_COUNT_MAX && chain[arg_num].valid == 0) { + chain[arg_num].valid = 1; + chain[arg_num].arg = arg_num; + chain[arg_num].op = arg_data.op; + /* TODO: we should check datum/mask size against the + * arch definition, e.g. 64 bit datum on x86 */ + switch (chain[arg_num].op) { + case SCMP_CMP_NE: + case SCMP_CMP_LT: + case SCMP_CMP_LE: + case SCMP_CMP_EQ: + case SCMP_CMP_GE: + case SCMP_CMP_GT: + chain[arg_num].mask = DATUM_MAX; + chain[arg_num].datum = arg_data.datum_a; + break; + case SCMP_CMP_MASKED_EQ: + chain[arg_num].mask = arg_data.datum_a; + chain[arg_num].datum = arg_data.datum_b; + break; + default: + rc = -EINVAL; + goto add_return; + } + } else { + rc = -EINVAL; + goto add_return; + } + } + + /* create a checkpoint */ + rc = db_col_transaction_start(col); + if (rc != 0) + goto add_return; + + /* add the rule to the different filters in the collection */ + for (iter = 0; iter < col->filter_cnt; iter++) { + db = col->filters[iter]; + + /* create the rule */ + rule = _db_rule_new(strict, action, syscall, chain); + if (rule == NULL) { + rc_tmp = -ENOMEM; + goto add_arch_fail; + } + + /* add the rule */ + rc_tmp = _db_col_rule_add(db, rule); + if (rc_tmp != 0) + free(rule); + +add_arch_fail: + if (rc_tmp != 0 && rc == 0) + rc = rc_tmp; + } + + /* commit the transaction or abort */ + if (rc == 0) + db_col_transaction_commit(col); + else + db_col_transaction_abort(col); + +add_return: + /* update the misc state */ + if (rc == 0 && action == SCMP_ACT_NOTIFY) + col->notify_used = true; + if (chain != NULL) + free(chain); + return rc; +} + +/** + * Start a new seccomp filter transaction + * @param col the filter collection + * + * This function starts a new seccomp filter transaction for the given filter + * collection. Returns zero on success, negative values on failure. + * + */ +int db_col_transaction_start(struct db_filter_col *col) +{ + int rc; + unsigned int iter; + struct db_filter_snap *snap; + struct db_filter *filter_o, *filter_s; + struct db_api_rule_list *rule_o, *rule_s = NULL; + + /* check to see if a shadow snapshot exists */ + if (col->snapshots && col->snapshots->shadow) { + /* we have a shadow! this will be easy */ + + /* NOTE: we don't bother to do any verification of the shadow + * because we start a new transaction every time we add + * a new rule to the filter(s); if this ever changes we + * will need to add a mechanism to verify that the shadow + * transaction is current/correct */ + + col->snapshots->shadow = false; + return 0; + } + + /* allocate the snapshot */ + snap = zmalloc(sizeof(*snap)); + if (snap == NULL) + return -ENOMEM; + snap->filters = zmalloc(sizeof(struct db_filter *) * col->filter_cnt); + if (snap->filters == NULL) { + free(snap); + return -ENOMEM; + } + snap->filter_cnt = col->filter_cnt; + for (iter = 0; iter < snap->filter_cnt; iter++) + snap->filters[iter] = NULL; + snap->next = NULL; + + /* create a snapshot of the current filter state */ + for (iter = 0; iter < col->filter_cnt; iter++) { + /* allocate a new filter */ + filter_o = col->filters[iter]; + filter_s = _db_init(filter_o->arch); + if (filter_s == NULL) + goto trans_start_failure; + snap->filters[iter] = filter_s; + + /* create a filter snapshot from existing rules */ + rule_o = filter_o->rules; + if (rule_o == NULL) + continue; + do { + /* duplicate the rule */ + rule_s = db_rule_dup(rule_o); + if (rule_s == NULL) + goto trans_start_failure; + + /* add the rule */ + rc = _db_col_rule_add(filter_s, rule_s); + if (rc != 0) + goto trans_start_failure; + rule_s = NULL; + + /* next rule */ + rule_o = rule_o->next; + } while (rule_o != filter_o->rules); + } + + /* add the snapshot to the list */ + snap->next = col->snapshots; + col->snapshots = snap; + + return 0; + +trans_start_failure: + if (rule_s != NULL) + free(rule_s); + _db_snap_release(snap); + return -ENOMEM; +} + +/** + * Abort the top most seccomp filter transaction + * @param col the filter collection + * + * This function aborts the most recent seccomp filter transaction. + * + */ +void db_col_transaction_abort(struct db_filter_col *col) +{ + int iter; + unsigned int filter_cnt; + struct db_filter **filters; + struct db_filter_snap *snap; + + if (col->snapshots == NULL) + return; + + /* replace the current filter with the last snapshot */ + snap = col->snapshots; + col->snapshots = snap->next; + filter_cnt = col->filter_cnt; + filters = col->filters; + col->filter_cnt = snap->filter_cnt; + col->filters = snap->filters; + free(snap); + + /* free the filter we swapped out */ + for (iter = 0; iter < filter_cnt; iter++) + _db_release(filters[iter]); + free(filters); +} + +/** + * Commit the top most seccomp filter transaction + * @param col the filter collection + * + * This function commits the most recent seccomp filter transaction and + * attempts to create a shadow transaction that is a duplicate of the current + * filter to speed up future transactions. + * + */ +void db_col_transaction_commit(struct db_filter_col *col) +{ + int rc; + unsigned int iter; + struct db_filter_snap *snap; + struct db_filter *filter_o, *filter_s; + struct db_api_rule_list *rule_o, *rule_s; + + snap = col->snapshots; + if (snap == NULL) + return; + + /* check for a shadow set by a higher transaction commit */ + if (snap->shadow) { + /* leave the shadow intact, but drop the next snapshot */ + if (snap->next) { + snap->next = snap->next->next; + _db_snap_release(snap->next); + } + return; + } + + /* adjust the number of filters if needed */ + if (col->filter_cnt > snap->filter_cnt) { + unsigned int tmp_i; + struct db_filter **tmp_f; + + /* add filters */ + tmp_f = realloc(snap->filters, + sizeof(struct db_filter *) * col->filter_cnt); + if (tmp_f == NULL) + goto shadow_err; + snap->filters = tmp_f; + do { + tmp_i = snap->filter_cnt; + snap->filters[tmp_i] = + _db_init(col->filters[tmp_i]->arch); + if (snap->filters[tmp_i] == NULL) + goto shadow_err; + snap->filter_cnt++; + } while (snap->filter_cnt < col->filter_cnt); + } else if (col->filter_cnt < snap->filter_cnt) { + /* remove filters */ + + /* NOTE: while we release the filters we no longer need, we + * don't bother to resize the filter array, we just + * adjust the filter counter, this *should* be harmless + * at the cost of a not reaping all the memory possible */ + + do { + _db_release(snap->filters[snap->filter_cnt--]); + } while (snap->filter_cnt > col->filter_cnt); + } + + /* loop through each filter and update the rules on the snapshot */ + for (iter = 0; iter < col->filter_cnt; iter++) { + filter_o = col->filters[iter]; + filter_s = snap->filters[iter]; + + /* skip ahead to the new rule(s) */ + rule_o = filter_o->rules; + rule_s = filter_s->rules; + if (rule_o == NULL) + /* nothing to shadow */ + continue; + if (rule_s != NULL) { + do { + rule_o = rule_o->next; + rule_s = rule_s->next; + } while (rule_s != filter_s->rules); + + /* did we actually add any rules? */ + if (rule_o == filter_o->rules) + /* no, we are done in this case */ + continue; + } + + /* update the old snapshot to make it a shadow */ + do { + /* duplicate the rule */ + rule_s = db_rule_dup(rule_o); + if (rule_s == NULL) + goto shadow_err; + + /* add the rule */ + rc = _db_col_rule_add(filter_s, rule_s); + if (rc != 0) { + free(rule_s); + goto shadow_err; + } + + /* next rule */ + rule_o = rule_o->next; + } while (rule_o != filter_o->rules); + } + + /* success, mark the snapshot as a shadow and return */ + snap->shadow = true; + return; + +shadow_err: + /* we failed making a shadow, cleanup and return */ + col->snapshots = snap->next; + _db_snap_release(snap); + return; +} diff --git a/src/db.h b/src/db.h new file mode 100644 index 0000000..765c607 --- /dev/null +++ b/src/db.h @@ -0,0 +1,217 @@ +/** + * Enhanced Seccomp Filter DB + * + * Copyright (c) 2012,2016 Red Hat <pmoore@redhat.com> + * Author: Paul Moore <paul@paul-moore.com> + */ + +/* + * 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>. + */ + +#ifndef _FILTER_DB_H +#define _FILTER_DB_H + +#include <inttypes.h> +#include <stdbool.h> + +#include <seccomp.h> + +#include "arch.h" + +/* XXX - need to provide doxygen comments for the types here */ + +struct db_api_arg { + unsigned int arg; + enum scmp_compare op; + scmp_datum_t mask; + scmp_datum_t datum; + + bool valid; +}; + +struct db_api_rule_list { + uint32_t action; + int syscall; + bool strict; + struct db_api_arg args[ARG_COUNT_MAX]; + + struct db_api_rule_list *prev, *next; +}; + +struct db_arg_chain_tree { + /* argument number (a0 = 0, a1 = 1, etc.) */ + unsigned int arg; + /* true to indicate this is the high 32-bit word of a 64-bit value */ + bool arg_h_flg; + /* argument bpf offset */ + unsigned int arg_offset; + + /* comparison operator */ + enum scmp_compare op; + enum scmp_compare op_orig; + /* syscall argument value */ + uint32_t mask; + uint32_t datum; + scmp_datum_t datum_full; + + /* actions */ + bool act_t_flg; + bool act_f_flg; + uint32_t act_t; + uint32_t act_f; + + /* list of nodes on this level */ + struct db_arg_chain_tree *lvl_prv, *lvl_nxt; + + /* next node in the chain */ + struct db_arg_chain_tree *nxt_t; + struct db_arg_chain_tree *nxt_f; + + unsigned int refcnt; +}; +#define ARG_MASK_MAX ((uint32_t)-1) + +struct db_sys_list { + /* native syscall number */ + unsigned int num; + + /* priority - higher is better */ + unsigned int priority; + + /* the argument chain heads */ + struct db_arg_chain_tree *chains; + unsigned int node_cnt; + + /* action in the case of no argument chains */ + uint32_t action; + + struct db_sys_list *next; + /* temporary use only by the BPF generator */ + struct db_sys_list *pri_prv, *pri_nxt; + + bool valid; +}; + +struct db_filter_attr { + /* action to take if we don't match an explicit allow/deny */ + uint32_t act_default; + /* action to take if we don't match the architecture */ + uint32_t act_badarch; + /* NO_NEW_PRIVS related attributes */ + uint32_t nnp_enable; + /* SECCOMP_FILTER_FLAG_TSYNC related attributes */ + uint32_t tsync_enable; + /* allow rules with a -1 syscall value */ + uint32_t api_tskip; + /* SECCOMP_FILTER_FLAG_LOG related attributes */ + uint32_t log_enable; + /* SPEC_ALLOW related attributes */ + uint32_t spec_allow; + /* SCMP_FLTATR_CTL_OPTIMIZE related attributes */ + uint32_t optimize; + /* return the raw system return codes */ + uint32_t api_sysrawrc; +}; + +struct db_filter { + /* target architecture */ + const struct arch_def *arch; + + /* syscall filters, kept as a sorted single-linked list */ + struct db_sys_list *syscalls; + unsigned int syscall_cnt; + + /* list of rules used to build the filters, kept in order */ + struct db_api_rule_list *rules; +}; + +struct db_filter_snap { + /* individual filters */ + struct db_filter **filters; + unsigned int filter_cnt; + bool shadow; + + struct db_filter_snap *next; +}; + +struct db_filter_col { + /* verification / state */ + int state; + + /* attributes */ + struct db_filter_attr attr; + + /* individual filters */ + int endian; + struct db_filter **filters; + unsigned int filter_cnt; + + /* transaction snapshots */ + struct db_filter_snap *snapshots; + + /* userspace notification */ + bool notify_used; +}; + +/** + * Iterate over each item in the DB list + * @param iter the iterator + * @param list the list + * + * This macro acts as for()/while() conditional and iterates the following + * statement for each item in the given list. + * + */ +#define db_list_foreach(iter,list) \ + for (iter = (list); iter != NULL; iter = iter->next) + +struct db_api_rule_list *db_rule_dup(const struct db_api_rule_list *src); + +struct db_filter_col *db_col_init(uint32_t def_action); +int db_col_reset(struct db_filter_col *col, uint32_t def_action); +void db_col_release(struct db_filter_col *col); + +int db_col_valid(struct db_filter_col *col); + +int db_col_action_valid(const struct db_filter_col *col, uint32_t action); + +int db_col_merge(struct db_filter_col *col_dst, struct db_filter_col *col_src); + +int db_col_arch_exist(struct db_filter_col *col, uint32_t arch_token); + +int db_col_attr_get(const struct db_filter_col *col, + enum scmp_filter_attr attr, uint32_t *value); +uint32_t db_col_attr_read(const struct db_filter_col *col, + enum scmp_filter_attr attr); +int db_col_attr_set(struct db_filter_col *col, + enum scmp_filter_attr attr, uint32_t value); + +int db_col_db_new(struct db_filter_col *col, const struct arch_def *arch); +int db_col_db_add(struct db_filter_col *col, struct db_filter *db); +int db_col_db_remove(struct db_filter_col *col, uint32_t arch_token); + +int db_col_rule_add(struct db_filter_col *col, + bool strict, uint32_t action, int syscall, + unsigned int arg_cnt, const struct scmp_arg_cmp *arg_array); + +int db_col_syscall_priority(struct db_filter_col *col, + int syscall, uint8_t priority); + +int db_col_transaction_start(struct db_filter_col *col); +void db_col_transaction_abort(struct db_filter_col *col); +void db_col_transaction_commit(struct db_filter_col *col); + +int db_rule_add(struct db_filter *db, const struct db_api_rule_list *rule); + +#endif diff --git a/src/gen_bpf.c b/src/gen_bpf.c new file mode 100644 index 0000000..90c38cc --- /dev/null +++ b/src/gen_bpf.c @@ -0,0 +1,2345 @@ +/** + * Seccomp BPF Translator + * + * Copyright (c) 2012 Red Hat <pmoore@redhat.com> + * Author: Paul Moore <paul@paul-moore.com> + */ + +/* + * 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 <errno.h> +#include <inttypes.h> +#include <limits.h> +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <stdbool.h> + +#ifndef _BSD_SOURCE +#define _BSD_SOURCE +#endif +#include <endian.h> + +#include <seccomp.h> + +#include "arch.h" +#include "arch-x32.h" +#include "gen_bpf.h" +#include "db.h" +#include "hash.h" +#include "system.h" +#include "helper.h" + +/* allocation increments */ +#define AINC_BLK 2 +#define AINC_PROG 64 + +/* binary tree definitions */ +#define SYSCALLS_PER_NODE (4) +#define BTREE_HSH_INVALID (UINT64_MAX) +#define BTREE_SYSCALL_INVALID (UINT_MAX) + +struct acc_state { + int32_t offset; + uint32_t mask; +}; +#define _ACC_STATE(x,y) \ + (struct acc_state){ .offset = (x), .mask = (y) } +#define _ACC_STATE_OFFSET(x) \ + _ACC_STATE(x,ARG_MASK_MAX) +#define _ACC_STATE_UNDEF \ + _ACC_STATE_OFFSET(-1) +#define _ACC_CMP_EQ(x,y) \ + ((x).offset == (y).offset && (x).mask == (y).mask) + +enum bpf_jump_type { + TGT_NONE = 0, + TGT_K, /* immediate "k" value */ + TGT_NXT, /* fall through to the next block */ + TGT_IMM, /* resolved immediate value */ + TGT_PTR_DB, /* pointer to part of the filter db */ + TGT_PTR_BLK, /* pointer to an instruction block */ + TGT_PTR_HSH, /* pointer to a block hash table */ +}; + +struct bpf_jump { + union { + uint8_t imm_j; + uint32_t imm_k; + uint64_t hash; + struct db_arg_chain_tree *db; + struct bpf_blk *blk; + unsigned int nxt; + } tgt; + enum bpf_jump_type type; +}; +#define _BPF_OP(a,x) \ + (_htot16(a,x)) +#define _BPF_JMP_NO \ + ((struct bpf_jump) { .type = TGT_NONE }) +#define _BPF_JMP_NXT(x) \ + ((struct bpf_jump) { .type = TGT_NXT, .tgt = { .nxt = (x) } }) +#define _BPF_JMP_IMM(x) \ + ((struct bpf_jump) { .type = TGT_IMM, .tgt = { .imm_j = (x) } }) +#define _BPF_JMP_DB(x) \ + ((struct bpf_jump) { .type = TGT_PTR_DB, .tgt = { .db = (x) } }) +#define _BPF_JMP_BLK(x) \ + ((struct bpf_jump) { .type = TGT_PTR_BLK, .tgt = { .blk = (x) } }) +#define _BPF_JMP_HSH(x) \ + ((struct bpf_jump) { .type = TGT_PTR_HSH, .tgt = { .hash = (x) } }) +#define _BPF_K(a,x) \ + ((struct bpf_jump) { .type = TGT_K, .tgt = { .imm_k = _htot32(a,x) } }) +#define _BPF_JMP_MAX 255 +#define _BPF_JMP_MAX_RET 255 + +struct bpf_instr { + uint16_t op; + struct bpf_jump jt; + struct bpf_jump jf; + struct bpf_jump k; +}; +#define _BPF_OFFSET_SYSCALL (offsetof(struct seccomp_data, nr)) +#define _BPF_SYSCALL(a) _BPF_K(a,_BPF_OFFSET_SYSCALL) +#define _BPF_OFFSET_ARCH (offsetof(struct seccomp_data, arch)) +#define _BPF_ARCH(a) _BPF_K(a,_BPF_OFFSET_ARCH) + +struct bpf_blk { + /* bpf instructions */ + struct bpf_instr *blks; + unsigned int blk_cnt; + unsigned int blk_alloc; + + /* accumulator state */ + struct acc_state acc_start; + struct acc_state acc_end; + + /* priority - higher is better */ + unsigned int priority; + + /* status flags */ + bool flag_hash; /* added to the hash table */ + bool flag_dup; /* duplicate block and in use */ + bool flag_unique; /* ->blks is unique to this block */ + + /* original db_arg_chain_tree node */ + const struct db_arg_chain_tree *node; + + /* used during block assembly */ + uint64_t hash; + struct bpf_blk *hash_nxt; + struct bpf_blk *prev, *next; + struct bpf_blk *lvl_prv, *lvl_nxt; +}; +#define _BLK_MSZE(x) \ + ((x)->blk_cnt * sizeof(*((x)->blks))) + +struct bpf_hash_bkt { + struct bpf_blk *blk; + struct bpf_hash_bkt *next; + unsigned int found; +}; + +#define _BPF_HASH_BITS 8 +#define _BPF_HASH_SIZE (1 << _BPF_HASH_BITS) +#define _BPF_HASH_MASK (_BPF_HASH_BITS - 1) +struct bpf_state { + /* block hash table */ + struct bpf_hash_bkt *htbl[_BPF_HASH_SIZE]; + + /* filter attributes */ + const struct db_filter_attr *attr; + /* bad arch action */ + uint64_t bad_arch_hsh; + /* default action */ + uint64_t def_hsh; + + /* bpf program */ + struct bpf_program *bpf; + + /* WARNING - the following variables are temporary use only */ + const struct arch_def *arch; + struct bpf_blk *b_head; + struct bpf_blk *b_tail; + struct bpf_blk *b_new; +}; + +/** + * Populate a BPF instruction + * @param _ins the BPF instruction + * @param _op the BPF operand + * @param _jt the BPF jt value + * @param _jf the BPF jf value + * @param _k the BPF k value + * + * Set the given values on the provided bpf_instr struct. + * + */ +#define _BPF_INSTR(_ins,_op,_jt,_jf,_k) \ + do { \ + memset(&(_ins), 0, sizeof(_ins)); \ + (_ins).op = (_op); \ + (_ins).jt = _jt; \ + (_ins).jf = _jf; \ + (_ins).k = _k; \ + } while (0) + +static struct bpf_blk *_gen_bpf_chain(struct bpf_state *state, + const struct db_sys_list *sys, + const struct db_arg_chain_tree *chain, + const struct bpf_jump *nxt_jump, + struct acc_state *a_state); + +static struct bpf_blk *_hsh_remove(struct bpf_state *state, uint64_t h_val); +static struct bpf_blk *_hsh_find(const struct bpf_state *state, uint64_t h_val); + +/** + * Convert a 16-bit host integer into the target's endianess + * @param arch the architecture definition + * @param val the 16-bit integer + * + * Convert the endianess of the supplied value and return it to the caller. + * + */ +static uint16_t _htot16(const struct arch_def *arch, uint16_t val) +{ + if (arch->endian == ARCH_ENDIAN_LITTLE) + return htole16(val); + else + return htobe16(val); +} + +/** + * Convert a 32-bit host integer into the target's endianess + * @param arch the architecture definition + * @param val the 32-bit integer + * + * Convert the endianess of the supplied value and return it to the caller. + * + */ +static uint32_t _htot32(const struct arch_def *arch, uint32_t val) +{ + if (arch->endian == ARCH_ENDIAN_LITTLE) + return htole32(val); + else + return htobe32(val); +} + +/** + * Free the BPF instruction block + * @param state the BPF state + * @param blk the BPF instruction block + * + * Free the BPF instruction block, any linked blocks are preserved and the hash + * table is not modified. In general, you probably want to use _blk_free() + * instead. + * + */ +static void __blk_free(struct bpf_state *state, struct bpf_blk *blk) +{ + struct bpf_blk *b_tmp; + + while (blk->hash_nxt != NULL) { + b_tmp = blk->hash_nxt; + blk->hash_nxt = b_tmp->hash_nxt; + if (!b_tmp->flag_dup) + free(b_tmp); + } + if (blk->blks != NULL && blk->flag_unique) + free(blk->blks); + free(blk); +} + +/** +* Free the BPF instruction block + * @param state the BPF state + * @param blk the BPF instruction block + * + * Free the BPF instruction block including any linked blocks. The hash table + * is updated to reflect the newly removed block(s). + * + */ +static void _blk_free(struct bpf_state *state, struct bpf_blk *blk) +{ + int iter; + struct bpf_blk *b_iter; + struct bpf_instr *i_iter; + + if (blk == NULL) + return; + + /* remove this block from the hash table */ + _hsh_remove(state, blk->hash); + + /* run through the block freeing TGT_PTR_{BLK,HSH} jump targets */ + for (iter = 0; iter < blk->blk_cnt; iter++) { + i_iter = &blk->blks[iter]; + switch (i_iter->jt.type) { + case TGT_PTR_BLK: + _blk_free(state, i_iter->jt.tgt.blk); + break; + case TGT_PTR_HSH: + b_iter = _hsh_find(state, i_iter->jt.tgt.hash); + _blk_free(state, b_iter); + break; + default: + /* do nothing */ + break; + } + switch (i_iter->jf.type) { + case TGT_PTR_BLK: + _blk_free(state, i_iter->jf.tgt.blk); + break; + case TGT_PTR_HSH: + b_iter = _hsh_find(state, i_iter->jf.tgt.hash); + _blk_free(state, b_iter); + break; + default: + /* do nothing */ + break; + } + } + __blk_free(state, blk); +} + +/** + * Allocate and initialize a new instruction block + * + * Allocate a new BPF instruction block and perform some very basic + * initialization. Returns a pointer to the block on success, NULL on failure. + * + */ +static struct bpf_blk *_blk_alloc(void) +{ + struct bpf_blk *blk; + + blk = zmalloc(sizeof(*blk)); + if (blk == NULL) + return NULL; + blk->flag_unique = true; + blk->acc_start = _ACC_STATE_UNDEF; + blk->acc_end = _ACC_STATE_UNDEF; + + return blk; +} + +/** + * Resize an instruction block + * @param state the BPF state + * @param blk the existing instruction block, or NULL + * @param size_add the minimum amount of instructions to add + * + * Resize the given instruction block such that it is at least as large as the + * current size plus @size_add. Returns a pointer to the block on success, + * NULL on failure. + * + */ +static struct bpf_blk *_blk_resize(struct bpf_state *state, + struct bpf_blk *blk, + unsigned int size_add) +{ + unsigned int size_adj = (AINC_BLK > size_add ? AINC_BLK : size_add); + struct bpf_instr *new; + + if (blk == NULL) + return NULL; + + if ((blk->blk_cnt + size_adj) <= blk->blk_alloc) + return blk; + + blk->blk_alloc += size_adj; + new = realloc(blk->blks, blk->blk_alloc * sizeof(*(blk->blks))); + if (new == NULL) { + _blk_free(state, blk); + return NULL; + } + blk->blks = new; + + return blk; +} + +/** + * Append a new BPF instruction to an instruction block + * @param state the BPF state + * @param blk the existing instruction block, or NULL + * @param instr the new instruction + * + * Add the new BPF instruction to the end of the given instruction block. If + * the given instruction block is NULL, a new block will be allocated. Returns + * a pointer to the block on success, NULL on failure, and in the case of + * failure the instruction block is free'd. + * + */ +static struct bpf_blk *_blk_append(struct bpf_state *state, + struct bpf_blk *blk, + const struct bpf_instr *instr) +{ + if (blk == NULL) { + blk = _blk_alloc(); + if (blk == NULL) + return NULL; + } + + if (_blk_resize(state, blk, 1) == NULL) + return NULL; + memcpy(&blk->blks[blk->blk_cnt++], instr, sizeof(*instr)); + + return blk; +} + +/** + * Prepend a new BPF instruction to an instruction block + * @param state the BPF state + * @param blk the existing instruction block, or NULL + * @param instr the new instruction + * + * Add the new BPF instruction to the start of the given instruction block. + * If the given instruction block is NULL, a new block will be allocated. + * Returns a pointer to the block on success, NULL on failure, and in the case + * of failure the instruction block is free'd. + * + */ +static struct bpf_blk *_blk_prepend(struct bpf_state *state, + struct bpf_blk *blk, + const struct bpf_instr *instr) +{ + /* empty - we can treat this like a normal append operation */ + if (blk == NULL || blk->blk_cnt == 0) + return _blk_append(state, blk, instr); + + if (_blk_resize(state, blk, 1) == NULL) + return NULL; + memmove(&blk->blks[1], &blk->blks[0], blk->blk_cnt++ * sizeof(*instr)); + memcpy(&blk->blks[0], instr, sizeof(*instr)); + + return blk; +} + +/** + * Append a block of BPF instructions to the final BPF program + * @param prg the BPF program + * @param blk the BPF instruction block + * + * Add the BPF instruction block to the end of the BPF program and perform the + * necessary translation. Returns zero on success, negative values on failure + * and in the case of failure the BPF program is free'd. + * + */ +static int _bpf_append_blk(struct bpf_program *prg, const struct bpf_blk *blk) +{ + int rc; + bpf_instr_raw *i_new; + bpf_instr_raw *i_iter; + unsigned int old_cnt = prg->blk_cnt; + unsigned int iter; + + /* (re)allocate the program memory */ + prg->blk_cnt += blk->blk_cnt; + i_new = realloc(prg->blks, BPF_PGM_SIZE(prg)); + if (i_new == NULL) { + rc = -ENOMEM; + goto bpf_append_blk_failure; + } + prg->blks = i_new; + + /* transfer and translate the blocks to raw instructions */ + for (iter = 0; iter < blk->blk_cnt; iter++) { + i_iter = &(prg->blks[old_cnt + iter]); + + i_iter->code = blk->blks[iter].op; + switch (blk->blks[iter].jt.type) { + case TGT_NONE: + i_iter->jt = 0; + break; + case TGT_IMM: + /* jump to the value specified */ + i_iter->jt = blk->blks[iter].jt.tgt.imm_j; + break; + default: + /* fatal error - we should never get here */ + rc = -EFAULT; + goto bpf_append_blk_failure; + } + switch (blk->blks[iter].jf.type) { + case TGT_NONE: + i_iter->jf = 0; + break; + case TGT_IMM: + /* jump to the value specified */ + i_iter->jf = blk->blks[iter].jf.tgt.imm_j; + break; + default: + /* fatal error - we should never get here */ + rc = -EFAULT; + goto bpf_append_blk_failure; + } + switch (blk->blks[iter].k.type) { + case TGT_K: + i_iter->k = blk->blks[iter].k.tgt.imm_k; + break; + default: + /* fatal error - we should never get here */ + rc = -EFAULT; + goto bpf_append_blk_failure; + } + } + + return prg->blk_cnt; + +bpf_append_blk_failure: + prg->blk_cnt = 0; + free(prg->blks); + return rc; +} + +/** + * Free the BPF program + * @param prg the BPF program + * + * Free the BPF program. None of the associated BPF state used to generate the + * BPF program is released in this function. + * + */ +static void _program_free(struct bpf_program *prg) +{ + if (prg == NULL) + return; + + if (prg->blks != NULL) + free(prg->blks); + free(prg); +} + +/** + * Free the BPF state + * @param state the BPF state + * + * Free all of the BPF state, including the BPF program if present. + * + */ +static void _state_release(struct bpf_state *state) +{ + unsigned int bkt; + struct bpf_hash_bkt *iter; + + if (state == NULL) + return; + + /* release all of the hash table entries */ + for (bkt = 0; bkt < _BPF_HASH_SIZE; bkt++) { + while (state->htbl[bkt]) { + iter = state->htbl[bkt]; + state->htbl[bkt] = iter->next; + __blk_free(state, iter->blk); + free(iter); + } + } + _program_free(state->bpf); + + memset(state, 0, sizeof(*state)); +} + +/** + * Add an instruction block to the BPF state hash table + * @param state the BPF state + * @param blk_p pointer to the BPF instruction block + * @param found initial found value (see _hsh_find_once() for description) + * + * This function adds an instruction block to the hash table, and frees the + * block if an identical instruction block already exists, returning a pointer + * to the original block in place of the given block. Returns zero on success + * and negative values on failure. + * + */ +static int _hsh_add(struct bpf_state *state, struct bpf_blk **blk_p, + unsigned int found) +{ + uint64_t h_val, h_val_tmp[3]; + struct bpf_hash_bkt *h_new, *h_iter, *h_prev = NULL; + struct bpf_blk *blk = *blk_p; + struct bpf_blk *b_iter; + + if (blk->flag_hash) + return 0; + + h_new = zmalloc(sizeof(*h_new)); + if (h_new == NULL) + return -ENOMEM; + + /* generate the hash */ + h_val_tmp[0] = hash(blk->blks, _BLK_MSZE(blk)); + h_val_tmp[1] = hash(&blk->acc_start, sizeof(blk->acc_start)); + h_val_tmp[2] = hash(&blk->acc_end, sizeof(blk->acc_end)); + h_val = hash(h_val_tmp, sizeof(h_val_tmp)); + blk->hash = h_val; + blk->flag_hash = true; + blk->node = NULL; + h_new->blk = blk; + h_new->found = (found ? 1 : 0); + + /* insert the block into the hash table */ +hsh_add_restart: + h_iter = state->htbl[h_val & _BPF_HASH_MASK]; + if (h_iter != NULL) { + do { + if ((h_iter->blk->hash == h_val) && + (_BLK_MSZE(h_iter->blk) == _BLK_MSZE(blk)) && + (memcmp(h_iter->blk->blks, blk->blks, + _BLK_MSZE(blk)) == 0) && + _ACC_CMP_EQ(h_iter->blk->acc_start, + blk->acc_start) && + _ACC_CMP_EQ(h_iter->blk->acc_end, + blk->acc_end)) { + /* duplicate block */ + free(h_new); + + /* store the duplicate block */ + b_iter = h_iter->blk; + while (b_iter->hash_nxt != NULL) + b_iter = b_iter->hash_nxt; + b_iter->hash_nxt = blk; + + /* in some cases we want to return the + * duplicate block */ + if (found) { + blk->flag_dup = true; + return 0; + } + + /* update the priority if needed */ + if (h_iter->blk->priority < blk->priority) + h_iter->blk->priority = blk->priority; + + /* try to save some memory */ + free(blk->blks); + blk->blks = h_iter->blk->blks; + blk->flag_unique = false; + + *blk_p = h_iter->blk; + return 0; + } else if (h_iter->blk->hash == h_val) { + /* hash collision */ + if ((h_val >> 32) == 0xffffffff) { + /* overflow */ + blk->flag_hash = false; + blk->hash = 0; + free(h_new); + return -EFAULT; + } + h_val += ((uint64_t)1 << 32); + h_new->blk->hash = h_val; + + /* restart at the beginning of the bucket */ + goto hsh_add_restart; + } else { + /* no match, move along */ + h_prev = h_iter; + h_iter = h_iter->next; + } + } while (h_iter != NULL); + h_prev->next = h_new; + } else + state->htbl[h_val & _BPF_HASH_MASK] = h_new; + + return 0; +} + +/** + * Remove an entry from the hash table + * @param state the BPF state + * @param h_val the hash value + * + * Remove an entry from the hash table and return it to the caller, NULL is + * returned if the entry can not be found. + * + */ +static struct bpf_blk *_hsh_remove(struct bpf_state *state, uint64_t h_val) +{ + unsigned int bkt = h_val & _BPF_HASH_MASK; + struct bpf_blk *blk; + struct bpf_hash_bkt *h_iter, *h_prev = NULL; + + h_iter = state->htbl[bkt]; + while (h_iter != NULL) { + if (h_iter->blk->hash == h_val) { + if (h_prev != NULL) + h_prev->next = h_iter->next; + else + state->htbl[bkt] = h_iter->next; + blk = h_iter->blk; + free(h_iter); + return blk; + } + h_prev = h_iter; + h_iter = h_iter->next; + } + + return NULL; +} + +/** + * Find and return a hash bucket + * @param state the BPF state + * @param h_val the hash value + * + * Find the entry associated with the given hash value and return it to the + * caller, NULL is returned if the entry can not be found. This function + * should not be called directly; use _hsh_find() and _hsh_find_once() instead. + * + */ +static struct bpf_hash_bkt *_hsh_find_bkt(const struct bpf_state *state, + uint64_t h_val) +{ + struct bpf_hash_bkt *h_iter; + + h_iter = state->htbl[h_val & _BPF_HASH_MASK]; + while (h_iter != NULL) { + if (h_iter->blk->hash == h_val) + return h_iter; + h_iter = h_iter->next; + } + + return NULL; +} + +/** + * Find and only return an entry in the hash table once + * @param state the BPF state + * @param h_val the hash value + * + * Find the entry associated with the given hash value and return it to the + * caller if it has not be returned previously by this function; returns NULL + * if the entry can not be found or has already been returned in a previous + * call. + * + */ +static struct bpf_blk *_hsh_find_once(const struct bpf_state *state, + uint64_t h_val) +{ + struct bpf_hash_bkt *h_iter; + + h_iter = _hsh_find_bkt(state, h_val); + if (h_iter == NULL || h_iter->found != 0) + return NULL; + h_iter->found = 1; + return h_iter->blk; +} + +/** + * Finds an entry in the hash table + * @param state the BPF state + * @param h_val the hash value + * + * Find the entry associated with the given hash value and return it to the + * caller, NULL is returned if the entry can not be found. + * + */ +static struct bpf_blk *_hsh_find(const struct bpf_state *state, uint64_t h_val) +{ + struct bpf_hash_bkt *h_iter; + + h_iter = _hsh_find_bkt(state, h_val); + if (h_iter == NULL) + return NULL; + return h_iter->blk; +} + +/** + * Generate a BPF action instruction + * @param state the BPF state + * @param blk the BPF instruction block, or NULL + * @param action the desired action + * + * Generate a BPF action instruction and append it to the given instruction + * block. Returns a pointer to the instruction block on success, NULL on + * failure. + * + */ +static struct bpf_blk *_gen_bpf_action(struct bpf_state *state, + struct bpf_blk *blk, uint32_t action) +{ + struct bpf_instr instr; + + _BPF_INSTR(instr, _BPF_OP(state->arch, BPF_RET), + _BPF_JMP_NO, _BPF_JMP_NO, _BPF_K(state->arch, action)); + return _blk_append(state, blk, &instr); +} + +/** + * Generate a BPF action instruction and insert it into the hash table + * @param state the BPF state + * @param action the desired action + * + * Generate a BPF action instruction and insert it into the hash table. + * Returns a pointer to the instruction block on success, NULL on failure. + * + */ +static struct bpf_blk *_gen_bpf_action_hsh(struct bpf_state *state, + uint32_t action) +{ + struct bpf_blk *blk; + + blk = _gen_bpf_action(state, NULL, action); + if (blk == NULL) + return NULL; + if (_hsh_add(state, &blk, 0) < 0) { + _blk_free(state, blk); + return NULL; + } + + return blk; +} + +/** + * Generate a BPF instruction block for a given chain node + * @param state the BPF state + * @param node the filter chain node + * @param a_state the accumulator state + * + * Generate BPF instructions to execute the filter for the given chain node. + * Returns a pointer to the instruction block on success, NULL on failure. + * + */ +static struct bpf_blk *_gen_bpf_node(struct bpf_state *state, + const struct db_arg_chain_tree *node, + struct acc_state *a_state) +{ + int32_t acc_offset; + uint32_t acc_mask; + uint64_t act_t_hash = 0, act_f_hash = 0; + struct bpf_blk *blk, *b_act; + struct bpf_instr instr; + + blk = _blk_alloc(); + if (blk == NULL) + return NULL; + blk->acc_start = *a_state; + + /* generate the action blocks */ + if (node->act_t_flg) { + b_act = _gen_bpf_action_hsh(state, node->act_t); + if (b_act == NULL) + goto node_failure; + act_t_hash = b_act->hash; + } + if (node->act_f_flg) { + b_act = _gen_bpf_action_hsh(state, node->act_f); + if (b_act == NULL) + goto node_failure; + act_f_hash = b_act->hash; + } + + /* check the accumulator state */ + acc_offset = node->arg_offset; + acc_mask = node->mask; + if (acc_offset < 0) + goto node_failure; + if ((acc_offset != a_state->offset) || + ((acc_mask & a_state->mask) != acc_mask)) { + /* reload the accumulator */ + a_state->offset = acc_offset; + a_state->mask = ARG_MASK_MAX; + _BPF_INSTR(instr, _BPF_OP(state->arch, BPF_LD + BPF_ABS), + _BPF_JMP_NO, _BPF_JMP_NO, + _BPF_K(state->arch, acc_offset)); + blk = _blk_append(state, blk, &instr); + if (blk == NULL) + goto node_failure; + /* we're not dependent on the accumulator anymore */ + blk->acc_start = _ACC_STATE_UNDEF; + } + if (acc_mask != a_state->mask) { + /* apply the bitmask */ + a_state->mask = acc_mask; + _BPF_INSTR(instr, _BPF_OP(state->arch, BPF_ALU + BPF_AND), + _BPF_JMP_NO, _BPF_JMP_NO, + _BPF_K(state->arch, acc_mask)); + blk = _blk_append(state, blk, &instr); + if (blk == NULL) + goto node_failure; + } + + /* set the accumulator state at the end of the block */ + /* NOTE: the accumulator end state is very critical when we are + * assembling the final state; we assume that however we leave + * this instruction block the accumulator state is represented + * by blk->acc_end, it must be kept correct */ + blk->acc_end = *a_state; + + /* check the accumulator against the datum */ + switch (node->op) { + case SCMP_CMP_MASKED_EQ: + case SCMP_CMP_EQ: + _BPF_INSTR(instr, _BPF_OP(state->arch, BPF_JMP + BPF_JEQ), + _BPF_JMP_NO, _BPF_JMP_NO, + _BPF_K(state->arch, node->datum)); + break; + case SCMP_CMP_GT: + _BPF_INSTR(instr, _BPF_OP(state->arch, BPF_JMP + BPF_JGT), + _BPF_JMP_NO, _BPF_JMP_NO, + _BPF_K(state->arch, node->datum)); + break; + case SCMP_CMP_GE: + _BPF_INSTR(instr, _BPF_OP(state->arch, BPF_JMP + BPF_JGE), + _BPF_JMP_NO, _BPF_JMP_NO, + _BPF_K(state->arch, node->datum)); + break; + case SCMP_CMP_NE: + case SCMP_CMP_LT: + case SCMP_CMP_LE: + default: + /* fatal error, we should never get here */ + goto node_failure; + } + + /* fixup the jump targets */ + if (node->nxt_t != NULL) + instr.jt = _BPF_JMP_DB(node->nxt_t); + else if (node->act_t_flg) + instr.jt = _BPF_JMP_HSH(act_t_hash); + else + instr.jt = _BPF_JMP_NXT(0); + if (node->nxt_f != NULL) + instr.jf = _BPF_JMP_DB(node->nxt_f); + else if (node->act_f_flg) + instr.jf = _BPF_JMP_HSH(act_f_hash); + else + instr.jf = _BPF_JMP_NXT(0); + blk = _blk_append(state, blk, &instr); + if (blk == NULL) + goto node_failure; + + blk->node = node; + return blk; + +node_failure: + _blk_free(state, blk); + return NULL; +} + +/** + * Resolve the jump targets in a BPF instruction block + * @param state the BPF state + * @param sys the syscall filter + * @param blk the BPF instruction block + * @param nxt_jump the jump to fallthrough to at the end of the level + * + * Resolve the jump targets in a BPF instruction block generated by the + * _gen_bpf_chain_lvl() function and adds the resulting block to the hash + * table. Returns a pointer to the new instruction block on success, NULL on + * failure. + * + */ +static struct bpf_blk *_gen_bpf_chain_lvl_res(struct bpf_state *state, + const struct db_sys_list *sys, + struct bpf_blk *blk, + const struct bpf_jump *nxt_jump) +{ + int rc; + unsigned int iter; + struct bpf_blk *b_new; + struct bpf_instr *i_iter; + struct db_arg_chain_tree *node; + + if (blk->flag_hash) + return blk; + + /* convert TGT_PTR_DB to TGT_PTR_HSH references */ + for (iter = 0; iter < blk->blk_cnt; iter++) { + i_iter = &blk->blks[iter]; + switch (i_iter->jt.type) { + case TGT_NONE: + case TGT_IMM: + case TGT_PTR_HSH: + /* ignore these jump types */ + break; + case TGT_PTR_BLK: + b_new = _gen_bpf_chain_lvl_res(state, sys, + i_iter->jt.tgt.blk, + nxt_jump); + if (b_new == NULL) + return NULL; + i_iter->jt = _BPF_JMP_HSH(b_new->hash); + break; + case TGT_PTR_DB: + node = (struct db_arg_chain_tree *)i_iter->jt.tgt.db; + b_new = _gen_bpf_chain(state, sys, node, + nxt_jump, &blk->acc_end); + if (b_new == NULL) + return NULL; + i_iter->jt = _BPF_JMP_HSH(b_new->hash); + break; + default: + /* we should not be here */ + return NULL; + } + switch (i_iter->jf.type) { + case TGT_NONE: + case TGT_IMM: + case TGT_PTR_HSH: + /* ignore these jump types */ + break; + case TGT_PTR_BLK: + b_new = _gen_bpf_chain_lvl_res(state, sys, + i_iter->jf.tgt.blk, + nxt_jump); + if (b_new == NULL) + return NULL; + i_iter->jf = _BPF_JMP_HSH(b_new->hash); + break; + case TGT_PTR_DB: + node = (struct db_arg_chain_tree *)i_iter->jf.tgt.db; + b_new = _gen_bpf_chain(state, sys, node, + nxt_jump, &blk->acc_end); + if (b_new == NULL) + return NULL; + i_iter->jf = _BPF_JMP_HSH(b_new->hash); + break; + default: + /* we should not be here */ + return NULL; + } + switch (i_iter->k.type) { + case TGT_NONE: + case TGT_K: + case TGT_PTR_HSH: + /* ignore these jump types */ + break; + default: + /* we should not be here */ + return NULL; + } + } + + /* insert the block into the hash table */ + rc = _hsh_add(state, &blk, 0); + if (rc < 0) + return NULL; + + return blk; +} + +/** + * Generates the BPF instruction blocks for a given filter chain + * @param state the BPF state + * @param sys the syscall filter + * @param chain the filter chain + * @param nxt_jump the jump to fallthrough to at the end of the level + * @param a_state the accumulator state + * + * Generate the BPF instruction blocks for the given filter chain and return + * a pointer to the first block on success; returns NULL on failure. + * + */ +static struct bpf_blk *_gen_bpf_chain(struct bpf_state *state, + const struct db_sys_list *sys, + const struct db_arg_chain_tree *chain, + const struct bpf_jump *nxt_jump, + struct acc_state *a_state) +{ + struct bpf_blk *b_head = NULL, *b_tail = NULL; + struct bpf_blk *b_prev, *b_next, *b_iter; + struct bpf_instr *i_iter; + const struct db_arg_chain_tree *c_iter; + unsigned int iter; + struct bpf_jump nxt_jump_tmp; + struct acc_state acc = *a_state; + + if (chain == NULL) { + b_head = _gen_bpf_action(state, NULL, sys->action); + if (b_head == NULL) + goto chain_failure; + b_tail = b_head; + } else { + /* find the starting node of the level */ + c_iter = chain; + while (c_iter->lvl_prv != NULL) + c_iter = c_iter->lvl_prv; + + /* build all of the blocks for this level */ + do { + b_iter = _gen_bpf_node(state, c_iter, &acc); + if (b_iter == NULL) + goto chain_failure; + if (b_head != NULL) { + b_iter->lvl_prv = b_tail; + b_tail->lvl_nxt = b_iter; + b_tail = b_iter; + } else { + b_head = b_iter; + b_tail = b_iter; + } + c_iter = c_iter->lvl_nxt; + } while (c_iter != NULL); + + /* resolve the TGT_NXT jumps */ + b_iter = b_head; + do { + b_next = b_iter->lvl_nxt; + for (iter = 0; iter < b_iter->blk_cnt; iter++) { + i_iter = &b_iter->blks[iter]; + if (i_iter->jt.type == TGT_NXT) { + if (i_iter->jt.tgt.nxt != 0) + goto chain_failure; + if (b_next == NULL) + i_iter->jt = *nxt_jump; + else + i_iter->jt = + _BPF_JMP_BLK(b_next); + } + if (i_iter->jf.type == TGT_NXT) { + if (i_iter->jf.tgt.nxt != 0) + goto chain_failure; + if (b_next == NULL) + i_iter->jf = *nxt_jump; + else + i_iter->jf = + _BPF_JMP_BLK(b_next); + } + } + b_iter = b_next; + } while (b_iter != NULL); + } + + /* resolve all of the blocks */ + memset(&nxt_jump_tmp, 0, sizeof(nxt_jump_tmp)); + b_iter = b_tail; + do { + /* b_iter may change after resolving, so save the linkage */ + b_prev = b_iter->lvl_prv; + b_next = b_iter->lvl_nxt; + + nxt_jump_tmp = _BPF_JMP_BLK(b_next); + b_iter = _gen_bpf_chain_lvl_res(state, sys, b_iter, + (b_next == NULL ? + nxt_jump : + &nxt_jump_tmp)); + if (b_iter == NULL) + goto chain_failure; + + /* restore the block linkage on this level */ + if (b_prev != NULL) + b_prev->lvl_nxt = b_iter; + b_iter->lvl_prv = b_prev; + b_iter->lvl_nxt = b_next; + if (b_next != NULL) + b_next->lvl_prv = b_iter; + if (b_iter->lvl_prv == NULL) + b_head = b_iter; + + b_iter = b_prev; + } while (b_iter != NULL); + + return b_head; + +chain_failure: + while (b_head != NULL) { + b_iter = b_head; + b_head = b_iter->lvl_nxt; + _blk_free(state, b_iter); + } + return NULL; +} + +/** + * Sort the syscalls by syscall number + * @param syscalls the linked list of syscalls to be sorted + * @param s_head the head of the linked list to be returned to the caller + * @param s_tail the tail of the linked list to be returned to the caller + */ +static void _sys_num_sort(struct db_sys_list *syscalls, + struct db_sys_list **s_head, + struct db_sys_list **s_tail) +{ + struct db_sys_list *s_iter, *s_iter_b; + + db_list_foreach(s_iter, syscalls) { + if (*s_head != NULL) { + s_iter_b = *s_head; + while ((s_iter_b->pri_nxt != NULL) && + (s_iter->num <= s_iter_b->num)) + s_iter_b = s_iter_b->pri_nxt; + + if (s_iter->num > s_iter_b->num) { + s_iter->pri_prv = s_iter_b->pri_prv; + s_iter->pri_nxt = s_iter_b; + if (s_iter_b == *s_head) { + (*s_head)->pri_prv = s_iter; + *s_head = s_iter; + } else { + s_iter->pri_prv->pri_nxt = s_iter; + s_iter->pri_nxt->pri_prv = s_iter; + } + } else { + s_iter->pri_prv = *s_tail; + s_iter->pri_nxt = NULL; + s_iter->pri_prv->pri_nxt = s_iter; + *s_tail = s_iter; + } + } else { + *s_head = s_iter; + *s_tail = s_iter; + (*s_head)->pri_prv = NULL; + (*s_head)->pri_nxt = NULL; + } + } +} + +/** + * Sort the syscalls by priority + * @param syscalls the linked list of syscalls to be sorted + * @param s_head the head of the linked list to be returned to the caller + * @param s_tail the tail of the linked list to be returned to the caller + */ +static void _sys_priority_sort(struct db_sys_list *syscalls, + struct db_sys_list **s_head, + struct db_sys_list **s_tail) +{ + struct db_sys_list *s_iter, *s_iter_b; + + db_list_foreach(s_iter, syscalls) { + if (*s_head != NULL) { + s_iter_b = *s_head; + while ((s_iter_b->pri_nxt != NULL) && + (s_iter->priority <= s_iter_b->priority)) + s_iter_b = s_iter_b->pri_nxt; + + if (s_iter->priority > s_iter_b->priority) { + s_iter->pri_prv = s_iter_b->pri_prv; + s_iter->pri_nxt = s_iter_b; + if (s_iter_b == *s_head) { + (*s_head)->pri_prv = s_iter; + *s_head = s_iter; + } else { + s_iter->pri_prv->pri_nxt = s_iter; + s_iter->pri_nxt->pri_prv = s_iter; + } + } else { + s_iter->pri_prv = *s_tail; + s_iter->pri_nxt = NULL; + s_iter->pri_prv->pri_nxt = s_iter; + *s_tail = s_iter; + } + } else { + *s_head = s_iter; + *s_tail = s_iter; + (*s_head)->pri_prv = NULL; + (*s_head)->pri_nxt = NULL; + } + } +} + +/** + * Sort the syscalls + * @param syscalls the linked list of syscalls to be sorted + * @param s_head the head of the linked list to be returned to the caller + * @param s_tail the tail of the linked list to be returned to the caller + * + * Wrapper function for sorting syscalls + * + */ +static void _sys_sort(struct db_sys_list *syscalls, + struct db_sys_list **s_head, + struct db_sys_list **s_tail, + uint32_t optimize) +{ + if (optimize != 2) + _sys_priority_sort(syscalls, s_head, s_tail); + else + /* sort by number for the binary tree */ + _sys_num_sort(syscalls, s_head, s_tail); +} + +/** + * Insert an instruction into the BPF state and connect the linked list + * @param state the BPF state + * @param instr the instruction to insert + * @param insert the BPF blk that represents the instruction + * @param next the next BPF instruction in the linked list + * @param existing_blk insert will be added to the end of this blk if non-NULL + * + * Insert a set of instructions into the BPF state and associate those + * instructions with the bpf_blk called insert. The "next" field in the + * newly inserted block will be linked with the "next" bpf_blk parameter. + */ +static int _gen_bpf_insert(struct bpf_state *state, struct bpf_instr *instr, + struct bpf_blk **insert, struct bpf_blk **next, + struct bpf_blk *existing_blk) +{ + int rc; + + *insert = _blk_append(state, existing_blk, instr); + if (*insert == NULL) + return -ENOMEM; + (*insert)->next = (*next); + if (*next != NULL) + (*next)->prev = (*insert); + *next = *insert; + + rc = _hsh_add(state, insert, 1); + return rc; +} + +/** + * Decide if we need to omit the syscall from the BPF filter + * @param state the BPF state + * @param syscall syscall being tested + * @return true if syscall is to be skipped, false otherwise + */ +static inline bool _skip_syscall(struct bpf_state *state, + struct db_sys_list *syscall) +{ + if (!syscall->valid) + return true; + + /* psuedo-syscalls should not be added to the filter unless explicity + * requested via SCMP_FLTATR_API_TSKIP + */ + if (((int)syscall->num < 0) && + (state->attr->api_tskip == 0 || syscall->num != -1)) + return true; + + return false; +} + +/** + * Calculate the number of syscalls that will be in the BPF filter + * @param state the BPF state + * @param s_tail the last syscall in the syscall linked list + */ +static unsigned int _get_syscall_cnt(struct bpf_state *state, + struct db_sys_list *s_tail) +{ + struct db_sys_list *s_iter; + unsigned int syscall_cnt = 0; + + for (s_iter = s_tail; s_iter != NULL; s_iter = s_iter->pri_prv) { + if (_skip_syscall(state, s_iter)) + continue; + + syscall_cnt++; + } + + return syscall_cnt; +} + +/** + * Calculate the number of levels in the binary tree + * @param syscall_cnt the number of syscalls in this seccomp filter + */ +static int _get_bintree_levels(unsigned int syscall_cnt) +{ + unsigned int i = 2, max_level = SYSCALLS_PER_NODE * 2; + + if (syscall_cnt == 0) + return 0; + + while (max_level < syscall_cnt) { + max_level <<= 1; + i++; + } + + return i; +} + +/** + * Initialize the binary tree + * @param bintree_hashes Array of hashes that store binary tree jump dests + * @param bintree_syscalls Array of syscalls for the binary tree "if > " logic + * @param bintree_levels Number of levels in the binary tree + * @param syscall_cnt Number of syscalls in this filter + * @param empty_cnt Number of empty slots needed to balance the tree + * + */ +static int _gen_bpf_init_bintree(uint64_t **bintree_hashes, + unsigned int **bintree_syscalls, + unsigned int *bintree_levels, + unsigned int syscall_cnt, + unsigned int *empty_cnt) +{ + int i; + + *bintree_levels = _get_bintree_levels(syscall_cnt); + + if (*bintree_levels > 0) { + *empty_cnt = ((unsigned int)(SYSCALLS_PER_NODE * 2) << + ((*bintree_levels) - 1)) - syscall_cnt; + *bintree_hashes = zmalloc(sizeof(uint64_t) * + (*bintree_levels)); + if (*bintree_hashes == NULL) + return -ENOMEM; + + *bintree_syscalls = zmalloc(sizeof(unsigned int) * + (*bintree_levels)); + if (*bintree_syscalls == NULL) + return -ENOMEM; + + for (i = 0; i < *bintree_levels; i++) { + (*bintree_syscalls)[i] = BTREE_SYSCALL_INVALID; + (*bintree_hashes)[i] = BTREE_HSH_INVALID; + } + } + + return 0; +} + +/** + * Generate the binary tree + * @param state the BPF state + * @param bintree_hashes Array of hashes that store binary tree jump dests + * @param bintree_syscalls Array of syscalls for the binary tree "if > " logic + * @param bintree_levels Number of levels in the binary tree + * @param total_cnt Total number of syscalls and empty slots in the bintree + * @param cur_syscall Current syscall being processed + * @param blks_added Number of BPF blocks added by this function + * + * Generate the BPF instruction blocks for the binary tree for cur_syscall. + * If this syscall is at the end of the node, then this function will + * create the requisite ifs and elses for the tree. + */ +static int _gen_bpf_bintree(struct bpf_state *state, uint64_t *bintree_hashes, + unsigned int *bintree_syscalls, + unsigned int bintree_levels, + unsigned int total_cnt, unsigned int cur_syscall, + unsigned int *blks_added) +{ + struct bpf_blk *b_bintree = NULL; + struct bpf_instr instr; + unsigned int level; + int rc = 0, i, j; + + for (i = bintree_levels - 1; i >= 0; i--) { + level = SYSCALLS_PER_NODE << i; + + if ((total_cnt % level) == 0) { + /* save the "if greater than" syscall num */ + bintree_syscalls[i] = cur_syscall; + /* save the hash for the jf case */ + bintree_hashes[i] = state->b_new->hash; + + for (j = 0; j < i; j++) { + if (bintree_syscalls[j] == BTREE_SYSCALL_INVALID || + bintree_hashes[j] == BTREE_HSH_INVALID) + /* we are near the end of the binary + * tree and the jump-to location is + * not valid. skip this if-else + */ + continue; + + _BPF_INSTR(instr, + _BPF_OP(state->arch, BPF_JMP + BPF_JGT), + _BPF_JMP_NO, + _BPF_JMP_NO, + _BPF_K(state->arch, bintree_syscalls[j])); + instr.jt = _BPF_JMP_HSH(b_bintree == NULL ? + state->b_new->hash : b_bintree->hash); + instr.jf = _BPF_JMP_HSH(bintree_hashes[j]); + (*blks_added)++; + + rc = _gen_bpf_insert(state, &instr, + &b_bintree, &state->b_head, NULL); + if (rc < 0) + goto out; + } + + if (b_bintree != NULL) + /* this is the last if in this "block". + * save it off so the next binary tree + * if can "else" to it. + */ + bintree_hashes[j] = b_bintree->hash; + break; + } + } + +out: + return rc; +} + +/** + * Generate the BPF instruction blocks for a given syscall + * @param state the BPF state + * @param sys the syscall filter DB entry + * @param nxt_hash the hash value of the next syscall filter DB entry + * @param acc_reset accumulator reset flag + * + * Generate the BPF instruction blocks for the given syscall filter and return + * a pointer to the first block on success; returns NULL on failure. It is + * important to note that the block returned has not been added to the hash + * table, however, any linked/referenced blocks have been added to the hash + * table. + * + */ +static struct bpf_blk *_gen_bpf_syscall(struct bpf_state *state, + const struct db_sys_list *sys, + uint64_t nxt_hash, + bool acc_reset) +{ + int rc; + struct bpf_instr instr; + struct bpf_blk *blk_c, *blk_s; + struct bpf_jump def_jump; + struct acc_state a_state; + + /* we do the memset before the assignment to keep valgrind happy */ + memset(&def_jump, 0, sizeof(def_jump)); + def_jump = _BPF_JMP_HSH(state->def_hsh); + + blk_s = _blk_alloc(); + if (blk_s == NULL) + return NULL; + + /* setup the accumulator state */ + if (acc_reset) { + _BPF_INSTR(instr, _BPF_OP(state->arch, BPF_LD + BPF_ABS), + _BPF_JMP_NO, _BPF_JMP_NO, + _BPF_SYSCALL(state->arch)); + blk_s = _blk_append(state, blk_s, &instr); + if (blk_s == NULL) + return NULL; + /* we've loaded the syscall ourselves */ + a_state = _ACC_STATE_OFFSET(_BPF_OFFSET_SYSCALL); + blk_s->acc_start = _ACC_STATE_UNDEF; + blk_s->acc_end = _ACC_STATE_OFFSET(_BPF_OFFSET_SYSCALL); + } else { + /* we rely on someone else to load the syscall */ + a_state = _ACC_STATE_UNDEF; + blk_s->acc_start = _ACC_STATE_OFFSET(_BPF_OFFSET_SYSCALL); + blk_s->acc_end = _ACC_STATE_OFFSET(_BPF_OFFSET_SYSCALL); + } + + /* generate the argument chains */ + blk_c = _gen_bpf_chain(state, sys, sys->chains, &def_jump, &a_state); + if (blk_c == NULL) { + _blk_free(state, blk_s); + return NULL; + } + + /* syscall check */ + _BPF_INSTR(instr, _BPF_OP(state->arch, BPF_JMP + BPF_JEQ), + _BPF_JMP_HSH(blk_c->hash), _BPF_JMP_HSH(nxt_hash), + _BPF_K(state->arch, sys->num)); + blk_s = _blk_append(state, blk_s, &instr); + if (blk_s == NULL) + return NULL; + blk_s->priority = sys->priority; + + /* add to the hash table */ + rc = _hsh_add(state, &blk_s, 1); + if (rc < 0) { + _blk_free(state, blk_s); + return NULL; + } + + return blk_s; +} + +/** + * Loop through the syscalls in the db_filter and generate their bpf + * @param state the BPF state + * @param db the filter DB + * @param db_secondary the secondary DB + * @param Number of blocks added by this function + */ +static int _gen_bpf_syscalls(struct bpf_state *state, + const struct db_filter *db, + const struct db_filter *db_secondary, + unsigned int *blks_added, uint32_t optimize, + unsigned int *bintree_levels) +{ + struct db_sys_list *s_head = NULL, *s_tail = NULL, *s_iter; + unsigned int syscall_cnt, empty_cnt = 0; + uint64_t *bintree_hashes = NULL, nxt_hsh; + unsigned int *bintree_syscalls = NULL; + bool acc_reset; + int rc = 0; + + state->arch = db->arch; + state->b_head = NULL; + state->b_tail = NULL; + state->b_new = NULL; + + *blks_added = 0; + + /* sort the syscall list */ + _sys_sort(db->syscalls, &s_head, &s_tail, optimize); + if (db_secondary != NULL) + _sys_sort(db_secondary->syscalls, &s_head, &s_tail, optimize); + + if (optimize == 2) { + syscall_cnt = _get_syscall_cnt(state, s_tail); + rc = _gen_bpf_init_bintree(&bintree_hashes, &bintree_syscalls, + bintree_levels, syscall_cnt, + &empty_cnt); + if (rc < 0) + goto out; + } + + if ((state->arch->token == SCMP_ARCH_X86_64 || + state->arch->token == SCMP_ARCH_X32) && (db_secondary == NULL)) + acc_reset = false; + else + acc_reset = true; + + if (*bintree_levels > 0) + /* The accumulator is reset when the first bintree "if" is + * generated. + */ + acc_reset = false; + + syscall_cnt = 0; + + /* create the syscall filters and add them to block list group */ + for (s_iter = s_tail; s_iter != NULL; s_iter = s_iter->pri_prv) { + if (_skip_syscall(state, s_iter)) + continue; + + if (*bintree_levels > 0 && + ((syscall_cnt + empty_cnt) % SYSCALLS_PER_NODE) == 0) + /* This is the last syscall in the node. go to the + * default hash */ + nxt_hsh = state->def_hsh; + else + nxt_hsh = state->b_head == NULL ? + state->def_hsh : state->b_head->hash; + + /* build the syscall filter */ + state->b_new = _gen_bpf_syscall(state, s_iter, nxt_hsh, + (s_iter == s_head ? + acc_reset : false)); + if (state->b_new == NULL) + goto out; + + /* add the filter to the list head */ + state->b_new->prev = NULL; + state->b_new->next = state->b_head; + if (state->b_tail != NULL) { + state->b_head->prev = state->b_new; + state->b_head = state->b_new; + } else { + state->b_head = state->b_new; + state->b_tail = state->b_head; + } + + if (state->b_tail->next != NULL) + state->b_tail = state->b_tail->next; + (*blks_added)++; + syscall_cnt++; + + /* build the binary tree if and else logic */ + if (*bintree_levels > 0) { + rc = _gen_bpf_bintree(state, bintree_hashes, + bintree_syscalls, + *bintree_levels, + syscall_cnt + empty_cnt, + s_iter->num, blks_added); + if (rc < 0) + goto out; + } + } + +out: + if (bintree_hashes != NULL) + free(bintree_hashes); + if (bintree_syscalls != NULL) + free(bintree_syscalls); + + return rc; +} + +/** + * Generate the BPF instruction blocks for a given filter/architecture + * @param state the BPF state + * @param db the filter DB + * @param db_secondary the secondary DB + * + * Generate the BPF instruction block for the given filter DB(s)/architecture(s) + * and return a pointer to the block on succes, NULL on failure. The resulting + * block assumes that the architecture token has already been loaded into the + * BPF accumulator. + * + */ +static struct bpf_blk *_gen_bpf_arch(struct bpf_state *state, + const struct db_filter *db, + const struct db_filter *db_secondary, + uint32_t optimize) +{ + int rc; + unsigned int blk_cnt = 0, blks_added = 0, bintree_levels = 0; + struct bpf_instr instr; + struct bpf_blk *b_iter, *b_bintree; + + state->arch = db->arch; + + /* create the syscall filters and add them to block list group */ + rc = _gen_bpf_syscalls(state, db, db_secondary, &blks_added, optimize, + &bintree_levels); + if (rc < 0) + goto arch_failure; + blk_cnt += blks_added; + + if (bintree_levels > 0) { + _BPF_INSTR(instr, _BPF_OP(state->arch, BPF_LD + BPF_ABS), + _BPF_JMP_NO, _BPF_JMP_NO, + _BPF_SYSCALL(state->arch)); + blk_cnt++; + + rc = _gen_bpf_insert(state, &instr, &b_bintree, + &state->b_head, NULL); + if (rc < 0) + goto arch_failure; + b_bintree->acc_start = _ACC_STATE_UNDEF; + b_bintree->acc_end = _ACC_STATE_OFFSET(_BPF_OFFSET_SYSCALL); + } + + /* additional ABI filtering */ + if ((state->arch->token == SCMP_ARCH_X86_64 || + state->arch->token == SCMP_ARCH_X32) && (db_secondary == NULL)) { + _BPF_INSTR(instr, _BPF_OP(state->arch, BPF_LD + BPF_ABS), + _BPF_JMP_NO, _BPF_JMP_NO, _BPF_SYSCALL(state->arch)); + state->b_new = _blk_append(state, NULL, &instr); + if (state->b_new == NULL) + goto arch_failure; + state->b_new->acc_end = _ACC_STATE_OFFSET(_BPF_OFFSET_SYSCALL); + if (state->arch->token == SCMP_ARCH_X86_64) { + /* filter out x32 */ + _BPF_INSTR(instr, + _BPF_OP(state->arch, BPF_JMP + BPF_JGE), + _BPF_JMP_NO, + _BPF_JMP_NO, + _BPF_K(state->arch, X32_SYSCALL_BIT)); + if (state->b_head != NULL) + instr.jf = _BPF_JMP_HSH(state->b_head->hash); + else + instr.jf = _BPF_JMP_HSH(state->def_hsh); + state->b_new = _blk_append(state, state->b_new, &instr); + if (state->b_new == NULL) + goto arch_failure; + /* NOTE: starting with Linux v4.8 the seccomp filters + * are processed both when the syscall is + * initially executed as well as after any + * tracing processes finish so we need to make + * sure we don't trap the -1 syscall which + * tracers can use to skip the syscall, see + * seccomp(2) for more information */ + _BPF_INSTR(instr, + _BPF_OP(state->arch, BPF_JMP + BPF_JEQ), + _BPF_JMP_NO, + _BPF_JMP_HSH(state->bad_arch_hsh), + _BPF_K(state->arch, -1)); + if (state->b_head != NULL) + instr.jt = _BPF_JMP_HSH(state->b_head->hash); + else + instr.jt = _BPF_JMP_HSH(state->def_hsh); + blk_cnt++; + } else if (state->arch->token == SCMP_ARCH_X32) { + /* filter out x86_64 */ + _BPF_INSTR(instr, + _BPF_OP(state->arch, BPF_JMP + BPF_JGE), + _BPF_JMP_NO, + _BPF_JMP_HSH(state->bad_arch_hsh), + _BPF_K(state->arch, X32_SYSCALL_BIT)); + if (state->b_head != NULL) + instr.jt = _BPF_JMP_HSH(state->b_head->hash); + else + instr.jt = _BPF_JMP_HSH(state->def_hsh); + blk_cnt++; + } else + /* we should never get here */ + goto arch_failure; + + rc = _gen_bpf_insert(state, &instr, &state->b_new, + &state->b_head, state->b_new); + if (rc < 0) + goto arch_failure; + } + + /* do the ABI/architecture check */ + _BPF_INSTR(instr, _BPF_OP(state->arch, BPF_JMP + BPF_JEQ), + _BPF_JMP_NO, _BPF_JMP_NXT(blk_cnt++), + _BPF_K(state->arch, state->arch->token_bpf)); + if (state->b_head != NULL) + instr.jt = _BPF_JMP_HSH(state->b_head->hash); + else + instr.jt = _BPF_JMP_HSH(state->def_hsh); + + rc = _gen_bpf_insert(state, &instr, &state->b_new, &state->b_head, + NULL); + if (rc < 0) + goto arch_failure; + + state->arch = NULL; + return state->b_head; + +arch_failure: + /* NOTE: we do the cleanup here and not just return an error as all of + * the instruction blocks may not be added to the hash table when we + * hit an error */ + state->arch = NULL; + b_iter = state->b_head; + while (b_iter != NULL) { + state->b_new = b_iter->next; + _blk_free(state, b_iter); + b_iter = state->b_new; + } + return NULL; +} + +/** + * Find the target block for the "next" jump + * @param blk the instruction block + * @param nxt the next offset + * + * Find the target block for the TGT_NXT jump using the given offset. Returns + * a pointer to the target block on success or NULL on failure. + * + */ +static struct bpf_blk *_gen_bpf_find_nxt(const struct bpf_blk *blk, + unsigned int nxt) +{ + struct bpf_blk *iter = blk->next; + + for (; (iter != NULL) && (nxt > 0); nxt--) + iter = iter->next; + + return iter; +} + +/** + * Manage jumps to return instructions + * @param state the BPF state + * @param blk the instruction block to check + * @param offset the instruction offset into the instruction block + * @param blk_ret the return instruction block + * + * Using the given block and instruction offset, calculate the jump distance + * between the jumping instruction and return instruction block. If the jump + * distance is too great, duplicate the return instruction to reduce the + * distance to the maximum value. Returns 1 if a long jump was added, zero if + * the existing jump is valid, and negative values on failure. + * + */ +static int _gen_bpf_build_jmp_ret(struct bpf_state *state, + struct bpf_blk *blk, unsigned int offset, + struct bpf_blk *blk_ret) +{ + unsigned int j_len; + uint64_t tgt_hash = blk_ret->hash; + struct bpf_blk *b_jmp, *b_new; + + /* calculate the jump distance */ + j_len = blk->blk_cnt - (offset + 1); + b_jmp = blk->next; + while (b_jmp != NULL && b_jmp != blk_ret && j_len < _BPF_JMP_MAX_RET) { + j_len += b_jmp->blk_cnt; + b_jmp = b_jmp->next; + } + if (b_jmp == NULL) + return -EFAULT; + if (j_len <= _BPF_JMP_MAX_RET && b_jmp == blk_ret) + return 0; + + /* we need a closer return instruction, see if one already exists */ + j_len = blk->blk_cnt - (offset + 1); + b_jmp = blk->next; + while (b_jmp != NULL && b_jmp->hash != tgt_hash && + j_len < _BPF_JMP_MAX_RET) { + j_len += b_jmp->blk_cnt; + b_jmp = b_jmp->next; + } + if (b_jmp == NULL) + return -EFAULT; + if (j_len <= _BPF_JMP_MAX_RET && b_jmp->hash == tgt_hash) + return 0; + + /* we need to insert a new return instruction - create one */ + b_new = _gen_bpf_action(state, NULL, blk_ret->blks[0].k.tgt.imm_k); + if (b_new == NULL) + return -EFAULT; + + /* NOTE - we need to be careful here, we're giving the block a hash + * value (this is a sneaky way to ensure we leverage the + * inserted long jumps as much as possible) but we never add the + * block to the hash table so it won't get cleaned up + * automatically */ + b_new->hash = tgt_hash; + + /* insert the jump after the current jumping block */ + b_new->prev = blk; + b_new->next = blk->next; + blk->next->prev = b_new; + blk->next = b_new; + + return 1; +} + +/** + * Manage jump lengths by duplicating and adding jumps if needed + * @param state the BPF state + * @param tail the tail of the instruction block list + * @param blk the instruction block to check + * @param offset the instruction offset into the instruction block + * @param tgt_hash the hash of the jump destination block + * + * Using the given block and instruction offset, calculate the jump distance + * between the jumping instruction and the destination. If the jump distance + * is too great, add a long jump instruction to reduce the distance to a legal + * value. Returns 1 if a new instruction was added, zero if the existing jump + * is valid, and negative values on failure. + * + */ +static int _gen_bpf_build_jmp(struct bpf_state *state, + struct bpf_blk *tail, + struct bpf_blk *blk, unsigned int offset, + uint64_t tgt_hash) +{ + int rc; + unsigned int jmp_len; + struct bpf_instr instr; + struct bpf_blk *b_new, *b_jmp, *b_tgt; + + /* find the jump target */ + b_tgt = tail; + while (b_tgt != blk && b_tgt->hash != tgt_hash) + b_tgt = b_tgt->prev; + if (b_tgt == blk) + return -EFAULT; + + if (b_tgt->blk_cnt == 1 && + b_tgt->blks[0].op == _BPF_OP(state->arch, BPF_RET)) { + rc = _gen_bpf_build_jmp_ret(state, blk, offset, b_tgt); + if (rc == 1) + return 1; + else if (rc < 0) + return rc; + } + + /* calculate the jump distance */ + jmp_len = blk->blk_cnt - (offset + 1); + b_jmp = blk->next; + while (b_jmp != NULL && b_jmp != b_tgt && jmp_len < _BPF_JMP_MAX) { + jmp_len += b_jmp->blk_cnt; + b_jmp = b_jmp->next; + } + if (b_jmp == NULL) + return -EFAULT; + if (jmp_len <= _BPF_JMP_MAX && b_jmp == b_tgt) + return 0; + + /* we need a long jump, see if one already exists */ + jmp_len = blk->blk_cnt - (offset + 1); + b_jmp = blk->next; + while (b_jmp != NULL && b_jmp->hash != tgt_hash && + jmp_len < _BPF_JMP_MAX) { + jmp_len += b_jmp->blk_cnt; + b_jmp = b_jmp->next; + } + if (b_jmp == NULL) + return -EFAULT; + if (jmp_len <= _BPF_JMP_MAX && b_jmp->hash == tgt_hash) + return 0; + + /* we need to insert a long jump - create one */ + _BPF_INSTR(instr, _BPF_OP(state->arch, BPF_JMP + BPF_JA), + _BPF_JMP_NO, _BPF_JMP_NO, _BPF_JMP_HSH(tgt_hash)); + b_new = _blk_append(state, NULL, &instr); + if (b_new == NULL) + return -EFAULT; + + /* NOTE - we need to be careful here, we're giving the block a hash + * value (this is a sneaky way to ensure we leverage the + * inserted long jumps as much as possible) but we never add the + * block to the hash table so it won't get cleaned up + * automatically */ + b_new->hash = tgt_hash; + + /* insert the jump after the current jumping block */ + b_new->prev = blk; + b_new->next = blk->next; + blk->next->prev = b_new; + blk->next = b_new; + + return 1; +} + +/** + * Generate the BPF program for the given filter collection + * @param state the BPF state + * @param col the filter collection + * + * Generate the BPF program for the given filter collection. Returns zero on + * success, negative values on failure. + * + */ +static int _gen_bpf_build_bpf(struct bpf_state *state, + const struct db_filter_col *col) +{ + int rc; + int iter; + uint64_t h_val; + unsigned int res_cnt; + unsigned int jmp_len; + int arch_x86_64 = -1, arch_x32 = -1; + struct bpf_instr instr; + struct bpf_instr *i_iter; + struct bpf_blk *b_badarch, *b_default; + struct bpf_blk *b_head = NULL, *b_tail = NULL, *b_iter, *b_new, *b_jmp; + struct db_filter *db_secondary = NULL; + struct arch_def pseudo_arch; + + /* create a fake architecture definition for use in the early stages */ + memset(&pseudo_arch, 0, sizeof(pseudo_arch)); + pseudo_arch.endian = col->endian; + state->arch = &pseudo_arch; + + /* generate the badarch action */ + b_badarch = _gen_bpf_action(state, NULL, state->attr->act_badarch); + if (b_badarch == NULL) + return -ENOMEM; + rc = _hsh_add(state, &b_badarch, 1); + if (rc < 0) + return rc; + state->bad_arch_hsh = b_badarch->hash; + + /* generate the default action */ + b_default = _gen_bpf_action(state, NULL, state->attr->act_default); + if (b_default == NULL) + return -ENOMEM; + rc = _hsh_add(state, &b_default, 0); + if (rc < 0) + return rc; + state->def_hsh = b_default->hash; + + /* load the architecture token/number */ + _BPF_INSTR(instr, _BPF_OP(state->arch, BPF_LD + BPF_ABS), + _BPF_JMP_NO, _BPF_JMP_NO, _BPF_ARCH(state->arch)); + b_head = _blk_append(state, NULL, &instr); + if (b_head == NULL) + return -ENOMEM; + b_head->acc_end = _ACC_STATE_OFFSET(_BPF_OFFSET_ARCH); + rc = _hsh_add(state, &b_head, 1); + if (rc < 0) + return rc; + b_tail = b_head; + + /* generate the per-architecture filters */ + for (iter = 0; iter < col->filter_cnt; iter++) { + if (col->filters[iter]->arch->token == SCMP_ARCH_X86_64) + arch_x86_64 = iter; + if (col->filters[iter]->arch->token == SCMP_ARCH_X32) + arch_x32 = iter; + } + for (iter = 0; iter < col->filter_cnt; iter++) { + /* figure out the secondary arch filter mess */ + if (iter == arch_x86_64) { + if (arch_x32 > iter) + db_secondary = col->filters[arch_x32]; + else if (arch_x32 >= 0) + continue; + } else if (iter == arch_x32) { + if (arch_x86_64 > iter) + db_secondary = col->filters[arch_x86_64]; + else if (arch_x86_64 >= 0) + continue; + } else + db_secondary = NULL; + + /* create the filter for the architecture(s) */ + b_new = _gen_bpf_arch(state, col->filters[iter], db_secondary, + col->attr.optimize); + if (b_new == NULL) + return -ENOMEM; + b_new->prev = b_tail; + b_tail->next = b_new; + b_tail = b_new; + while (b_tail->next != NULL) + b_tail = b_tail->next; + } + + /* add a badarch action to the end */ + b_badarch->prev = b_tail; + b_badarch->next = NULL; + b_tail->next = b_badarch; + b_tail = b_badarch; + + /* reset the state to the pseudo_arch for the final resolution */ + state->arch = &pseudo_arch; + + /* resolve any TGT_NXT jumps at the top level */ + b_iter = b_head; + do { + for (iter = 0; iter < b_iter->blk_cnt; iter++) { + i_iter = &b_iter->blks[iter]; + if (i_iter->jt.type == TGT_NXT) { + b_jmp = _gen_bpf_find_nxt(b_iter, + i_iter->jt.tgt.nxt); + if (b_jmp == NULL) + return -EFAULT; + i_iter->jt = _BPF_JMP_HSH(b_jmp->hash); + } + if (i_iter->jf.type == TGT_NXT) { + b_jmp = _gen_bpf_find_nxt(b_iter, + i_iter->jf.tgt.nxt); + if (b_jmp == NULL) + return -EFAULT; + i_iter->jf = _BPF_JMP_HSH(b_jmp->hash); + } + /* we shouldn't need to worry about a TGT_NXT in k */ + } + b_iter = b_iter->next; + } while (b_iter != NULL && b_iter->next != NULL); + + /* pull in all of the TGT_PTR_HSH jumps, one layer at a time */ + b_iter = b_tail; + do { + b_jmp = NULL; + /* look for jumps - backwards (shorter jumps) */ + for (iter = b_iter->blk_cnt - 1; + (iter >= 0) && (b_jmp == NULL); + iter--) { + i_iter = &b_iter->blks[iter]; + if (i_iter->jt.type == TGT_PTR_HSH) + b_jmp = _hsh_find_once(state, + i_iter->jt.tgt.hash); + if (b_jmp == NULL && i_iter->jf.type == TGT_PTR_HSH) + b_jmp = _hsh_find_once(state, + i_iter->jf.tgt.hash); + if (b_jmp == NULL && i_iter->k.type == TGT_PTR_HSH) + b_jmp = _hsh_find_once(state, + i_iter->k.tgt.hash); + if (b_jmp != NULL) { + /* do we need to reload the accumulator? */ + if ((b_jmp->acc_start.offset != -1) && + !_ACC_CMP_EQ(b_iter->acc_end, + b_jmp->acc_start)) { + if (b_jmp->acc_start.mask != ARG_MASK_MAX) { + _BPF_INSTR(instr, + _BPF_OP(state->arch, + BPF_ALU + BPF_AND), + _BPF_JMP_NO, + _BPF_JMP_NO, + _BPF_K(state->arch, + b_jmp->acc_start.mask)); + b_jmp = _blk_prepend(state, + b_jmp, + &instr); + if (b_jmp == NULL) + return -EFAULT; + } + _BPF_INSTR(instr, + _BPF_OP(state->arch, + BPF_LD + BPF_ABS), + _BPF_JMP_NO, _BPF_JMP_NO, + _BPF_K(state->arch, + b_jmp->acc_start.offset)); + b_jmp = _blk_prepend(state, + b_jmp, &instr); + if (b_jmp == NULL) + return -EFAULT; + /* not reliant on the accumulator */ + b_jmp->acc_start = _ACC_STATE_UNDEF; + } + /* insert the new block after this block */ + b_jmp->prev = b_iter; + b_jmp->next = b_iter->next; + b_iter->next = b_jmp; + if (b_jmp->next) + b_jmp->next->prev = b_jmp; + } + } + if (b_jmp != NULL) { + while (b_tail->next != NULL) + b_tail = b_tail->next; + b_iter = b_tail; + } else + b_iter = b_iter->prev; + } while (b_iter != NULL); + + + /* NOTE - from here to the end of the function we need to fail via the + * the build_bpf_free_blks label, not just return an error; see + * the _gen_bpf_build_jmp() function for details */ + + /* check for long jumps and insert if necessary, we also verify that + * all our jump targets are valid at this point in the process */ + b_iter = b_tail; + do { + res_cnt = 0; + for (iter = b_iter->blk_cnt - 1; iter >= 0; iter--) { + i_iter = &b_iter->blks[iter]; + switch (i_iter->jt.type) { + case TGT_NONE: + case TGT_IMM: + break; + case TGT_PTR_HSH: + h_val = i_iter->jt.tgt.hash; + rc = _gen_bpf_build_jmp(state, b_tail, + b_iter, iter, + h_val); + if (rc < 0) + goto build_bpf_free_blks; + res_cnt += rc; + break; + default: + /* fatal error */ + rc = -EFAULT; + goto build_bpf_free_blks; + } + switch (i_iter->jf.type) { + case TGT_NONE: + case TGT_IMM: + break; + case TGT_PTR_HSH: + h_val = i_iter->jf.tgt.hash; + rc = _gen_bpf_build_jmp(state, b_tail, + b_iter, iter, + h_val); + if (rc < 0) + goto build_bpf_free_blks; + res_cnt += rc; + break; + default: + /* fatal error */ + rc = -EFAULT; + goto build_bpf_free_blks; + } + } + if (res_cnt == 0) + b_iter = b_iter->prev; + } while (b_iter != NULL); + + /* build the bpf program */ + do { + b_iter = b_head; + /* resolve the TGT_PTR_HSH jumps */ + for (iter = 0; iter < b_iter->blk_cnt; iter++) { + i_iter = &b_iter->blks[iter]; + if (i_iter->jt.type == TGT_PTR_HSH) { + h_val = i_iter->jt.tgt.hash; + jmp_len = b_iter->blk_cnt - (iter + 1); + b_jmp = b_iter->next; + while (b_jmp != NULL && b_jmp->hash != h_val) { + jmp_len += b_jmp->blk_cnt; + b_jmp = b_jmp->next; + } + if (b_jmp == NULL || jmp_len > _BPF_JMP_MAX) { + rc = -EFAULT; + goto build_bpf_free_blks; + } + i_iter->jt = _BPF_JMP_IMM(jmp_len); + } + if (i_iter->jf.type == TGT_PTR_HSH) { + h_val = i_iter->jf.tgt.hash; + jmp_len = b_iter->blk_cnt - (iter + 1); + b_jmp = b_iter->next; + while (b_jmp != NULL && b_jmp->hash != h_val) { + jmp_len += b_jmp->blk_cnt; + b_jmp = b_jmp->next; + } + if (b_jmp == NULL || jmp_len > _BPF_JMP_MAX) { + rc = -EFAULT; + goto build_bpf_free_blks; + } + i_iter->jf = _BPF_JMP_IMM(jmp_len); + } + if (i_iter->k.type == TGT_PTR_HSH) { + h_val = i_iter->k.tgt.hash; + jmp_len = b_iter->blk_cnt - (iter + 1); + b_jmp = b_tail; + while (b_jmp->hash != h_val) + b_jmp = b_jmp->prev; + b_jmp = b_jmp->prev; + while (b_jmp != b_iter) { + jmp_len += b_jmp->blk_cnt; + b_jmp = b_jmp->prev; + } + if (b_jmp == NULL) { + rc = -EFAULT; + goto build_bpf_free_blks; + } + i_iter->k = _BPF_K(state->arch, jmp_len); + } + } + + /* build the bpf program */ + rc = _bpf_append_blk(state->bpf, b_iter); + if (rc < 0) + goto build_bpf_free_blks; + + /* we're done with the block, free it */ + b_head = b_iter->next; + _blk_free(state, b_iter); + } while (b_head != NULL); + + return 0; + +build_bpf_free_blks: + b_iter = b_head; + while (b_iter != NULL) { + b_jmp = b_iter->next; + _hsh_remove(state, b_iter->hash); + __blk_free(state, b_iter); + b_iter = b_jmp; + } + return rc; +} + +/** + * Generate a BPF representation of the filter DB + * @param col the seccomp filter collection + * @param prgm_ptr the bpf program pointer + * + * This function generates a BPF representation of the given filter collection. + * Returns zero on success, negative values on failure. + * + */ +int gen_bpf_generate(const struct db_filter_col *col, + struct bpf_program **prgm_ptr) +{ + int rc; + struct bpf_state state; + struct bpf_program *prgm; + + if (col->filter_cnt == 0) + return -EINVAL; + + memset(&state, 0, sizeof(state)); + state.attr = &col->attr; + + state.bpf = zmalloc(sizeof(*(prgm))); + if (state.bpf == NULL) + return -ENOMEM; + + rc = _gen_bpf_build_bpf(&state, col); + if (rc == 0) { + *prgm_ptr = state.bpf; + state.bpf = NULL; + } + _state_release(&state); + + return rc; +} + +/** + * Free memory associated with a BPF representation + * @param program the BPF representation + * + * Free the memory associated with a BPF representation generated by the + * gen_bpf_generate() function. + * + */ +void gen_bpf_release(struct bpf_program *program) +{ + _program_free(program); +} diff --git a/src/gen_bpf.h b/src/gen_bpf.h new file mode 100644 index 0000000..8f886ae --- /dev/null +++ b/src/gen_bpf.h @@ -0,0 +1,43 @@ +/** + * Seccomp BPF Translator + * + * Copyright (c) 2012 Red Hat <pmoore@redhat.com> + * Author: Paul Moore <paul@paul-moore.com> + */ + +/* + * 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>. + */ + +#ifndef _TRANSLATOR_BPF_H +#define _TRANSLATOR_BPF_H + +#include <inttypes.h> + +#include "arch.h" +#include "db.h" +#include "system.h" + +/* NOTE - do not change this structure, it is part of the prctl() API */ +struct bpf_program { + uint16_t blk_cnt; + bpf_instr_raw *blks; +}; +#define BPF_PGM_SIZE(x) \ + ((x)->blk_cnt * sizeof(*((x)->blks))) + +int gen_bpf_generate(const struct db_filter_col *col, + struct bpf_program **prgm_ptr); +void gen_bpf_release(struct bpf_program *program); + +#endif diff --git a/src/gen_pfc.c b/src/gen_pfc.c new file mode 100644 index 0000000..d58f586 --- /dev/null +++ b/src/gen_pfc.c @@ -0,0 +1,507 @@ +/** + * Seccomp Pseudo Filter Code (PFC) Generator + * + * Copyright (c) 2012 Red Hat <pmoore@redhat.com> + * Author: Paul Moore <paul@paul-moore.com> + */ + +/* + * 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 <errno.h> +#include <inttypes.h> +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <unistd.h> + +/* NOTE: needed for the arch->token decoding in _pfc_arch() */ +#include <linux/audit.h> + +#include <seccomp.h> + +#include "arch.h" +#include "db.h" +#include "gen_pfc.h" +#include "helper.h" +#include "system.h" + +struct pfc_sys_list { + struct db_sys_list *sys; + struct pfc_sys_list *next; +}; + +/* XXX - we should check the fprintf() return values */ + +/** + * Display a string representation of the architecture + * @param arch the architecture definition + */ +static const char *_pfc_arch(const struct arch_def *arch) +{ + switch (arch->token) { + case SCMP_ARCH_X86: + return "x86"; + case SCMP_ARCH_X86_64: + return "x86_64"; + case SCMP_ARCH_X32: + return "x32"; + case SCMP_ARCH_ARM: + return "arm"; + case SCMP_ARCH_AARCH64: + return "aarch64"; + case SCMP_ARCH_MIPS: + return "mips"; + case SCMP_ARCH_MIPSEL: + return "mipsel"; + case SCMP_ARCH_MIPS64: + return "mips64"; + case SCMP_ARCH_MIPSEL64: + return "mipsel64"; + case SCMP_ARCH_MIPS64N32: + return "mips64n32"; + case SCMP_ARCH_MIPSEL64N32: + return "mipsel64n32"; + case SCMP_ARCH_PARISC: + return "parisc"; + case SCMP_ARCH_PARISC64: + return "parisc64"; + case SCMP_ARCH_PPC64: + return "ppc64"; + case SCMP_ARCH_PPC64LE: + return "ppc64le"; + case SCMP_ARCH_PPC: + return "ppc"; + case SCMP_ARCH_S390X: + return "s390x"; + case SCMP_ARCH_S390: + return "s390"; + case SCMP_ARCH_RISCV64: + return "riscv64"; + default: + return "UNKNOWN"; + } +} + +/** + * Display a string representation of the node argument + * @param fds the file stream to send the output + * @param arch the architecture definition + * @param node the node + */ +static void _pfc_arg(FILE *fds, + const struct arch_def *arch, + const struct db_arg_chain_tree *node) +{ + if (arch->size == ARCH_SIZE_64) { + if (arch_arg_offset_hi(arch, node->arg) == node->arg_offset) + fprintf(fds, "$a%d.hi32", node->arg); + else + fprintf(fds, "$a%d.lo32", node->arg); + } else + fprintf(fds, "$a%d", node->arg); +} + +/** + * Display a string representation of the filter action + * @param fds the file stream to send the output + * @param action the action + */ +static void _pfc_action(FILE *fds, uint32_t action) +{ + switch (action & SECCOMP_RET_ACTION_FULL) { + case SCMP_ACT_KILL_PROCESS: + fprintf(fds, "action KILL_PROCESS;\n"); + break; + case SCMP_ACT_KILL_THREAD: + fprintf(fds, "action KILL;\n"); + break; + case SCMP_ACT_TRAP: + fprintf(fds, "action TRAP;\n"); + break; + case SCMP_ACT_ERRNO(0): + fprintf(fds, "action ERRNO(%u);\n", (action & 0x0000ffff)); + break; + case SCMP_ACT_TRACE(0): + fprintf(fds, "action TRACE(%u);\n", (action & 0x0000ffff)); + break; + case SCMP_ACT_LOG: + fprintf(fds, "action LOG;\n"); + break; + case SCMP_ACT_ALLOW: + fprintf(fds, "action ALLOW;\n"); + break; + default: + fprintf(fds, "action 0x%x;\n", action); + } +} + +/** + * Indent the output stream + * @param fds the file stream to send the output + * @param lvl the indentation level + * + * This function indents the output stream with whitespace based on the + * requested indentation level. + */ +static void _indent(FILE *fds, unsigned int lvl) +{ + while (lvl-- > 0) + fprintf(fds, " "); +} + +/** + * Generate the pseudo filter code for an argument chain + * @param arch the architecture definition + * @param node the head of the argument chain + * @param lvl the indentation level + * @param fds the file stream to send the output + * + * This function generates the pseudo filter code representation of the given + * argument chain and writes it to the given output stream. + * + */ +static void _gen_pfc_chain(const struct arch_def *arch, + const struct db_arg_chain_tree *node, + unsigned int lvl, FILE *fds) +{ + const struct db_arg_chain_tree *c_iter; + + /* get to the start */ + c_iter = node; + while (c_iter->lvl_prv != NULL) + c_iter = c_iter->lvl_prv; + + while (c_iter != NULL) { + /* comparison operation */ + _indent(fds, lvl); + fprintf(fds, "if ("); + _pfc_arg(fds, arch, c_iter); + switch (c_iter->op) { + case SCMP_CMP_EQ: + fprintf(fds, " == "); + break; + case SCMP_CMP_GE: + fprintf(fds, " >= "); + break; + case SCMP_CMP_GT: + fprintf(fds, " > "); + break; + case SCMP_CMP_MASKED_EQ: + fprintf(fds, " & 0x%.8x == ", c_iter->mask); + break; + case SCMP_CMP_NE: + case SCMP_CMP_LT: + case SCMP_CMP_LE: + default: + fprintf(fds, " ??? "); + } + fprintf(fds, "%u)\n", c_iter->datum); + + /* true result */ + if (c_iter->act_t_flg) { + _indent(fds, lvl + 1); + _pfc_action(fds, c_iter->act_t); + } else if (c_iter->nxt_t != NULL) + _gen_pfc_chain(arch, c_iter->nxt_t, lvl + 1, fds); + + /* false result */ + if (c_iter->act_f_flg) { + _indent(fds, lvl); + fprintf(fds, "else\n"); + _indent(fds, lvl + 1); + _pfc_action(fds, c_iter->act_f); + } else if (c_iter->nxt_f != NULL) { + _indent(fds, lvl); + fprintf(fds, "else\n"); + _gen_pfc_chain(arch, c_iter->nxt_f, lvl + 1, fds); + } + + c_iter = c_iter->lvl_nxt; + } +} + +/** + * Generate pseudo filter code for a syscall + * @param arch the architecture definition + * @param sys the syscall filter + * @param fds the file stream to send the output + * + * This function generates a pseudo filter code representation of the given + * syscall filter and writes it to the given output stream. + * + */ +static void _gen_pfc_syscall(const struct arch_def *arch, + const struct db_sys_list *sys, FILE *fds, + int lvl) +{ + unsigned int sys_num = sys->num; + const char *sys_name = arch_syscall_resolve_num(arch, sys_num); + + _indent(fds, lvl); + fprintf(fds, "# filter for syscall \"%s\" (%u) [priority: %d]\n", + (sys_name ? sys_name : "UNKNOWN"), sys_num, sys->priority); + _indent(fds, lvl); + fprintf(fds, "if ($syscall == %u)\n", sys_num); + if (sys->chains == NULL) { + _indent(fds, lvl + 1); + _pfc_action(fds, sys->action); + } else + _gen_pfc_chain(arch, sys->chains, lvl + 1, fds); +} + +#define SYSCALLS_PER_NODE (4) +static int _get_bintree_levels(unsigned int syscall_cnt, + uint32_t optimize) +{ + unsigned int i = 0, max_level; + + if (optimize != 2) + /* Only use a binary tree if requested */ + return 0; + + if (syscall_cnt == 0) + return 0; + + do { + max_level = SYSCALLS_PER_NODE << i; + i++; + } while(max_level < syscall_cnt); + + return i; +} + +static int _get_bintree_syscall_num(const struct pfc_sys_list *cur, + int lookahead_cnt, + int *const num) +{ + while (lookahead_cnt > 0 && cur != NULL) { + cur = cur->next; + lookahead_cnt--; + } + + if (cur == NULL) + return -EFAULT; + + *num = cur->sys->num; + return 0; +} + +static int _sys_num_sort(struct db_sys_list *syscalls, + struct pfc_sys_list **p_head) +{ + struct pfc_sys_list *p_iter = NULL, *p_new, *p_prev; + struct db_sys_list *s_iter; + + db_list_foreach(s_iter, syscalls) { + p_new = zmalloc(sizeof(*p_new)); + if (p_new == NULL) { + return -ENOMEM; + } + p_new->sys = s_iter; + + p_prev = NULL; + p_iter = *p_head; + while (p_iter != NULL && + s_iter->num < p_iter->sys->num) { + p_prev = p_iter; + p_iter = p_iter->next; + } + if (*p_head == NULL) + *p_head = p_new; + else if (p_prev == NULL) { + p_new->next = *p_head; + *p_head = p_new; + } else { + p_new->next = p_iter; + p_prev->next = p_new; + } + } + + return 0; +} + +static int _sys_priority_sort(struct db_sys_list *syscalls, + struct pfc_sys_list **p_head) +{ + struct pfc_sys_list *p_iter = NULL, *p_new, *p_prev; + struct db_sys_list *s_iter; + + db_list_foreach(s_iter, syscalls) { + p_new = zmalloc(sizeof(*p_new)); + if (p_new == NULL) { + return -ENOMEM; + } + p_new->sys = s_iter; + + p_prev = NULL; + p_iter = *p_head; + while (p_iter != NULL && + s_iter->priority < p_iter->sys->priority) { + p_prev = p_iter; + p_iter = p_iter->next; + } + if (*p_head == NULL) + *p_head = p_new; + else if (p_prev == NULL) { + p_new->next = *p_head; + *p_head = p_new; + } else { + p_new->next = p_iter; + p_prev->next = p_new; + } + } + + return 0; +} + +static int _sys_sort(struct db_sys_list *syscalls, + struct pfc_sys_list **p_head, + uint32_t optimize) +{ + if (optimize != 2) + return _sys_priority_sort(syscalls, p_head); + else + /* sort by number for the binary tree */ + return _sys_num_sort(syscalls, p_head); +} + +/** + * Generate pseudo filter code for an architecture + * @param col the seccomp filter collection + * @param db the single seccomp filter + * @param fds the file stream to send the output + * + * This function generates a pseudo filter code representation of the given + * filter DB and writes it to the given output stream. Returns zero on + * success, negative values on failure. + * + */ +static int _gen_pfc_arch(const struct db_filter_col *col, + const struct db_filter *db, FILE *fds, + uint32_t optimize) +{ + int rc = 0, i = 0, lookahead_num; + unsigned int syscall_cnt = 0, bintree_levels, level, indent = 1; + struct pfc_sys_list *p_iter = NULL, *p_head = NULL; + + /* sort the syscall list */ + rc = _sys_sort(db->syscalls, &p_head, optimize); + if (rc < 0) + goto arch_return; + + bintree_levels = _get_bintree_levels(db->syscall_cnt, optimize); + + fprintf(fds, "# filter for arch %s (%u)\n", + _pfc_arch(db->arch), db->arch->token_bpf); + fprintf(fds, "if ($arch == %u)\n", db->arch->token_bpf); + p_iter = p_head; + while (p_iter != NULL) { + if (!p_iter->sys->valid) { + p_iter = p_iter->next; + continue; + } + + for (i = bintree_levels - 1; i > 0; i--) { + level = SYSCALLS_PER_NODE << i; + + if (syscall_cnt == 0 || (syscall_cnt % level) == 0) { + rc = _get_bintree_syscall_num(p_iter, level / 2, + &lookahead_num); + if (rc < 0) + /* We have reached the end of the bintree. + * There aren't enough syscalls to construct + * any more if-elses. + */ + continue; + _indent(fds, indent); + fprintf(fds, "if ($syscall > %u)\n", lookahead_num); + indent++; + } else if ((syscall_cnt % (level / 2)) == 0) { + lookahead_num = p_iter->sys->num; + _indent(fds, indent - 1); + fprintf(fds, "else # ($syscall <= %u)\n", + p_iter->sys->num); + } + + } + + _gen_pfc_syscall(db->arch, p_iter->sys, fds, indent); + syscall_cnt++; + p_iter = p_iter->next; + + /* undo the indentations as the else statements complete */ + for (i = 0; i < bintree_levels; i++) { + if (syscall_cnt % ((SYSCALLS_PER_NODE * 2) << i) == 0) + indent--; + } + } + _indent(fds, 1); + fprintf(fds, "# default action\n"); + _indent(fds, 1); + _pfc_action(fds, col->attr.act_default); + +arch_return: + while (p_head != NULL) { + p_iter = p_head; + p_head = p_head->next; + free(p_iter); + } + return rc; +} +/** + * Generate a pseudo filter code string representation + * @param col the seccomp filter collection + * @param fd the fd to send the output + * + * This function generates a pseudo filter code representation of the given + * filter collection and writes it to the given fd. Returns zero on success, + * negative errno values on failure. + * + */ +int gen_pfc_generate(const struct db_filter_col *col, int fd) +{ + int newfd; + unsigned int iter; + FILE *fds; + + newfd = dup(fd); + if (newfd < 0) + return -errno; + fds = fdopen(newfd, "a"); + if (fds == NULL) { + close(newfd); + return -errno; + } + + /* generate the pfc */ + fprintf(fds, "#\n"); + fprintf(fds, "# pseudo filter code start\n"); + fprintf(fds, "#\n"); + + for (iter = 0; iter < col->filter_cnt; iter++) + _gen_pfc_arch(col, col->filters[iter], fds, + col->attr.optimize); + + fprintf(fds, "# invalid architecture action\n"); + _pfc_action(fds, col->attr.act_badarch); + fprintf(fds, "#\n"); + fprintf(fds, "# pseudo filter code end\n"); + fprintf(fds, "#\n"); + + fflush(fds); + fclose(fds); + + return 0; +} diff --git a/src/gen_pfc.h b/src/gen_pfc.h new file mode 100644 index 0000000..ceb932c --- /dev/null +++ b/src/gen_pfc.h @@ -0,0 +1,29 @@ +/** + * Seccomp String Translator + * + * Copyright (c) 2012 Red Hat <pmoore@redhat.com> + * Author: Paul Moore <paul@paul-moore.com> + */ + +/* + * 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>. + */ + +#ifndef _TRANSLATOR_STR_H +#define _TRANSLATOR_STR_H + +#include "db.h" + +int gen_pfc_generate(const struct db_filter_col *col, int fd); + +#endif diff --git a/src/hash.c b/src/hash.c new file mode 100644 index 0000000..4435900 --- /dev/null +++ b/src/hash.c @@ -0,0 +1,90 @@ +/** + * Seccomp Library hash code + * + */ + +/* + * This code is based on MurmurHash3.cpp from Austin Appleby and is placed in + * the public domain. + * + * https://github.com/aappleby/smhasher + * + */ + +#include <stdlib.h> +#include <inttypes.h> + +#include "hash.h" + +static inline uint32_t getblock32(const uint32_t *p, int i) +{ + return p[i]; +} + +static inline uint32_t rotl32(uint32_t x, int8_t r) +{ + return (x << r) | (x >> (32 - r)); +} + +static inline uint32_t fmix32(uint32_t h) +{ + h ^= h >> 16; + h *= 0x85ebca6b; + h ^= h >> 13; + h *= 0xc2b2ae35; + h ^= h >> 16; + + return h; +} + +/* NOTE: this is an implementation of MurmurHash3_x86_32 */ +uint32_t hash(const void *key, size_t length) +{ + const uint8_t *data = (const uint8_t *)key; + const uint32_t *blocks; + const uint8_t *tail; + const int nblocks = length / 4; + const uint32_t c1 = 0xcc9e2d51; + const uint32_t c2 = 0x1b873593; + uint32_t k1; + uint32_t k2 = 0; + int i; + + /* NOTE: we always force a seed of 0 */ + uint32_t h1 = 0; + + /* body */ + blocks = (const uint32_t *)(data + nblocks * 4); + for(i = -nblocks; i; i++) { + k1 = getblock32(blocks, i); + + k1 *= c1; + k1 = rotl32(k1, 15); + k1 *= c2; + + h1 ^= k1; + h1 = rotl32(h1, 13); + h1 = h1 * 5 + 0xe6546b64; + } + + /* tail */ + tail = (const uint8_t *)(data + nblocks * 4); + switch(length & 3) { + case 3: + k2 ^= tail[2] << 16; + case 2: + k2 ^= tail[1] << 8; + case 1: + k2 ^= tail[0]; + k2 *= c1; + k2 = rotl32(k2, 15); + k2 *= c2; + h1 ^= k2; + }; + + /* finalization */ + h1 ^= length; + h1 = fmix32(h1); + + return h1; +} diff --git a/src/hash.h b/src/hash.h new file mode 100644 index 0000000..357131d --- /dev/null +++ b/src/hash.h @@ -0,0 +1,16 @@ +/** + * Seccomp Library hash code + * + * See hash.c for information on the implementation. + * + */ + +#ifndef _HASH_H +#define _HASH_H + +#include <inttypes.h> + +uint32_t hash(const void *key, size_t length); + +#endif + diff --git a/src/helper.c b/src/helper.c new file mode 100644 index 0000000..c746749 --- /dev/null +++ b/src/helper.c @@ -0,0 +1,49 @@ +/** + * Helper functions for libseccomp + * + * Copyright (c) 2017 Red Hat <pmoore@redhat.com> + * Author: Paul Moore <paul@paul-moore.com> + */ + +/* + * 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 <string.h> + +#include "helper.h" + +/** + * Allocate memory + * @param size the size of the buffer to allocate + * + * This function allocates a buffer of the given size, initializes it to zero, + * and returns a pointer to buffer on success. NULL is returned on failure. + * + */ +void *zmalloc(size_t size) +{ + void *ptr; + + /* NOTE: unlike malloc() zero size allocations always return NULL */ + if (size == 0) + return NULL; + + ptr = malloc(size); + if (!ptr) + return NULL; + memset(ptr, 0, size); + + return ptr; +} diff --git a/src/helper.h b/src/helper.h new file mode 100644 index 0000000..2d610ce --- /dev/null +++ b/src/helper.h @@ -0,0 +1,27 @@ +/** + * Helper functions for libseccomp + * + * Copyright (c) 2017 Red Hat <pmoore@redhat.com> + * Author: Paul Moore <paul@paul-moore.com> + */ + +/* + * 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>. + */ + +#ifndef _FILTER_HELPER_H +#define _FILTER_HELPER_H + +void *zmalloc(size_t size); + +#endif diff --git a/src/python/Makefile.am b/src/python/Makefile.am new file mode 100644 index 0000000..5166412 --- /dev/null +++ b/src/python/Makefile.am @@ -0,0 +1,52 @@ +#### +# Seccomp Library Python Bindings +# + +# +# 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>. +# + +PY_DISTUTILS = \ + VERSION_RELEASE="@PACKAGE_VERSION@" \ + CPPFLAGS="-I\${top_srcdir}/include ${AM_CPPFLAGS} ${CPPFLAGS}" \ + CFLAGS="${AM_CFLAGS} ${CFLAGS}" \ + LDFLAGS="${AM_LDFLAGS} ${LDFLAGS}" \ + ${PYTHON} ${srcdir}/setup.py + +# support silent builds +PY_BUILD_0 = @echo " PYTHON " $@; ${PY_DISTUTILS} -q build +PY_BUILD_1 = ${PY_DISTUTILS} build +PY_BUILD_ = ${PY_BUILD_0} +PY_BUILD = ${PY_BUILD_@AM_V@} + +PY_INSTALL = ${PY_DISTUTILS} install + +EXTRA_DIST = libseccomp.pxd seccomp.pyx setup.py + +all-local: build + +build: ../libseccomp.la libseccomp.pxd seccomp.pyx setup.py + [ ${srcdir} == ${builddir} ] || cp ${srcdir}/seccomp.pyx ${builddir} + ${PY_BUILD} && touch build + +install-exec-local: build + ${PY_INSTALL} --install-lib=${DESTDIR}/${pyexecdir} \ + --record=${DESTDIR}/${pyexecdir}/install_files.txt + +uninstall-local: + cat ${DESTDIR}/${pyexecdir}/install_files.txt | xargs ${RM} -f + ${RM} -f ${DESTDIR}/${pyexecdir}/install_files.txt + +clean-local: + [ ${srcdir} == ${builddir} ] || ${RM} -f ${builddir}/seccomp.pyx + ${RM} -rf seccomp.c build dist seccomp.egg-info diff --git a/src/python/Makefile.in b/src/python/Makefile.in new file mode 100644 index 0000000..de9800d --- /dev/null +++ b/src/python/Makefile.in @@ -0,0 +1,519 @@ +# Makefile.in generated by automake 1.16.5 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2021 Free Software Foundation, Inc. + +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +#### +# Seccomp Library Python Bindings +# + +# +# 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>. +# +VPATH = @srcdir@ +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +subdir = src/python +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/ax_code_coverage.m4 \ + $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ + $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ + $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/configure.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +SOURCES = +DIST_SOURCES = +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +am__DIST_COMMON = $(srcdir)/Makefile.in +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AM_CFLAGS = @AM_CFLAGS@ +AM_CPPFLAGS = @AM_CPPFLAGS@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AM_LDFLAGS = @AM_LDFLAGS@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CODE_COVERAGE_CFLAGS = @CODE_COVERAGE_CFLAGS@ +CODE_COVERAGE_CPPFLAGS = @CODE_COVERAGE_CPPFLAGS@ +CODE_COVERAGE_CXXFLAGS = @CODE_COVERAGE_CXXFLAGS@ +CODE_COVERAGE_ENABLED = @CODE_COVERAGE_ENABLED@ +CODE_COVERAGE_LDFLAGS = @CODE_COVERAGE_LDFLAGS@ +CODE_COVERAGE_LIBS = @CODE_COVERAGE_LIBS@ +CPPFLAGS = @CPPFLAGS@ +CSCOPE = @CSCOPE@ +CTAGS = @CTAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +ETAGS = @ETAGS@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +FILECMD = @FILECMD@ +GCOV = @GCOV@ +GENHTML = @GENHTML@ +GPERF = @GPERF@ +GREP = @GREP@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LCOV = @LCOV@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PYTHON = @PYTHON@ +PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ +PYTHON_PLATFORM = @PYTHON_PLATFORM@ +PYTHON_PREFIX = @PYTHON_PREFIX@ +PYTHON_VERSION = @PYTHON_VERSION@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +VERSION_MAJOR = @VERSION_MAJOR@ +VERSION_MICRO = @VERSION_MICRO@ +VERSION_MINOR = @VERSION_MINOR@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +cython = @cython@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +have_coverity = @have_coverity@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +pkgpyexecdir = @pkgpyexecdir@ +pkgpythondir = @pkgpythondir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +pyexecdir = @pyexecdir@ +pythondir = @pythondir@ +runstatedir = @runstatedir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +PY_DISTUTILS = \ + VERSION_RELEASE="@PACKAGE_VERSION@" \ + CPPFLAGS="-I\${top_srcdir}/include ${AM_CPPFLAGS} ${CPPFLAGS}" \ + CFLAGS="${AM_CFLAGS} ${CFLAGS}" \ + LDFLAGS="${AM_LDFLAGS} ${LDFLAGS}" \ + ${PYTHON} ${srcdir}/setup.py + + +# support silent builds +PY_BUILD_0 = @echo " PYTHON " $@; ${PY_DISTUTILS} -q build +PY_BUILD_1 = ${PY_DISTUTILS} build +PY_BUILD_ = ${PY_BUILD_0} +PY_BUILD = ${PY_BUILD_@AM_V@} +PY_INSTALL = ${PY_DISTUTILS} install +EXTRA_DIST = libseccomp.pxd seccomp.pyx setup.py +all: all-am + +.SUFFIXES: +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign src/python/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --foreign src/python/Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs +tags TAGS: + +ctags CTAGS: + +cscope cscopelist: + +distdir: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) distdir-am + +distdir-am: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile all-local +installdirs: +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-libtool clean-local mostlyclean-am + +distclean: distclean-am + -rm -f Makefile +distclean-am: clean-am distclean-generic + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: install-exec-local + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-generic mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-local + +.MAKE: install-am install-strip + +.PHONY: all all-am all-local check check-am clean clean-generic \ + clean-libtool clean-local cscopelist-am ctags-am distclean \ + distclean-generic distclean-libtool distdir dvi dvi-am html \ + html-am info info-am install install-am install-data \ + install-data-am install-dvi install-dvi-am install-exec \ + install-exec-am install-exec-local install-html \ + install-html-am install-info install-info-am install-man \ + install-pdf install-pdf-am install-ps install-ps-am \ + install-strip installcheck installcheck-am installdirs \ + maintainer-clean maintainer-clean-generic mostlyclean \ + mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ + tags-am uninstall uninstall-am uninstall-local + +.PRECIOUS: Makefile + + +all-local: build + +build: ../libseccomp.la libseccomp.pxd seccomp.pyx setup.py + [ ${srcdir} == ${builddir} ] || cp ${srcdir}/seccomp.pyx ${builddir} + ${PY_BUILD} && touch build + +install-exec-local: build + ${PY_INSTALL} --install-lib=${DESTDIR}/${pyexecdir} \ + --record=${DESTDIR}/${pyexecdir}/install_files.txt + +uninstall-local: + cat ${DESTDIR}/${pyexecdir}/install_files.txt | xargs ${RM} -f + ${RM} -f ${DESTDIR}/${pyexecdir}/install_files.txt + +clean-local: + [ ${srcdir} == ${builddir} ] || ${RM} -f ${builddir}/seccomp.pyx + ${RM} -rf seccomp.c build dist seccomp.egg-info + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/src/python/libseccomp.pxd b/src/python/libseccomp.pxd new file mode 100644 index 0000000..0629bf1 --- /dev/null +++ b/src/python/libseccomp.pxd @@ -0,0 +1,172 @@ +# +# Seccomp Library Python Bindings +# +# Copyright (c) 2012,2013 Red Hat <pmoore@redhat.com> +# Author: Paul Moore <paul@paul-moore.com> +# + +# +# 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>. +# + +from libc.stdint cimport int8_t, int16_t, int32_t, int64_t +from libc.stdint cimport uint8_t, uint16_t, uint32_t, uint64_t + +cdef extern from "seccomp.h": + + cdef struct scmp_version: + unsigned int major + unsigned int minor + unsigned int micro + + ctypedef void* scmp_filter_ctx + + cdef enum: + SCMP_ARCH_NATIVE + SCMP_ARCH_X86 + SCMP_ARCH_X86_64 + SCMP_ARCH_X32 + SCMP_ARCH_ARM + SCMP_ARCH_AARCH64 + SCMP_ARCH_MIPS + SCMP_ARCH_MIPS64 + SCMP_ARCH_MIPS64N32 + SCMP_ARCH_MIPSEL + SCMP_ARCH_MIPSEL64 + SCMP_ARCH_MIPSEL64N32 + SCMP_ARCH_PARISC + SCMP_ARCH_PARISC64 + SCMP_ARCH_PPC + SCMP_ARCH_PPC64 + SCMP_ARCH_PPC64LE + SCMP_ARCH_S390 + SCMP_ARCH_S390X + SCMP_ARCH_RISCV64 + + cdef enum scmp_filter_attr: + SCMP_FLTATR_ACT_DEFAULT + SCMP_FLTATR_ACT_BADARCH + SCMP_FLTATR_CTL_NNP + SCMP_FLTATR_CTL_TSYNC + SCMP_FLTATR_API_TSKIP + SCMP_FLTATR_CTL_LOG + SCMP_FLTATR_CTL_SSB + SCMP_FLTATR_CTL_OPTIMIZE + SCMP_FLTATR_API_SYSRAWRC + + cdef enum scmp_compare: + SCMP_CMP_NE + SCMP_CMP_LT + SCMP_CMP_LE + SCMP_CMP_EQ + SCMP_CMP_GE + SCMP_CMP_GT + SCMP_CMP_MASKED_EQ + + cdef enum: + SCMP_ACT_KILL_PROCESS + SCMP_ACT_KILL + SCMP_ACT_TRAP + SCMP_ACT_LOG + SCMP_ACT_ALLOW + SCMP_ACT_NOTIFY + unsigned int SCMP_ACT_ERRNO(int errno) + unsigned int SCMP_ACT_TRACE(int value) + + ctypedef uint64_t scmp_datum_t + + cdef struct scmp_arg_cmp: + unsigned int arg + scmp_compare op + scmp_datum_t datum_a + scmp_datum_t datum_b + + cdef struct seccomp_data: + int nr + uint32_t arch + uint64_t instruction_pointer + uint64_t args[6] + + cdef struct seccomp_notif_sizes: + uint16_t seccomp_notif + uint16_t seccomp_notif_resp + uint16_t seccomp_data + + cdef struct seccomp_notif: + uint64_t id + uint32_t pid + uint32_t flags + seccomp_data data + + cdef struct seccomp_notif_resp: + uint64_t id + int64_t val + int32_t error + uint32_t flags + + scmp_version *seccomp_version() + + unsigned int seccomp_api_get() + int seccomp_api_set(unsigned int level) + + scmp_filter_ctx seccomp_init(uint32_t def_action) + int seccomp_reset(scmp_filter_ctx ctx, uint32_t def_action) + void seccomp_release(scmp_filter_ctx ctx) + + int seccomp_merge(scmp_filter_ctx ctx_dst, scmp_filter_ctx ctx_src) + + uint32_t seccomp_arch_resolve_name(char *arch_name) + uint32_t seccomp_arch_native() + int seccomp_arch_exist(scmp_filter_ctx ctx, int arch_token) + int seccomp_arch_add(scmp_filter_ctx ctx, int arch_token) + int seccomp_arch_remove(scmp_filter_ctx ctx, int arch_token) + + int seccomp_load(scmp_filter_ctx ctx) + + int seccomp_attr_get(scmp_filter_ctx ctx, + scmp_filter_attr attr, uint32_t* value) + int seccomp_attr_set(scmp_filter_ctx ctx, + scmp_filter_attr attr, uint32_t value) + + char *seccomp_syscall_resolve_num_arch(int arch_token, int num) + int seccomp_syscall_resolve_name_arch(int arch_token, char *name) + int seccomp_syscall_resolve_name_rewrite(int arch_token, char *name) + int seccomp_syscall_resolve_name(char *name) + int seccomp_syscall_priority(scmp_filter_ctx ctx, + int syscall, uint8_t priority) + + int seccomp_rule_add(scmp_filter_ctx ctx, uint32_t action, + int syscall, unsigned int arg_cnt, ...) + int seccomp_rule_add_array(scmp_filter_ctx ctx, + uint32_t action, int syscall, + unsigned int arg_cnt, + scmp_arg_cmp *arg_array) + int seccomp_rule_add_exact(scmp_filter_ctx ctx, uint32_t action, + int syscall, unsigned int arg_cnt, ...) + int seccomp_rule_add_exact_array(scmp_filter_ctx ctx, + uint32_t action, int syscall, + unsigned int arg_cnt, + scmp_arg_cmp *arg_array) + + int seccomp_notify_alloc(seccomp_notif **req, seccomp_notif_resp **resp) + void seccomp_notify_free(seccomp_notif *req, seccomp_notif_resp *resp) + int seccomp_notify_receive(int fd, seccomp_notif *req) + int seccomp_notify_respond(int fd, seccomp_notif_resp *resp) + int seccomp_notify_id_valid(int fd, uint64_t id) + int seccomp_notify_fd(scmp_filter_ctx ctx) + + int seccomp_export_pfc(scmp_filter_ctx ctx, int fd) + int seccomp_export_bpf(scmp_filter_ctx ctx, int fd) + +# kate: syntax python; +# kate: indent-mode python; space-indent on; indent-width 4; mixedindent off; diff --git a/src/python/seccomp.pyx b/src/python/seccomp.pyx new file mode 100644 index 0000000..2eeabc1 --- /dev/null +++ b/src/python/seccomp.pyx @@ -0,0 +1,1048 @@ +# +# Seccomp Library Python Bindings +# +# Copyright (c) 2012,2013,2017 Red Hat <pmoore@redhat.com> +# Author: Paul Moore <paul@paul-moore.com> +# + +# +# 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>. +# + +# cython: language_level = 3str + +""" Python bindings for the libseccomp library + +The libseccomp library provides and easy to use, platform independent, +interface to the Linux Kernel's syscall filtering mechanism: seccomp. The +libseccomp API is designed to abstract away the underlying BPF based +syscall filter language and present a more conventional function-call +based filtering interface that should be familiar to, and easily adopted +by application developers. + +Filter action values: + KILL_PROCESS - kill the process + KILL - kill the thread + LOG - allow the syscall to be executed after the action has been logged + ALLOW - allow the syscall to execute + TRAP - a SIGSYS signal will be thrown + NOTIFY - a notification event will be sent via the notification API + ERRNO(x) - syscall will return (x) + TRACE(x) - if the process is being traced, (x) will be returned to the + tracing process via PTRACE_EVENT_SECCOMP and the + PTRACE_GETEVENTMSG option + +Argument comparison values (see the Arg class): + + NE - arg != datum_a + LT - arg < datum_a + LE - arg <= datum_a + EQ - arg == datum_a + GT - arg > datum_a + GE - arg >= datum_a + MASKED_EQ - (arg & datum_a) == datum_b + + +Example: + + import sys + from seccomp import * + + # create a filter object with a default KILL action + f = SyscallFilter(defaction=KILL) + + # add some basic syscalls which python typically wants + f.add_rule(ALLOW, "rt_sigaction") + f.add_rule(ALLOW, "rt_sigreturn") + f.add_rule(ALLOW, "exit_group") + f.add_rule(ALLOW, "brk") + + # add syscall filter rules to allow certain syscalls + f.add_rule(ALLOW, "open") + f.add_rule(ALLOW, "close") + f.add_rule(ALLOW, "read", Arg(0, EQ, sys.stdin.fileno())) + f.add_rule(ALLOW, "write", Arg(0, EQ, sys.stdout.fileno())) + f.add_rule(ALLOW, "write", Arg(0, EQ, sys.stderr.fileno())) + + # load the filter into the kernel + f.load() +""" +__author__ = 'Paul Moore <paul@paul-moore.com>' +__date__ = "3 February 2017" + +from cpython.version cimport PY_MAJOR_VERSION +from libc.stdint cimport int8_t, int16_t, int32_t, int64_t +from libc.stdint cimport uint8_t, uint16_t, uint32_t, uint64_t +from libc.stdlib cimport free +import errno + +cimport libseccomp + +def c_str(string): + """ Convert a Python string to a C string. + + Arguments: + string - the Python string + + Description: + Convert the Python string into a form usable by C taking into consideration + the Python major version, e.g. Python 2.x or Python 3.x. + See http://docs.cython.org/en/latest/src/tutorial/strings.html for more + information. + """ + if PY_MAJOR_VERSION < 3: + return string + else: + return bytes(string, "ascii") + +KILL_PROCESS = libseccomp.SCMP_ACT_KILL_PROCESS +KILL = libseccomp.SCMP_ACT_KILL +TRAP = libseccomp.SCMP_ACT_TRAP +LOG = libseccomp.SCMP_ACT_LOG +ALLOW = libseccomp.SCMP_ACT_ALLOW +NOTIFY = libseccomp.SCMP_ACT_NOTIFY +def ERRNO(int errno): + """The action ERRNO(x) means that the syscall will return (x). + To conform to Linux syscall calling conventions, the syscall return + value should almost always be a negative number. + """ + return libseccomp.SCMP_ACT_ERRNO(errno) +def TRACE(int value): + """The action TRACE(x) means that, if the process is being traced, (x) + will be returned to the tracing process via PTRACE_EVENT_SECCOMP + and the PTRACE_GETEVENTMSG option. + """ + return libseccomp.SCMP_ACT_TRACE(value) + +NE = libseccomp.SCMP_CMP_NE +LT = libseccomp.SCMP_CMP_LT +LE = libseccomp.SCMP_CMP_LE +EQ = libseccomp.SCMP_CMP_EQ +GE = libseccomp.SCMP_CMP_GE +GT = libseccomp.SCMP_CMP_GT +MASKED_EQ = libseccomp.SCMP_CMP_MASKED_EQ + +def system_arch(): + """ Return the system architecture value. + + Description: + Returns the native system architecture value. + """ + return libseccomp.seccomp_arch_native() + +def resolve_syscall(arch, syscall): + """ Resolve the syscall. + + Arguments: + arch - the architecture value, e.g. Arch.* + syscall - the syscall name or number + + Description: + Resolve an architecture's syscall name to the correct number or the + syscall number to the correct name. + """ + cdef char *ret_str + + if isinstance(syscall, basestring): + return libseccomp.seccomp_syscall_resolve_name_rewrite(arch, + c_str(syscall)) + elif isinstance(syscall, int): + ret_str = libseccomp.seccomp_syscall_resolve_num_arch(arch, syscall) + if ret_str is NULL: + raise ValueError('Unknown syscall %d on arch %d' % (syscall, arch)) + else: + return ret_str + else: + raise TypeError("Syscall must either be an int or str type") + +def get_api(): + """ Query the level of API support + + Description: + Returns the API level value indicating the current supported + functionality. + """ + level = libseccomp.seccomp_api_get() + if level < 0: + raise RuntimeError(str.format("Library error (errno = {0})", level)) + + return level + +def set_api(unsigned int level): + """ Set the level of API support + + Arguments: + level - the API level + + Description: + This function forcibly sets the API level at runtime. General use + of this function is strongly discouraged. + """ + rc = libseccomp.seccomp_api_set(level) + if rc == -errno.EINVAL: + raise ValueError("Invalid level") + elif rc != 0: + raise RuntimeError(str.format("Library error (errno = {0})", rc)) + +cdef class Arch: + """ Python object representing the SyscallFilter architecture values. + + Data values: + NATIVE - the native architecture + X86 - 32-bit x86 + X86_64 - 64-bit x86 + X32 - 64-bit x86 using the x32 ABI + ARM - ARM + AARCH64 - 64-bit ARM + MIPS - MIPS O32 ABI + MIPS64 - MIPS 64-bit ABI + MIPS64N32 - MIPS N32 ABI + MIPSEL - MIPS little endian O32 ABI + MIPSEL64 - MIPS little endian 64-bit ABI + MIPSEL64N32 - MIPS little endian N32 ABI + PARISC - 32-bit PA-RISC + PARISC64 - 64-bit PA-RISC + PPC64 - 64-bit PowerPC + PPC - 32-bit PowerPC + RISCV64 - 64-bit RISC-V + """ + + cdef int _token + + NATIVE = libseccomp.SCMP_ARCH_NATIVE + X86 = libseccomp.SCMP_ARCH_X86 + X86_64 = libseccomp.SCMP_ARCH_X86_64 + X32 = libseccomp.SCMP_ARCH_X32 + ARM = libseccomp.SCMP_ARCH_ARM + AARCH64 = libseccomp.SCMP_ARCH_AARCH64 + MIPS = libseccomp.SCMP_ARCH_MIPS + MIPS64 = libseccomp.SCMP_ARCH_MIPS64 + MIPS64N32 = libseccomp.SCMP_ARCH_MIPS64N32 + MIPSEL = libseccomp.SCMP_ARCH_MIPSEL + MIPSEL64 = libseccomp.SCMP_ARCH_MIPSEL64 + MIPSEL64N32 = libseccomp.SCMP_ARCH_MIPSEL64N32 + PARISC = libseccomp.SCMP_ARCH_PARISC + PARISC64 = libseccomp.SCMP_ARCH_PARISC64 + PPC = libseccomp.SCMP_ARCH_PPC + PPC64 = libseccomp.SCMP_ARCH_PPC64 + PPC64LE = libseccomp.SCMP_ARCH_PPC64LE + S390 = libseccomp.SCMP_ARCH_S390 + S390X = libseccomp.SCMP_ARCH_S390X + RISCV64 = libseccomp.SCMP_ARCH_RISCV64 + + def __cinit__(self, arch=libseccomp.SCMP_ARCH_NATIVE): + """ Initialize the architecture object. + + Arguments: + arch - the architecture name or token value + + Description: + Create an architecture object using the given name or token value. + """ + if isinstance(arch, int): + if arch == libseccomp.SCMP_ARCH_NATIVE: + self._token = libseccomp.seccomp_arch_native() + elif arch == libseccomp.SCMP_ARCH_X86: + self._token = libseccomp.SCMP_ARCH_X86 + elif arch == libseccomp.SCMP_ARCH_X86_64: + self._token = libseccomp.SCMP_ARCH_X86_64 + elif arch == libseccomp.SCMP_ARCH_X32: + self._token = libseccomp.SCMP_ARCH_X32 + elif arch == libseccomp.SCMP_ARCH_ARM: + self._token = libseccomp.SCMP_ARCH_ARM + elif arch == libseccomp.SCMP_ARCH_AARCH64: + self._token = libseccomp.SCMP_ARCH_AARCH64 + elif arch == libseccomp.SCMP_ARCH_MIPS: + self._token = libseccomp.SCMP_ARCH_MIPS + elif arch == libseccomp.SCMP_ARCH_MIPS64: + self._token = libseccomp.SCMP_ARCH_MIPS64 + elif arch == libseccomp.SCMP_ARCH_MIPS64N32: + self._token = libseccomp.SCMP_ARCH_MIPS64N32 + elif arch == libseccomp.SCMP_ARCH_MIPSEL: + self._token = libseccomp.SCMP_ARCH_MIPSEL + elif arch == libseccomp.SCMP_ARCH_MIPSEL64: + self._token = libseccomp.SCMP_ARCH_MIPSEL64 + elif arch == libseccomp.SCMP_ARCH_MIPSEL64N32: + self._token = libseccomp.SCMP_ARCH_MIPSEL64N32 + elif arch == libseccomp.SCMP_ARCH_PARISC: + self._token = libseccomp.SCMP_ARCH_PARISC + elif arch == libseccomp.SCMP_ARCH_PARISC64: + self._token = libseccomp.SCMP_ARCH_PARISC64 + elif arch == libseccomp.SCMP_ARCH_PPC: + self._token = libseccomp.SCMP_ARCH_PPC + elif arch == libseccomp.SCMP_ARCH_PPC64: + self._token = libseccomp.SCMP_ARCH_PPC64 + elif arch == libseccomp.SCMP_ARCH_PPC64LE: + self._token = libseccomp.SCMP_ARCH_PPC64LE + elif arch == libseccomp.SCMP_ARCH_S390: + self._token = libseccomp.SCMP_ARCH_S390 + elif arch == libseccomp.SCMP_ARCH_S390X: + self._token = libseccomp.SCMP_ARCH_S390X + else: + self._token = 0; + elif isinstance(arch, basestring): + self._token = libseccomp.seccomp_arch_resolve_name(c_str(arch)) + else: + raise TypeError("Architecture must be an int or str type") + if self._token == 0: + raise ValueError("Invalid architecture") + + def __int__(self): + """ Convert the architecture object to a token value. + + Description: + Convert the architecture object to an integer representing the + architecture's token value. + """ + return self._token + +cdef class Attr: + """ Python object representing the SyscallFilter attributes. + + Data values: + ACT_DEFAULT - the filter's default action + ACT_BADARCH - the filter's bad architecture action + CTL_NNP - the filter's "no new privileges" flag + CTL_NNP - the filter's thread sync flag + CTL_TSYNC - sync threads on filter load + CTL_TSKIP - allow rules with a -1 syscall number + CTL_LOG - log not-allowed actions + CTL_SSB - disable SSB mitigations + CTL_OPTIMIZE - the filter's optimization level: + 0: currently unused + 1: rules weighted by priority and complexity (DEFAULT) + 2: binary tree sorted by syscall number + API_SYSRAWRC - return the raw syscall codes + """ + ACT_DEFAULT = libseccomp.SCMP_FLTATR_ACT_DEFAULT + ACT_BADARCH = libseccomp.SCMP_FLTATR_ACT_BADARCH + CTL_NNP = libseccomp.SCMP_FLTATR_CTL_NNP + CTL_TSYNC = libseccomp.SCMP_FLTATR_CTL_TSYNC + API_TSKIP = libseccomp.SCMP_FLTATR_API_TSKIP + CTL_LOG = libseccomp.SCMP_FLTATR_CTL_LOG + CTL_SSB = libseccomp.SCMP_FLTATR_CTL_SSB + CTL_OPTIMIZE = libseccomp.SCMP_FLTATR_CTL_OPTIMIZE + API_SYSRAWRC = libseccomp.SCMP_FLTATR_API_SYSRAWRC + +cdef class Arg: + """ Python object representing a SyscallFilter syscall argument. + """ + cdef libseccomp.scmp_arg_cmp _arg + + def __cinit__(self, arg, op, datum_a, datum_b = 0): + """ Initialize the argument comparison. + + Arguments: + arg - the argument number, starting at 0 + op - the argument comparison operator, e.g. {NE,LT,LE,...} + datum_a - argument value + datum_b - argument value, only valid when op == MASKED_EQ + + Description: + Create an argument comparison object for use with SyscallFilter. + """ + self._arg.arg = arg + self._arg.op = op + self._arg.datum_a = datum_a + self._arg.datum_b = datum_b + + cdef libseccomp.scmp_arg_cmp to_c(self): + """ Convert the object into a C structure. + + Description: + Helper function which should only be used internally by + SyscallFilter objects and exists for the sole purpose of making it + easier to deal with the varadic functions of the libseccomp API, + e.g. seccomp_rule_add(). + """ + return self._arg + +cdef class Notification: + """ Python object representing a seccomp notification. + """ + cdef uint64_t _id + cdef uint32_t _pid + cdef uint32_t _flags + cdef int _syscall + cdef uint32_t _syscall_arch + cdef uint64_t _syscall_ip + cdef uint64_t _syscall_args[6] + + def __cinit__(self, id, pid, flags, syscall, arch, ip, args): + """ Initialize the notification. + + Arguments: + id - the notification ID + pid - the process ID + flags - the notification flags + syscall - the syscall number + ip - the instruction pointer + args - list of the six syscall arguments + + Description: + Create a seccomp Notification object. + """ + self._id = id + self._pid = pid + self._flags = flags + self._syscall = syscall + self._syscall_arch = arch + self._syscall_ip = ip + self._syscall_args[0] = args[0] + self._syscall_args[1] = args[1] + self._syscall_args[2] = args[2] + self._syscall_args[3] = args[3] + self._syscall_args[4] = args[4] + self._syscall_args[5] = args[5] + + @property + def id(self): + """ Get the seccomp notification ID. + + Description: + Get the seccomp notification ID. + """ + return self._id + + @property + def pid(self): + """ Get the seccomp notification process ID. + + Description: + Get the seccomp notification process ID. + """ + return self._pid + + @property + def flags(self): + """ Get the seccomp notification flags. + + Description: + Get the seccomp notification flags. + """ + return self._flags + + @property + def syscall(self): + """ Get the seccomp notification syscall. + + Description: + Get the seccomp notification syscall. + """ + return self._syscall + + @property + def syscall_arch(self): + """ Get the seccomp notification syscall architecture. + + Description: + Get the seccomp notification syscall architecture. + """ + return self._syscall_arch + + @property + def syscall_ip(self): + """ Get the seccomp notification syscall instruction pointer. + + Description: + Get the seccomp notification syscall instruction pointer. + """ + return self._syscall_ip + + @property + def syscall_args(self): + """ Get the seccomp notification syscall arguments. + + Description: + Get the seccomp notification syscall arguments in a six element list. + """ + return [self._syscall_args[0], self._syscall_args[1], + self._syscall_args[2], self._syscall_args[3], + self._syscall_args[4], self._syscall_args[5]] + +cdef class NotificationResponse: + """ Python object representing a seccomp notification response. + """ + cdef uint64_t _id + cdef int64_t _val + cdef int32_t _error + cdef uint32_t _flags + + def __cinit__(self, notify, val = 0, error = 0, flags = 0): + """ Initialize the notification response. + + Arguments: + notify - a Notification object + val - the notification response value + error - the notification response error + flags - the notification response flags + + Description: + Create a seccomp NotificationResponse object. + """ + self._id = notify.id + self._val = val + self._error = error + self._flags = flags + + @property + def id(self): + """ Get the seccomp notification response ID. + + Description: + Get the seccomp notification response ID. + """ + return self._id + + @id.setter + def id(self, value): + """ Set the seccomp notification response ID. + + Arguments: + id - the notification response ID + + Description: + Set the seccomp notification response ID. + """ + self._id = value + + @property + def val(self): + """ Get the seccomp notification response value. + + Description: + Get the seccomp notification response value. + """ + return self._val + + @val.setter + def val(self, value): + """ Set the seccomp notification response value. + + Arguments: + val - the notification response value + + Description: + Set the seccomp notification response value. + """ + self._val = value + + @property + def error(self): + """ Get the seccomp notification response error. + + Description: + Get the seccomp notification response error. + """ + return self._error + + @error.setter + def error(self, value): + """ Set the seccomp notification response error. + + Arguments: + error - the notification response error + + Description: + Set the seccomp notification response error. + """ + self._error = value + + @property + def flags(self): + """ Get the seccomp notification response flags. + + Description: + Get the seccomp notification response flags. + """ + return self._flags + + @flags.setter + def flags(self, value): + """ Set the seccomp notification response flags. + + Arguments: + flags - the notification response flags + + Description: + Set the seccomp notification response flags. + """ + self._flags = value + +cdef class SyscallFilter: + """ Python object representing a seccomp syscall filter. """ + cdef int _defaction + cdef libseccomp.scmp_filter_ctx _ctx + + def __cinit__(self, int defaction): + self._ctx = libseccomp.seccomp_init(defaction) + if self._ctx == NULL: + raise RuntimeError("Library error") + _defaction = defaction + + def __init__(self, defaction): + """ Initialize the filter state + + Arguments: + defaction - the default filter action + + Description: + Initializes the seccomp filter state to the defaults. + """ + + def __dealloc__(self): + """ Destroys the filter state and releases any resources. + + Description: + Destroys the seccomp filter state and releases any resources + associated with the filter state. This function does not affect + any seccomp filters already loaded into the kernel. + """ + if self._ctx != NULL: + libseccomp.seccomp_release(self._ctx) + + def reset(self, int defaction = -1): + """ Reset the filter state. + + Arguments: + defaction - the default filter action + + Description: + Resets the seccomp filter state to an initial default state, if a + default filter action is not specified in the reset call the + original action will be reused. This function does not affect any + seccomp filters alread loaded into the kernel. + """ + if defaction == -1: + defaction = self._defaction + rc = libseccomp.seccomp_reset(self._ctx, defaction) + if rc == -errno.EINVAL: + raise ValueError("Invalid action") + if rc != 0: + raise RuntimeError(str.format("Library error (errno = {0})", rc)) + _defaction = defaction + + def merge(self, SyscallFilter filter): + """ Merge two existing SyscallFilter objects. + + Arguments: + filter - a valid SyscallFilter object + + Description: + Merges a valid SyscallFilter object with the current SyscallFilter + object; the passed filter object will be reset on success. In + order to successfully merge two seccomp filters they must have the + same attribute values and not share any of the same architectures. + """ + rc = libseccomp.seccomp_merge(self._ctx, filter._ctx) + if rc != 0: + raise RuntimeError(str.format("Library error (errno = {0})", rc)) + filter._ctx = NULL + filter = SyscallFilter(filter._defaction) + + def exist_arch(self, arch): + """ Check if the seccomp filter contains a given architecture. + + Arguments: + arch - the architecture value, e.g. Arch.* + + Description: + Test to see if a given architecture is included in the filter. + Return True is the architecture exists, False if it does not + exist. + """ + rc = libseccomp.seccomp_arch_exist(self._ctx, arch) + if rc == 0: + return True + elif rc == -errno.EEXIST: + return False + elif rc == -errno.EINVAL: + raise ValueError("Invalid architecture") + else: + raise RuntimeError(str.format("Library error (errno = {0})", rc)) + + def add_arch(self, arch): + """ Add an architecture to the filter. + + Arguments: + arch - the architecture value, e.g. Arch.* + + Description: + Add the given architecture to the filter. Any new rules added + after this method returns successfully will be added to this new + architecture, but any existing rules will not be added to the new + architecture. + """ + rc = libseccomp.seccomp_arch_add(self._ctx, arch) + if rc == -errno.EINVAL: + raise ValueError("Invalid architecture") + elif rc != 0: + raise RuntimeError(str.format("Library error (errno = {0})", rc)) + + def remove_arch(self, arch): + """ Remove an architecture from the filter. + + Arguments: + arch - the architecture value, e.g. Arch.* + + Description: + Remove the given architecture from the filter. The filter must + always contain at least one architecture, so if only one + architecture exists in the filter this method will fail. + """ + rc = libseccomp.seccomp_arch_remove(self._ctx, arch) + if rc == -errno.EINVAL: + raise ValueError("Invalid architecture") + elif rc != 0: + raise RuntimeError(str.format("Library error (errno = {0})", rc)) + + def load(self): + """ Load the filter into the Linux Kernel. + + Description: + Load the current filter into the Linux Kernel. As soon as the + method returns the filter will be active and enforcing. + """ + rc = libseccomp.seccomp_load(self._ctx) + if rc != 0: + raise RuntimeError(str.format("Library error (errno = {0})", rc)) + + def get_attr(self, attr): + """ Get an attribute value from the filter. + + Arguments: + attr - the attribute, e.g. Attr.* + + Description: + Lookup the given attribute in the filter and return the + attribute's value to the caller. + """ + cdef uint32_t value = 0 + rc = libseccomp.seccomp_attr_get(self._ctx, + attr, <uint32_t *>&value) + if rc == -errno.EINVAL: + raise ValueError("Invalid attribute") + elif rc != 0: + raise RuntimeError(str.format("Library error (errno = {0})", rc)) + return value + + def set_attr(self, attr, int value): + """ Set a filter attribute. + + Arguments: + attr - the attribute, e.g. Attr.* + value - the attribute value + + Description: + Lookup the given attribute in the filter and assign it the given + value. + """ + rc = libseccomp.seccomp_attr_set(self._ctx, attr, value) + if rc == -errno.EINVAL: + raise ValueError("Invalid attribute") + elif rc != 0: + raise RuntimeError(str.format("Library error (errno = {0})", rc)) + + def syscall_priority(self, syscall, int priority): + """ Set the filter priority of a syscall. + + Arguments: + syscall - the syscall name or number + priority - the priority of the syscall + + Description: + Set the filter priority of the given syscall. A syscall with a + higher priority will have less overhead in the generated filter + code which is loaded into the system. Priority values can range + from 0 to 255 inclusive. + """ + if priority < 0 or priority > 255: + raise ValueError("Syscall priority must be between 0 and 255") + if isinstance(syscall, str): + syscall_str = syscall.encode() + syscall_num = libseccomp.seccomp_syscall_resolve_name(syscall_str) + elif isinstance(syscall, int): + syscall_num = syscall + else: + raise TypeError("Syscall must either be an int or str type") + rc = libseccomp.seccomp_syscall_priority(self._ctx, + syscall_num, priority) + if rc != 0: + raise RuntimeError(str.format("Library error (errno = {0})", rc)) + + def add_rule(self, int action, syscall, *args): + """ Add a new rule to filter. + + Arguments: + action - the rule action: KILL_PROCESS, KILL, TRAP, ERRNO(), TRACE(), + LOG, or ALLOW + syscall - the syscall name or number + args - variable number of Arg objects + + Description: + Add a new rule to the filter, matching on the given syscall and an + optional list of argument comparisons. If the rule is triggered + the given action will be taken by the kernel. In order for the + rule to trigger, the syscall as well as each argument comparison + must be true. + + In the case where the specific rule is not valid on a specific + architecture, e.g. socket() on 32-bit x86, this method rewrites + the rule to the best possible match. If you don't want this fule + rewriting to take place use add_rule_exactly(). + """ + cdef libseccomp.scmp_arg_cmp c_arg[6] + if isinstance(syscall, str): + syscall_str = syscall.encode() + syscall_num = libseccomp.seccomp_syscall_resolve_name(syscall_str) + elif isinstance(syscall, int): + syscall_num = syscall + else: + raise TypeError("Syscall must either be an int or str type") + """ NOTE: the code below exists solely to deal with the varadic + nature of seccomp_rule_add() function and the inability of Cython + to handle this automatically """ + if len(args) > 6: + raise RuntimeError("Maximum number of arguments exceeded") + cdef Arg arg + for i, arg in enumerate(args): + c_arg[i] = arg.to_c() + if len(args) == 0: + rc = libseccomp.seccomp_rule_add(self._ctx, action, syscall_num, 0) + elif len(args) == 1: + rc = libseccomp.seccomp_rule_add(self._ctx, action, syscall_num, + len(args), + c_arg[0]) + elif len(args) == 2: + rc = libseccomp.seccomp_rule_add(self._ctx, action, syscall_num, + len(args), + c_arg[0], + c_arg[1]) + elif len(args) == 3: + rc = libseccomp.seccomp_rule_add(self._ctx, action, syscall_num, + len(args), + c_arg[0], + c_arg[1], + c_arg[2]) + elif len(args) == 4: + rc = libseccomp.seccomp_rule_add(self._ctx, action, syscall_num, + len(args), + c_arg[0], + c_arg[1], + c_arg[2], + c_arg[3]) + elif len(args) == 5: + rc = libseccomp.seccomp_rule_add(self._ctx, action, syscall_num, + len(args), + c_arg[0], + c_arg[1], + c_arg[2], + c_arg[3], + c_arg[4]) + elif len(args) == 6: + rc = libseccomp.seccomp_rule_add(self._ctx, action, syscall_num, + len(args), + c_arg[0], + c_arg[1], + c_arg[2], + c_arg[3], + c_arg[4], + c_arg[5]) + else: + raise RuntimeError("Maximum number of arguments exceeded") + if rc != 0: + raise RuntimeError(str.format("Library error (errno = {0})", rc)) + + def add_rule_exactly(self, int action, syscall, *args): + """ Add a new rule to filter. + + Arguments: + action - the rule action: KILL_PROCESS, KILL, TRAP, ERRNO(), TRACE(), + LOG, or ALLOW + syscall - the syscall name or number + args - variable number of Arg objects + + Description: + Add a new rule to the filter, matching on the given syscall and an + optional list of argument comparisons. If the rule is triggered + the given action will be taken by the kernel. In order for the + rule to trigger, the syscall as well as each argument comparison + must be true. + + This method attempts to add the filter rule exactly as specified + which can cause problems on certain architectures, e.g. socket() + on 32-bit x86. For a architecture independent version of this + method use add_rule(). + """ + cdef libseccomp.scmp_arg_cmp c_arg[6] + if isinstance(syscall, str): + syscall_str = syscall.encode() + syscall_num = libseccomp.seccomp_syscall_resolve_name(syscall_str) + elif isinstance(syscall, int): + syscall_num = syscall + else: + raise TypeError("Syscall must either be an int or str type") + """ NOTE: the code below exists solely to deal with the varadic + nature of seccomp_rule_add_exact() function and the inability of + Cython to handle this automatically """ + if len(args) > 6: + raise RuntimeError("Maximum number of arguments exceeded") + cdef Arg arg + for i, arg in enumerate(args): + c_arg[i] = arg.to_c() + if len(args) == 0: + rc = libseccomp.seccomp_rule_add_exact(self._ctx, action, + syscall_num, 0) + elif len(args) == 1: + rc = libseccomp.seccomp_rule_add_exact(self._ctx, action, + syscall_num, len(args), + c_arg[0]) + elif len(args) == 2: + rc = libseccomp.seccomp_rule_add_exact(self._ctx, action, + syscall_num, len(args), + c_arg[0], + c_arg[1]) + elif len(args) == 3: + rc = libseccomp.seccomp_rule_add_exact(self._ctx, action, + syscall_num, len(args), + c_arg[0], + c_arg[1], + c_arg[2]) + elif len(args) == 4: + rc = libseccomp.seccomp_rule_add_exact(self._ctx, action, + syscall_num, len(args), + c_arg[0], + c_arg[1], + c_arg[2], + c_arg[3]) + elif len(args) == 5: + rc = libseccomp.seccomp_rule_add_exact(self._ctx, action, + syscall_num, len(args), + c_arg[0], + c_arg[1], + c_arg[2], + c_arg[3], + c_arg[4]) + elif len(args) == 6: + rc = libseccomp.seccomp_rule_add_exact(self._ctx, action, + syscall_num, len(args), + c_arg[0], + c_arg[1], + c_arg[2], + c_arg[3], + c_arg[4], + c_arg[5]) + else: + raise RuntimeError("Maximum number of arguments exceeded") + if rc != 0: + raise RuntimeError(str.format("Library error (errno = {0})", rc)) + + def receive_notify(self): + """ Receive seccomp notifications. + + Description: + Receive a seccomp notification from the system, requires the use of + the NOTIFY action. + """ + cdef libseccomp.seccomp_notif *req + + fd = libseccomp.seccomp_notify_fd(self._ctx) + if fd < 0: + raise RuntimeError("Notifications not enabled/active") + rc = libseccomp.seccomp_notify_alloc(&req, NULL) + if rc < 0: + raise RuntimeError(str.format("Library error (errno = {0})", rc)) + rc = libseccomp.seccomp_notify_receive(fd, req) + if rc < 0: + raise RuntimeError(str.format("Library error (errno = {0})", rc)) + rc = libseccomp.seccomp_notify_id_valid(fd, req.id) + if rc < 0: + raise RuntimeError(str.format("Library error (errno = {0})", rc)) + notify = Notification(req.id, req.pid, req.flags, req.data.nr, + req.data.arch, req.data.instruction_pointer, + [req.data.args[0], req.data.args[1], + req.data.args[2], req.data.args[3], + req.data.args[4], req.data.args[5]]) + free(req) + return notify + + def respond_notify(self, response): + """ Send a seccomp notification response. + + Arguments: + response - the response to send to the system + + Description: + Respond to a seccomp notification. + """ + cdef libseccomp.seccomp_notif_resp *resp + + fd = libseccomp.seccomp_notify_fd(self._ctx) + if fd < 0: + raise RuntimeError("Notifications not enabled/active") + rc = libseccomp.seccomp_notify_alloc(NULL, &resp) + if rc < 0: + raise RuntimeError(str.format("Library error (errno = {0})", rc)) + resp.id = response.id + resp.val = response.val + resp.error = response.error + resp.flags = response.flags + rc = libseccomp.seccomp_notify_respond(fd, resp) + if rc < 0: + raise RuntimeError(str.format("Library error (errno = {0})", rc)) + + def get_notify_fd(self): + """ Get the seccomp notification file descriptor + + Description: + Returns the seccomp listener file descriptor that was generated when + the seccomp policy was loaded. This is only valid after load() with a + filter that makes use of the NOTIFY action. + """ + fd = libseccomp.seccomp_notify_fd(self._ctx) + if fd < 0: + raise RuntimeError("Notifications not enabled/active") + return fd + + def export_pfc(self, file): + """ Export the filter in PFC format. + + Arguments: + file - the output file + + Description: + Output the filter in Pseudo Filter Code (PFC) to the given file. + The output is functionally equivalent to the BPF based filter + which is loaded into the Linux Kernel. + """ + rc = libseccomp.seccomp_export_pfc(self._ctx, file.fileno()) + if rc != 0: + raise RuntimeError(str.format("Library error (errno = {0})", rc)) + + def export_bpf(self, file): + """ Export the filter in BPF format. + + Arguments: + file - the output file + + Description: + Output the filter in Berkeley Packet Filter (BPF) to the given + file. The output is identical to what is loaded into the + Linux Kernel. + """ + rc = libseccomp.seccomp_export_bpf(self._ctx, file.fileno()) + if rc != 0: + raise RuntimeError(str.format("Library error (errno = {0})", rc)) + +# kate: syntax python; +# kate: indent-mode python; space-indent on; indent-width 4; mixedindent off; diff --git a/src/python/setup.py b/src/python/setup.py new file mode 100755 index 0000000..0419111 --- /dev/null +++ b/src/python/setup.py @@ -0,0 +1,48 @@ +#!/usr/bin/env python + +# +# Enhanced Seccomp Library Python Module Build Script +# +# Copyright (c) 2012 Red Hat <pmoore@redhat.com> +# Author: Paul Moore <paul@paul-moore.com> +# + +# +# 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>. +# + +import os + +from distutils.core import setup +from distutils.extension import Extension +from Cython.Distutils import build_ext + +setup( + name = "seccomp", + version = os.environ["VERSION_RELEASE"], + description = "Python binding for libseccomp", + long_description = "Python API for the Linux Kernel's syscall filtering capability, seccomp.", + url = "https://github.com/seccomp/libseccomp", + maintainer = "Paul Moore", + maintainer_email = "paul@paul-moore.com", + license = "LGPLv2.1", + platforms = "Linux", + cmdclass = {'build_ext': build_ext}, + ext_modules = [ + Extension("seccomp", ["seccomp.pyx"], + # unable to handle libtool libraries directly + extra_objects=["../.libs/libseccomp.a"], + # fix build warnings, see PEP 3123 + extra_compile_args=["-fno-strict-aliasing"]) + ] +) diff --git a/src/syscalls.c b/src/syscalls.c new file mode 100644 index 0000000..9c58c12 --- /dev/null +++ b/src/syscalls.c @@ -0,0 +1,551 @@ +/** + * Enhanced Seccomp Syscall Table Functions + * + * Copyright (c) 2012, 2020 Red Hat <pmoore@redhat.com> + * Author: Paul Moore <paul@paul-moore.com> + * gperf support: Giuseppe Scrivano <gscrivan@redhat.com> + */ + +/* + * 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 <string.h> +#include <seccomp.h> + +#include "db.h" +#include "arch.h" +#include "syscalls.h" + +/** + * Resolve a syscall name to a number + * @param arch the arch definition + * @param name the syscall name + * + * Resolve the given syscall name to the syscall number using the syscall table. + * Returns the syscall number on success, including negative pseudo syscall + * numbers; returns __NR_SCMP_ERROR on failure. + * + */ +int abi_syscall_resolve_name_munge(const struct arch_def *arch, + const char *name) +{ + +#define _ABI_SYSCALL_RES_NAME_CHK(NAME) \ + if (!strcmp(name, #NAME)) return __PNR_##NAME; + + _ABI_SYSCALL_RES_NAME_CHK(socket) + _ABI_SYSCALL_RES_NAME_CHK(bind) + _ABI_SYSCALL_RES_NAME_CHK(connect) + _ABI_SYSCALL_RES_NAME_CHK(listen) + _ABI_SYSCALL_RES_NAME_CHK(accept) + _ABI_SYSCALL_RES_NAME_CHK(getsockname) + _ABI_SYSCALL_RES_NAME_CHK(getpeername) + _ABI_SYSCALL_RES_NAME_CHK(socketpair) + _ABI_SYSCALL_RES_NAME_CHK(send) + _ABI_SYSCALL_RES_NAME_CHK(recv) + _ABI_SYSCALL_RES_NAME_CHK(sendto) + _ABI_SYSCALL_RES_NAME_CHK(recvfrom) + _ABI_SYSCALL_RES_NAME_CHK(shutdown) + _ABI_SYSCALL_RES_NAME_CHK(setsockopt) + _ABI_SYSCALL_RES_NAME_CHK(getsockopt) + _ABI_SYSCALL_RES_NAME_CHK(sendmsg) + _ABI_SYSCALL_RES_NAME_CHK(recvmsg) + _ABI_SYSCALL_RES_NAME_CHK(accept4) + _ABI_SYSCALL_RES_NAME_CHK(recvmmsg) + _ABI_SYSCALL_RES_NAME_CHK(sendmmsg) + _ABI_SYSCALL_RES_NAME_CHK(semop) + _ABI_SYSCALL_RES_NAME_CHK(semget) + _ABI_SYSCALL_RES_NAME_CHK(semctl) + _ABI_SYSCALL_RES_NAME_CHK(semtimedop) + _ABI_SYSCALL_RES_NAME_CHK(msgsnd) + _ABI_SYSCALL_RES_NAME_CHK(msgrcv) + _ABI_SYSCALL_RES_NAME_CHK(msgget) + _ABI_SYSCALL_RES_NAME_CHK(msgctl) + _ABI_SYSCALL_RES_NAME_CHK(shmat) + _ABI_SYSCALL_RES_NAME_CHK(shmdt) + _ABI_SYSCALL_RES_NAME_CHK(shmget) + _ABI_SYSCALL_RES_NAME_CHK(shmctl) + + return arch->syscall_resolve_name_raw(name); +} + +/** + * Resolve a syscall number to a name + * @param arch the arch definition + * @param num the syscall number + * + * Resolve the given syscall number to the syscall name using the syscall table. + * Returns a pointer to the syscall name string on success, including pseudo + * syscall names; returns NULL on failure. + * + */ +const char *abi_syscall_resolve_num_munge(const struct arch_def *arch, int num) +{ + +#define _ABI_SYSCALL_RES_NUM_CHK(NAME) \ + if (num == __PNR_##NAME) return #NAME; + + _ABI_SYSCALL_RES_NUM_CHK(socket) + _ABI_SYSCALL_RES_NUM_CHK(bind) + _ABI_SYSCALL_RES_NUM_CHK(connect) + _ABI_SYSCALL_RES_NUM_CHK(listen) + _ABI_SYSCALL_RES_NUM_CHK(accept) + _ABI_SYSCALL_RES_NUM_CHK(getsockname) + _ABI_SYSCALL_RES_NUM_CHK(getpeername) + _ABI_SYSCALL_RES_NUM_CHK(socketpair) + _ABI_SYSCALL_RES_NUM_CHK(send) + _ABI_SYSCALL_RES_NUM_CHK(recv) + _ABI_SYSCALL_RES_NUM_CHK(sendto) + _ABI_SYSCALL_RES_NUM_CHK(recvfrom) + _ABI_SYSCALL_RES_NUM_CHK(shutdown) + _ABI_SYSCALL_RES_NUM_CHK(setsockopt) + _ABI_SYSCALL_RES_NUM_CHK(getsockopt) + _ABI_SYSCALL_RES_NUM_CHK(sendmsg) + _ABI_SYSCALL_RES_NUM_CHK(recvmsg) + _ABI_SYSCALL_RES_NUM_CHK(accept4) + _ABI_SYSCALL_RES_NUM_CHK(recvmmsg) + _ABI_SYSCALL_RES_NUM_CHK(sendmmsg) + _ABI_SYSCALL_RES_NUM_CHK(semop) + _ABI_SYSCALL_RES_NUM_CHK(semget) + _ABI_SYSCALL_RES_NUM_CHK(semctl) + _ABI_SYSCALL_RES_NUM_CHK(semtimedop) + _ABI_SYSCALL_RES_NUM_CHK(msgsnd) + _ABI_SYSCALL_RES_NUM_CHK(msgrcv) + _ABI_SYSCALL_RES_NUM_CHK(msgget) + _ABI_SYSCALL_RES_NUM_CHK(msgctl) + _ABI_SYSCALL_RES_NUM_CHK(shmat) + _ABI_SYSCALL_RES_NUM_CHK(shmdt) + _ABI_SYSCALL_RES_NUM_CHK(shmget) + _ABI_SYSCALL_RES_NUM_CHK(shmctl) + + return arch->syscall_resolve_num_raw(num); +} + +/** + * Check if a syscall is a socket syscall + * @param arch the arch definition + * @param sys the syscall number + * + * Returns true if the syscall is a socket related syscall, false otherwise. + * + */ +static bool _abi_syscall_socket_test(const struct arch_def *arch, int sys) +{ + const char *name; + + /* multiplexed pseduo-syscalls */ + if (sys <= -100 && sys >= -120) + return true; + + name = arch->syscall_resolve_num_raw(sys); + if (!name) + return false; + +#define _ABI_SYSCALL_SOCK_CHK(NAME) \ + if (!strcmp(name, #NAME)) return true; + + _ABI_SYSCALL_SOCK_CHK(socket) + _ABI_SYSCALL_SOCK_CHK(bind) + _ABI_SYSCALL_SOCK_CHK(connect) + _ABI_SYSCALL_SOCK_CHK(listen) + _ABI_SYSCALL_SOCK_CHK(accept) + _ABI_SYSCALL_SOCK_CHK(getsockname) + _ABI_SYSCALL_SOCK_CHK(getpeername) + _ABI_SYSCALL_SOCK_CHK(socketpair) + _ABI_SYSCALL_SOCK_CHK(send) + _ABI_SYSCALL_SOCK_CHK(recv) + _ABI_SYSCALL_SOCK_CHK(sendto) + _ABI_SYSCALL_SOCK_CHK(recvfrom) + _ABI_SYSCALL_SOCK_CHK(shutdown) + _ABI_SYSCALL_SOCK_CHK(setsockopt) + _ABI_SYSCALL_SOCK_CHK(getsockopt) + _ABI_SYSCALL_SOCK_CHK(sendmsg) + _ABI_SYSCALL_SOCK_CHK(recvmsg) + _ABI_SYSCALL_SOCK_CHK(accept4) + _ABI_SYSCALL_SOCK_CHK(recvmmsg) + _ABI_SYSCALL_SOCK_CHK(sendmmsg) + + return false; +} + +/** + * Check if a syscall is an ipc syscall + * @param arch the arch definition + * @param sys the syscall number + * + * Returns true if the syscall is an ipc related syscall, false otherwise. + * + */ +static bool _abi_syscall_ipc_test(const struct arch_def *arch, int sys) +{ + const char *name; + + /* multiplexed pseduo-syscalls */ + if (sys <= -200 && sys >= -224) + return true; + + name = arch->syscall_resolve_num_raw(sys); + if (!name) + return false; + +#define _ABI_SYSCALL_IPC_CHK(NAME) \ + if (!strcmp(name, #NAME)) return true; + + _ABI_SYSCALL_IPC_CHK(semop) + _ABI_SYSCALL_IPC_CHK(semget) + _ABI_SYSCALL_IPC_CHK(semctl) + _ABI_SYSCALL_IPC_CHK(semtimedop) + _ABI_SYSCALL_IPC_CHK(msgsnd) + _ABI_SYSCALL_IPC_CHK(msgrcv) + _ABI_SYSCALL_IPC_CHK(msgget) + _ABI_SYSCALL_IPC_CHK(msgctl) + _ABI_SYSCALL_IPC_CHK(shmat) + _ABI_SYSCALL_IPC_CHK(shmdt) + _ABI_SYSCALL_IPC_CHK(shmget) + _ABI_SYSCALL_IPC_CHK(shmctl) + + return false; +} + +/** + * Convert a multiplexed pseudo syscall into a direct syscall + * @param arch the arch definition + * @param syscall the multiplexed pseudo syscall number + * + * Return the related direct syscall number, __NR_SCMP_UNDEF is there is + * no related syscall, or __NR_SCMP_ERROR otherwise. + * + */ +static int _abi_syscall_demux(const struct arch_def *arch, int syscall) +{ + int sys = __NR_SCMP_UNDEF; + +#define _ABI_SYSCALL_DEMUX_CHK(NAME) \ +case __PNR_##NAME: \ + sys = arch->syscall_resolve_name_raw(#NAME); break; + + switch (syscall) { + _ABI_SYSCALL_DEMUX_CHK(socket) + _ABI_SYSCALL_DEMUX_CHK(bind) + _ABI_SYSCALL_DEMUX_CHK(connect) + _ABI_SYSCALL_DEMUX_CHK(listen) + _ABI_SYSCALL_DEMUX_CHK(accept) + _ABI_SYSCALL_DEMUX_CHK(getsockname) + _ABI_SYSCALL_DEMUX_CHK(getpeername) + _ABI_SYSCALL_DEMUX_CHK(socketpair) + _ABI_SYSCALL_DEMUX_CHK(send) + _ABI_SYSCALL_DEMUX_CHK(recv) + _ABI_SYSCALL_DEMUX_CHK(sendto) + _ABI_SYSCALL_DEMUX_CHK(recvfrom) + _ABI_SYSCALL_DEMUX_CHK(shutdown) + _ABI_SYSCALL_DEMUX_CHK(setsockopt) + _ABI_SYSCALL_DEMUX_CHK(getsockopt) + _ABI_SYSCALL_DEMUX_CHK(sendmsg) + _ABI_SYSCALL_DEMUX_CHK(recvmsg) + _ABI_SYSCALL_DEMUX_CHK(accept4) + _ABI_SYSCALL_DEMUX_CHK(recvmmsg) + _ABI_SYSCALL_DEMUX_CHK(sendmmsg) + _ABI_SYSCALL_DEMUX_CHK(semop) + _ABI_SYSCALL_DEMUX_CHK(semget) + _ABI_SYSCALL_DEMUX_CHK(semctl) + _ABI_SYSCALL_DEMUX_CHK(semtimedop) + _ABI_SYSCALL_DEMUX_CHK(msgsnd) + _ABI_SYSCALL_DEMUX_CHK(msgrcv) + _ABI_SYSCALL_DEMUX_CHK(msgget) + _ABI_SYSCALL_DEMUX_CHK(msgctl) + _ABI_SYSCALL_DEMUX_CHK(shmat) + _ABI_SYSCALL_DEMUX_CHK(shmdt) + _ABI_SYSCALL_DEMUX_CHK(shmget) + _ABI_SYSCALL_DEMUX_CHK(shmctl) + } + + /* this looks odd because the arch resolver returns _ERROR if it can't + * resolve the syscall, but we want to use _UNDEF for that, so we set + * 'sys' to a sentinel value of _UNDEF and if it is error here we know + * the resolve failed to find a match */ + if (sys == __NR_SCMP_UNDEF) + sys = __NR_SCMP_ERROR; + else if (sys == __NR_SCMP_ERROR) + sys = __NR_SCMP_UNDEF; + + return sys; +} + +/** + * Convert a direct syscall into multiplexed pseudo socket syscall + * @param arch the arch definition + * @param syscall the direct syscall + * + * Return the related multiplexed pseudo syscall number, __NR_SCMP_UNDEF is + * there is no related pseudo syscall, or __NR_SCMP_ERROR otherwise. + * + */ +static int _abi_syscall_mux(const struct arch_def *arch, int syscall) +{ + const char *sys; + + sys = arch->syscall_resolve_num_raw(syscall); + if (!sys) + return __NR_SCMP_ERROR; + +#define _ABI_SYSCALL_MUX_CHK(NAME) \ + if (!strcmp(sys, #NAME)) return __PNR_##NAME; + + _ABI_SYSCALL_MUX_CHK(socket) + _ABI_SYSCALL_MUX_CHK(bind) + _ABI_SYSCALL_MUX_CHK(connect) + _ABI_SYSCALL_MUX_CHK(listen) + _ABI_SYSCALL_MUX_CHK(accept) + _ABI_SYSCALL_MUX_CHK(getsockname) + _ABI_SYSCALL_MUX_CHK(getpeername) + _ABI_SYSCALL_MUX_CHK(socketpair) + _ABI_SYSCALL_MUX_CHK(send) + _ABI_SYSCALL_MUX_CHK(recv) + _ABI_SYSCALL_MUX_CHK(sendto) + _ABI_SYSCALL_MUX_CHK(recvfrom) + _ABI_SYSCALL_MUX_CHK(shutdown) + _ABI_SYSCALL_MUX_CHK(setsockopt) + _ABI_SYSCALL_MUX_CHK(getsockopt) + _ABI_SYSCALL_MUX_CHK(sendmsg) + _ABI_SYSCALL_MUX_CHK(recvmsg) + _ABI_SYSCALL_MUX_CHK(accept4) + _ABI_SYSCALL_MUX_CHK(recvmmsg) + _ABI_SYSCALL_MUX_CHK(sendmmsg) + _ABI_SYSCALL_MUX_CHK(semop) + _ABI_SYSCALL_MUX_CHK(semget) + _ABI_SYSCALL_MUX_CHK(semctl) + _ABI_SYSCALL_MUX_CHK(semtimedop) + _ABI_SYSCALL_MUX_CHK(msgsnd) + _ABI_SYSCALL_MUX_CHK(msgrcv) + _ABI_SYSCALL_MUX_CHK(msgget) + _ABI_SYSCALL_MUX_CHK(msgctl) + _ABI_SYSCALL_MUX_CHK(shmat) + _ABI_SYSCALL_MUX_CHK(shmdt) + _ABI_SYSCALL_MUX_CHK(shmget) + _ABI_SYSCALL_MUX_CHK(shmctl) + + return __NR_SCMP_ERROR; +} + +/** + * Rewrite a syscall value to match the architecture + * @param arch the arch definition + * @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. + * + */ +int abi_syscall_rewrite(const struct arch_def *arch, int *syscall) +{ + int sys = *syscall; + + if (sys <= -100 && sys >= -120) + *syscall = arch->sys_socketcall; + else if (sys <= -200 && sys >= -224) + *syscall = arch->sys_ipc; + else if (sys < 0) + return -EDOM; + + return 0; +} + +/** + * add a new rule to the abi seccomp filter + * @param db the seccomp filter db + * @param rule the filter rule + * + * This function adds a new syscall filter to the seccomp filter db, making any + * necessary adjustments for the abi ABI. Returns zero on success, negative + * values on failure. + * + * It is important to note that in the case of failure the db may be corrupted, + * the caller must use the transaction mechanism if the db integrity is + * important. + * + */ +int abi_rule_add(struct db_filter *db, struct db_api_rule_list *rule) +{ + int rc = 0; + unsigned int iter; + int sys = rule->syscall; + int sys_a, sys_b; + struct db_api_rule_list *rule_a, *rule_b, *rule_dup = NULL; + + if (_abi_syscall_socket_test(db->arch, sys)) { + /* socket syscalls */ + + /* strict check for the multiplexed socket syscalls */ + for (iter = 0; iter < ARG_COUNT_MAX; iter++) { + if ((rule->args[iter].valid != 0) && (rule->strict)) { + rc = -EINVAL; + goto add_return; + } + } + + /* determine both the muxed and direct syscall numbers */ + if (sys > 0) { + sys_a = _abi_syscall_mux(db->arch, sys); + if (sys_a == __NR_SCMP_ERROR) { + rc = __NR_SCMP_ERROR; + goto add_return; + } + sys_b = sys; + } else { + sys_a = sys; + sys_b = _abi_syscall_demux(db->arch, sys); + if (sys_b == __NR_SCMP_ERROR) { + rc = __NR_SCMP_ERROR; + goto add_return; + } + } + + /* use rule_a for the multiplexed syscall and use rule_b for + * the direct wired syscall */ + + if (sys_a == __NR_SCMP_UNDEF) { + rule_a = NULL; + rule_b = rule; + } else if (sys_b == __NR_SCMP_UNDEF) { + rule_a = rule; + rule_b = NULL; + } else { + /* need two rules, dup the first and link together */ + rule_a = rule; + rule_dup = db_rule_dup(rule_a); + rule_b = rule_dup; + if (rule_b == NULL) + goto add_return; + rule_b->prev = rule_a; + rule_b->next = NULL; + rule_a->next = rule_b; + } + + /* multiplexed socket syscalls */ + if (rule_a != NULL) { + rule_a->syscall = db->arch->sys_socketcall; + rule_a->args[0].arg = 0; + rule_a->args[0].op = SCMP_CMP_EQ; + rule_a->args[0].mask = DATUM_MAX; + rule_a->args[0].datum = (-sys_a) % 100; + rule_a->args[0].valid = 1; + } + + /* direct wired socket syscalls */ + if (rule_b != NULL) + rule_b->syscall = sys_b; + + /* we should be protected by a transaction checkpoint */ + if (rule_a != NULL) { + rc = db_rule_add(db, rule_a); + if (rc < 0) + goto add_return; + } + if (rule_b != NULL) { + rc = db_rule_add(db, rule_b); + if (rc < 0) + goto add_return; + } + } else if (_abi_syscall_ipc_test(db->arch, sys)) { + /* ipc syscalls */ + + /* strict check for the multiplexed socket syscalls */ + for (iter = 0; iter < ARG_COUNT_MAX; iter++) { + if ((rule->args[iter].valid != 0) && (rule->strict)) { + rc = -EINVAL; + goto add_return; + } + } + + /* determine both the muxed and direct syscall numbers */ + if (sys > 0) { + sys_a = _abi_syscall_mux(db->arch, sys); + if (sys_a == __NR_SCMP_ERROR) { + rc = __NR_SCMP_ERROR; + goto add_return; + } + sys_b = sys; + } else { + sys_a = sys; + sys_b = _abi_syscall_demux(db->arch, sys); + if (sys_b == __NR_SCMP_ERROR) { + rc = __NR_SCMP_ERROR; + goto add_return; + } + } + + /* use rule_a for the multiplexed syscall and use rule_b for + * the direct wired syscall */ + + if (sys_a == __NR_SCMP_UNDEF) { + rule_a = NULL; + rule_b = rule; + } else if (sys_b == __NR_SCMP_UNDEF) { + rule_a = rule; + rule_b = NULL; + } else { + /* need two rules, dup the first and link together */ + rule_a = rule; + rule_dup = db_rule_dup(rule_a); + rule_b = rule_dup; + if (rule_b == NULL) + goto add_return; + rule_b->prev = rule_a; + rule_b->next = NULL; + rule_a->next = rule_b; + } + + /* multiplexed socket syscalls */ + if (rule_a != NULL) { + rule_a->syscall = db->arch->sys_ipc; + rule_a->args[0].arg = 0; + rule_a->args[0].op = SCMP_CMP_EQ; + rule_a->args[0].mask = DATUM_MAX; + rule_a->args[0].datum = (-sys_a) % 200; + rule_a->args[0].valid = 1; + } + + /* direct wired socket syscalls */ + if (rule_b != NULL) + rule_b->syscall = sys_b; + + /* we should be protected by a transaction checkpoint */ + if (rule_a != NULL) { + rc = db_rule_add(db, rule_a); + if (rc < 0) + goto add_return; + } + if (rule_b != NULL) { + rc = db_rule_add(db, rule_b); + if (rc < 0) + goto add_return; + } + } else if (sys >= 0) { + /* normal syscall processing */ + rc = db_rule_add(db, rule); + if (rc < 0) + goto add_return; + } else if (rule->strict) { + rc = -EDOM; + goto add_return; + } + +add_return: + if (rule_dup != NULL) + free(rule_dup); + return rc; +} diff --git a/src/syscalls.csv b/src/syscalls.csv new file mode 100644 index 0000000..b0da8e6 --- /dev/null +++ b/src/syscalls.csv @@ -0,0 +1,488 @@ +#syscall (v6.7.0-rc3 2023-11-30),x86,x86_64,x32,arm,aarch64,mips,mips64,mips64n32,parisc,parisc64,ppc,ppc64,riscv64,s390,s390x +accept,PNR,43,43,285,202,168,42,42,35,35,330,330,202,PNR,PNR +accept4,364,288,288,366,242,334,293,297,320,320,344,344,242,364,364 +access,33,21,21,33,PNR,33,20,20,33,33,33,33,PNR,33,33 +acct,51,163,163,51,89,51,158,158,51,51,51,51,89,51,51 +add_key,286,248,248,309,217,280,239,243,264,264,269,269,217,278,278 +adjtimex,124,159,159,124,171,124,154,154,124,124,124,124,171,124,124 +afs_syscall,137,183,183,PNR,PNR,137,176,176,PNR,PNR,137,137,PNR,137,137 +alarm,27,37,37,PNR,PNR,27,37,37,27,27,27,27,PNR,27,27 +arch_prctl,384,158,158,PNR,PNR,PNR,PNR,PNR,PNR,PNR,PNR,PNR,PNR,PNR,PNR +arm_fadvise64_64,PNR,PNR,PNR,270,PNR,PNR,PNR,PNR,PNR,PNR,PNR,PNR,PNR,PNR,PNR +arm_sync_file_range,PNR,PNR,PNR,341,PNR,PNR,PNR,PNR,PNR,PNR,PNR,PNR,PNR,PNR,PNR +bdflush,134,PNR,PNR,134,PNR,134,PNR,PNR,134,134,134,134,PNR,134,134 +bind,361,49,49,282,200,169,48,48,22,22,327,327,200,361,361 +bpf,357,321,321,386,280,355,315,319,341,341,361,361,280,351,351 +break,17,PNR,PNR,PNR,PNR,17,PNR,PNR,PNR,PNR,17,17,PNR,PNR,PNR +breakpoint,PNR,PNR,PNR,983041,PNR,PNR,PNR,PNR,PNR,PNR,PNR,PNR,PNR,PNR,PNR +brk,45,12,12,45,214,45,12,12,45,45,45,45,214,45,45 +cachectl,PNR,PNR,PNR,PNR,PNR,148,198,198,PNR,PNR,PNR,PNR,PNR,PNR,PNR +cacheflush,PNR,PNR,PNR,983042,PNR,147,197,197,356,356,PNR,PNR,PNR,PNR,PNR +cachestat,451,451,451,451,451,451,451,451,451,451,451,451,451,451,451 +capget,184,125,125,184,90,204,123,123,106,106,183,183,90,184,184 +capset,185,126,126,185,91,205,124,124,107,107,184,184,91,185,185 +chdir,12,80,80,12,49,12,78,78,12,12,12,12,49,12,12 +chmod,15,90,90,15,PNR,15,88,88,15,15,15,15,PNR,15,15 +chown,182,92,92,182,PNR,202,90,90,180,180,181,181,PNR,182,212 +chown32,212,PNR,PNR,212,PNR,PNR,PNR,PNR,PNR,PNR,PNR,PNR,PNR,212,PNR +chroot,61,161,161,61,51,61,156,156,61,61,61,61,51,61,61 +clock_adjtime,343,305,305,372,266,341,300,305,324,324,347,347,266,337,337 +clock_adjtime64,405,PNR,PNR,405,PNR,405,PNR,405,405,PNR,405,PNR,PNR,405,PNR +clock_getres,266,229,229,264,114,264,223,227,257,257,247,247,114,261,261 +clock_getres_time64,406,PNR,PNR,406,PNR,406,PNR,406,406,PNR,406,PNR,PNR,406,PNR +clock_gettime,265,228,228,263,113,263,222,226,256,256,246,246,113,260,260 +clock_gettime64,403,PNR,PNR,403,PNR,403,PNR,403,403,PNR,403,PNR,PNR,403,PNR +clock_nanosleep,267,230,230,265,115,265,224,228,258,258,248,248,115,262,262 +clock_nanosleep_time64,407,PNR,PNR,407,PNR,407,PNR,407,407,PNR,407,PNR,PNR,407,PNR +clock_settime,264,227,227,262,112,262,221,225,255,255,245,245,112,259,259 +clock_settime64,404,PNR,PNR,404,PNR,404,PNR,404,404,PNR,404,PNR,PNR,404,PNR +clone,120,56,56,120,220,120,55,55,120,120,120,120,220,120,120 +clone3,435,435,435,435,435,435,435,435,435,435,435,435,435,435,435 +close,6,3,3,6,57,6,3,3,6,6,6,6,57,6,6 +close_range,436,436,436,436,436,436,436,436,436,436,436,436,436,436,436 +connect,362,42,42,283,203,170,41,41,31,31,328,328,203,362,362 +copy_file_range,377,326,326,391,285,360,320,324,346,346,379,379,285,375,375 +creat,8,85,85,8,PNR,8,83,83,8,8,8,8,PNR,8,8 +create_module,127,174,PNR,PNR,PNR,127,167,167,PNR,PNR,127,127,PNR,127,127 +delete_module,129,176,176,129,106,129,169,169,129,129,129,129,106,129,129 +dup,41,32,32,41,23,41,31,31,41,41,41,41,23,41,41 +dup2,63,33,33,63,PNR,63,32,32,63,63,63,63,PNR,63,63 +dup3,330,292,292,358,24,327,286,290,312,312,316,316,24,326,326 +epoll_create,254,213,213,250,PNR,248,207,207,224,224,236,236,PNR,249,249 +epoll_create1,329,291,291,357,20,326,285,289,311,311,315,315,20,327,327 +epoll_ctl,255,233,233,251,21,249,208,208,225,225,237,237,21,250,250 +epoll_ctl_old,PNR,214,PNR,PNR,PNR,PNR,PNR,PNR,PNR,PNR,PNR,PNR,PNR,PNR,PNR +epoll_pwait,319,281,281,346,22,313,272,276,297,297,303,303,22,312,312 +epoll_pwait2,441,441,441,441,441,441,441,441,441,441,441,441,441,441,441 +epoll_wait,256,232,232,252,PNR,250,209,209,226,226,238,238,PNR,251,251 +epoll_wait_old,PNR,215,PNR,PNR,PNR,PNR,PNR,PNR,PNR,PNR,PNR,PNR,PNR,PNR,PNR +eventfd,323,284,284,351,PNR,319,278,282,304,304,307,307,PNR,318,318 +eventfd2,328,290,290,356,19,325,284,288,310,310,314,314,19,323,323 +execve,11,59,520,11,221,11,57,57,11,11,11,11,221,11,11 +execveat,358,322,545,387,281,356,316,320,342,342,362,362,281,354,354 +exit,1,60,60,1,93,1,58,58,1,1,1,1,93,1,1 +exit_group,252,231,231,248,94,246,205,205,222,222,234,234,94,248,248 +faccessat,307,269,269,334,48,300,259,263,287,287,298,298,48,300,300 +faccessat2,439,439,439,439,439,439,439,439,439,439,439,439,439,439,439 +fadvise64,250,221,221,PNR,223,254,215,216,PNR,PNR,233,233,223,253,253 +fadvise64_64,272,PNR,PNR,PNR,PNR,PNR,PNR,PNR,236,236,254,PNR,PNR,264,PNR +fallocate,324,285,285,352,47,320,279,283,305,305,309,309,47,314,314 +fanotify_init,338,300,300,367,262,336,295,300,322,322,323,323,262,332,332 +fanotify_mark,339,301,301,368,263,337,296,301,323,323,324,324,263,333,333 +fchdir,133,81,81,133,50,133,79,79,133,133,133,133,50,133,133 +fchmod,94,91,91,94,52,94,89,89,94,94,94,94,52,94,94 +fchmodat,306,268,268,333,53,299,258,262,286,286,297,297,53,299,299 +fchmodat2,452,452,452,452,452,452,452,452,452,452,452,452,452,452,452 +fchown,95,93,93,95,55,95,91,91,95,95,95,95,55,95,207 +fchown32,207,PNR,PNR,207,PNR,PNR,PNR,PNR,PNR,PNR,PNR,PNR,PNR,207,PNR +fchownat,298,260,260,325,54,291,250,254,278,278,289,289,54,291,291 +fcntl,55,72,72,55,25,55,70,70,55,55,55,55,25,55,55 +fcntl64,221,PNR,PNR,221,PNR,220,PNR,212,202,202,204,PNR,PNR,221,PNR +fdatasync,148,75,75,148,83,152,73,73,148,148,148,148,83,148,148 +fgetxattr,231,193,193,231,10,229,185,185,243,243,214,214,10,229,229 +finit_module,350,313,313,379,273,348,307,312,333,333,353,353,273,344,344 +flistxattr,234,196,196,234,13,232,188,188,246,246,217,217,13,232,232 +flock,143,73,73,143,32,143,71,71,143,143,143,143,32,143,143 +fork,2,57,57,2,PNR,2,56,56,2,2,2,2,PNR,2,2 +fremovexattr,237,199,199,237,16,235,191,191,249,249,220,220,16,235,235 +fsconfig,431,431,431,431,431,431,431,431,431,431,431,431,431,431,431 +fsetxattr,228,190,190,228,7,226,182,182,240,240,211,211,7,226,226 +fsmount,432,432,432,432,432,432,432,432,432,432,432,432,432,432,432 +fsopen,430,430,430,430,430,430,430,430,430,430,430,430,430,430,430 +fspick,433,433,433,433,433,433,433,433,433,433,433,433,433,433,433 +fstat,108,5,5,108,80,108,5,5,28,28,108,108,80,108,108 +fstat64,197,PNR,PNR,197,PNR,215,PNR,PNR,112,112,197,PNR,PNR,197,PNR +fstatat64,300,PNR,PNR,327,PNR,293,PNR,PNR,280,280,291,PNR,PNR,293,PNR +fstatfs,100,138,138,100,44,100,135,135,100,100,100,100,44,100,100 +fstatfs64,269,PNR,PNR,267,PNR,256,PNR,218,299,299,253,253,PNR,266,266 +fsync,118,74,74,118,82,118,72,72,118,118,118,118,82,118,118 +ftime,35,PNR,PNR,PNR,PNR,35,PNR,PNR,PNR,PNR,35,35,PNR,PNR,PNR +ftruncate,93,77,77,93,46,93,75,75,93,93,93,93,46,93,93 +ftruncate64,194,PNR,PNR,194,PNR,212,PNR,PNR,200,200,194,PNR,PNR,194,PNR +futex,240,202,202,240,98,238,194,194,210,210,221,221,98,238,238 +futex_requeue,456,456,456,456,456,456,456,456,456,456,456,456,456,456,456 +futex_time64,422,PNR,PNR,422,PNR,422,PNR,422,422,PNR,422,PNR,PNR,422,PNR +futex_wait,455,455,455,455,455,455,455,455,455,455,455,455,455,455,455 +futex_waitv,449,449,449,449,449,449,449,449,449,449,449,449,449,449,449 +futex_wake,454,454,454,454,454,454,454,454,454,454,454,454,454,454,454 +futimesat,299,261,261,326,PNR,292,251,255,279,279,290,290,PNR,292,292 +getcpu,318,309,309,345,168,312,271,275,296,296,302,302,168,311,311 +getcwd,183,79,79,183,17,203,77,77,110,110,182,182,17,183,183 +getdents,141,78,78,141,PNR,141,76,76,141,141,141,141,PNR,141,141 +getdents64,220,217,217,217,61,219,308,299,201,201,202,202,61,220,220 +getegid,50,108,108,50,177,50,106,106,50,50,50,50,177,50,202 +getegid32,202,PNR,PNR,202,PNR,PNR,PNR,PNR,PNR,PNR,PNR,PNR,PNR,202,PNR +geteuid,49,107,107,49,175,49,105,105,49,49,49,49,175,49,201 +geteuid32,201,PNR,PNR,201,PNR,PNR,PNR,PNR,PNR,PNR,PNR,PNR,PNR,201,PNR +getgid,47,104,104,47,176,47,102,102,47,47,47,47,176,47,200 +getgid32,200,PNR,PNR,200,PNR,PNR,PNR,PNR,PNR,PNR,PNR,PNR,PNR,200,PNR +getgroups,80,115,115,80,158,80,113,113,80,80,80,80,158,80,205 +getgroups32,205,PNR,PNR,205,PNR,PNR,PNR,PNR,PNR,PNR,PNR,PNR,PNR,205,PNR +getitimer,105,36,36,105,102,105,35,35,105,105,105,105,102,105,105 +get_kernel_syms,130,177,PNR,PNR,PNR,130,170,170,PNR,PNR,130,130,PNR,130,130 +get_mempolicy,275,239,239,320,236,269,228,232,261,261,260,260,236,269,269 +getpeername,368,52,52,287,205,171,51,51,53,53,332,332,205,368,368 +getpgid,132,121,121,132,155,132,119,119,132,132,132,132,155,132,132 +getpgrp,65,111,111,65,PNR,65,109,109,65,65,65,65,PNR,65,65 +getpid,20,39,39,20,172,20,38,38,20,20,20,20,172,20,20 +getpmsg,188,181,181,PNR,PNR,208,174,174,PNR,PNR,187,187,PNR,188,188 +getppid,64,110,110,64,173,64,108,108,64,64,64,64,173,64,64 +getpriority,96,140,140,96,141,96,137,137,96,96,96,96,141,96,96 +getrandom,355,318,318,384,278,353,313,317,339,339,359,359,278,349,349 +getresgid,171,120,120,171,150,191,118,118,171,171,170,170,150,171,211 +getresgid32,211,PNR,PNR,211,PNR,PNR,PNR,PNR,PNR,PNR,PNR,PNR,PNR,211,PNR +getresuid,165,118,118,165,148,186,116,116,165,165,165,165,148,165,209 +getresuid32,209,PNR,PNR,209,PNR,PNR,PNR,PNR,PNR,PNR,PNR,PNR,PNR,209,PNR +getrlimit,76,97,97,PNR,163,76,95,95,76,76,76,76,163,76,191 +get_robust_list,312,274,531,339,100,310,269,273,290,290,299,299,100,305,305 +getrusage,77,98,98,77,165,77,96,96,77,77,77,77,165,77,77 +getsid,147,124,124,147,156,151,122,122,147,147,147,147,156,147,147 +getsockname,367,51,51,286,204,172,50,50,44,44,331,331,204,367,367 +getsockopt,365,55,542,295,209,173,54,54,182,182,340,340,209,365,365 +get_thread_area,244,211,PNR,PNR,PNR,PNR,PNR,PNR,PNR,PNR,PNR,PNR,PNR,PNR,PNR +gettid,224,186,186,224,178,222,178,178,206,206,207,207,178,236,236 +gettimeofday,78,96,96,78,169,78,94,94,78,78,78,78,169,78,78 +get_tls,PNR,PNR,PNR,983046,PNR,PNR,PNR,PNR,PNR,PNR,PNR,PNR,PNR,PNR,PNR +getuid,24,102,102,24,174,24,100,100,24,24,24,24,174,24,199 +getuid32,199,PNR,PNR,199,PNR,PNR,PNR,PNR,PNR,PNR,PNR,PNR,PNR,199,PNR +getxattr,229,191,191,229,8,227,183,183,241,241,212,212,8,227,227 +gtty,32,PNR,PNR,PNR,PNR,32,PNR,PNR,PNR,PNR,32,32,PNR,PNR,PNR +idle,112,PNR,PNR,PNR,PNR,112,PNR,PNR,PNR,PNR,112,112,PNR,112,112 +init_module,128,175,175,128,105,128,168,168,128,128,128,128,105,128,128 +inotify_add_watch,292,254,254,317,27,285,244,248,270,270,276,276,27,285,285 +inotify_init,291,253,253,316,PNR,284,243,247,269,269,275,275,PNR,284,284 +inotify_init1,332,294,294,360,26,329,288,292,314,314,318,318,26,324,324 +inotify_rm_watch,293,255,255,318,28,286,245,249,271,271,277,277,28,286,286 +io_cancel,249,210,210,247,3,245,204,204,219,219,231,231,3,247,247 +ioctl,54,16,514,54,29,54,15,15,54,54,54,54,29,54,54 +io_destroy,246,207,207,244,1,242,201,201,216,216,228,228,1,244,244 +io_getevents,247,208,208,245,4,243,202,202,217,217,229,229,4,245,245 +ioperm,101,173,173,PNR,PNR,101,PNR,PNR,PNR,PNR,101,101,PNR,101,PNR +io_pgetevents,385,333,333,399,292,368,328,332,350,350,388,388,292,382,382 +io_pgetevents_time64,416,PNR,PNR,416,PNR,416,PNR,416,416,PNR,416,PNR,PNR,416,PNR +iopl,110,172,172,PNR,PNR,110,PNR,PNR,PNR,PNR,110,110,PNR,PNR,PNR +ioprio_get,290,252,252,315,31,315,274,278,268,268,274,274,31,283,283 +ioprio_set,289,251,251,314,30,314,273,277,267,267,273,273,30,282,282 +io_setup,245,206,543,243,0,241,200,200,215,215,227,227,0,243,243 +io_submit,248,209,544,246,2,244,203,203,218,218,230,230,2,246,246 +io_uring_enter,426,426,426,426,426,426,426,426,426,426,426,426,426,426,426 +io_uring_register,427,427,427,427,427,427,427,427,427,427,427,427,427,427,427 +io_uring_setup,425,425,425,425,425,425,425,425,425,425,425,425,425,425,425 +ipc,117,PNR,PNR,PNR,PNR,117,PNR,PNR,PNR,PNR,117,117,PNR,117,117 +kcmp,349,312,312,378,272,347,306,311,332,332,354,354,272,343,343 +kexec_file_load,PNR,320,320,401,294,PNR,PNR,PNR,355,355,382,382,294,381,381 +kexec_load,283,246,528,347,104,311,270,274,300,300,268,268,104,277,277 +keyctl,288,250,250,311,219,282,241,245,266,266,271,271,219,280,280 +kill,37,62,62,37,129,37,60,60,37,37,37,37,129,37,37 +landlock_add_rule,445,445,445,445,445,445,445,445,445,445,445,445,445,445,445 +landlock_create_ruleset,444,444,444,444,444,444,444,444,444,444,444,444,444,444,444 +landlock_restrict_self,446,446,446,446,446,446,446,446,446,446,446,446,446,446,446 +lchown,16,94,94,16,PNR,16,92,92,16,16,16,16,PNR,16,198 +lchown32,198,PNR,PNR,198,PNR,PNR,PNR,PNR,PNR,PNR,PNR,PNR,PNR,198,PNR +lgetxattr,230,192,192,230,9,228,184,184,242,242,213,213,9,228,228 +link,9,86,86,9,PNR,9,84,84,9,9,9,9,PNR,9,9 +linkat,303,265,265,330,37,296,255,259,283,283,294,294,37,296,296 +listen,363,50,50,284,201,174,49,49,32,32,329,329,201,363,363 +listxattr,232,194,194,232,11,230,186,186,244,244,215,215,11,230,230 +llistxattr,233,195,195,233,12,231,187,187,245,245,216,216,12,231,231 +_llseek,140,PNR,PNR,140,PNR,140,PNR,PNR,140,140,140,140,PNR,140,PNR +lock,53,PNR,PNR,PNR,PNR,53,PNR,PNR,PNR,PNR,53,53,PNR,PNR,PNR +lookup_dcookie,253,212,212,249,18,247,206,206,223,223,235,235,18,110,110 +lremovexattr,236,198,198,236,15,234,190,190,248,248,219,219,15,234,234 +lseek,19,8,8,19,62,19,8,8,19,19,19,19,62,19,19 +lsetxattr,227,189,189,227,6,225,181,181,239,239,210,210,6,225,225 +lstat,107,6,6,107,PNR,107,6,6,84,84,107,107,PNR,107,107 +lstat64,196,PNR,PNR,196,PNR,214,PNR,PNR,198,198,196,PNR,PNR,196,PNR +madvise,219,28,28,220,233,218,27,27,119,119,205,205,233,219,219 +map_shadow_stack,453,453,PNR,453,453,453,453,453,453,453,453,453,453,453,453 +mbind,274,237,237,319,235,268,227,231,260,260,259,259,235,268,268 +membarrier,375,324,324,389,283,358,318,322,343,343,365,365,283,356,356 +memfd_create,356,319,319,385,279,354,314,318,340,340,360,360,279,350,350 +memfd_secret,447,447,447,PNR,447,PNR,PNR,PNR,PNR,PNR,PNR,PNR,447,447,447 +migrate_pages,294,256,256,400,238,287,246,250,272,272,258,258,238,287,287 +mincore,218,27,27,219,232,217,26,26,72,72,206,206,232,218,218 +mkdir,39,83,83,39,PNR,39,81,81,39,39,39,39,PNR,39,39 +mkdirat,296,258,258,323,34,289,248,252,276,276,287,287,34,289,289 +mknod,14,133,133,14,PNR,14,131,131,14,14,14,14,PNR,14,14 +mknodat,297,259,259,324,33,290,249,253,277,277,288,288,33,290,290 +mlock,150,149,149,150,228,154,146,146,150,150,150,150,228,150,150 +mlock2,376,325,325,390,284,359,319,323,345,345,378,378,284,374,374 +mlockall,152,151,151,152,230,156,148,148,152,152,152,152,230,152,152 +mmap,90,9,9,PNR,222,90,9,9,90,90,90,90,222,90,90 +mmap2,192,PNR,PNR,192,PNR,210,PNR,PNR,89,89,192,PNR,PNR,192,PNR +modify_ldt,123,154,154,PNR,PNR,123,PNR,PNR,PNR,PNR,123,123,PNR,PNR,PNR +mount,21,165,165,21,40,21,160,160,21,21,21,21,40,21,21 +mount_setattr,442,442,442,442,442,442,442,442,442,442,442,442,442,442,442 +move_mount,429,429,429,429,429,429,429,429,429,429,429,429,429,429,429 +move_pages,317,279,533,344,239,308,267,271,295,295,301,301,239,310,310 +mprotect,125,10,10,125,226,125,10,10,125,125,125,125,226,125,125 +mpx,56,PNR,PNR,PNR,PNR,56,PNR,PNR,PNR,PNR,56,56,PNR,PNR,PNR +mq_getsetattr,282,245,245,279,185,276,235,239,234,234,267,267,185,276,276 +mq_notify,281,244,527,278,184,275,234,238,233,233,266,266,184,275,275 +mq_open,277,240,240,274,180,271,230,234,229,229,262,262,180,271,271 +mq_timedreceive,280,243,243,277,183,274,233,237,232,232,265,265,183,274,274 +mq_timedreceive_time64,419,PNR,PNR,419,PNR,419,PNR,419,419,PNR,419,PNR,PNR,419,PNR +mq_timedsend,279,242,242,276,182,273,232,236,231,231,264,264,182,273,273 +mq_timedsend_time64,418,PNR,PNR,418,PNR,418,PNR,418,418,PNR,418,PNR,PNR,418,PNR +mq_unlink,278,241,241,275,181,272,231,235,230,230,263,263,181,272,272 +mremap,163,25,25,163,216,167,24,24,163,163,163,163,216,163,163 +msgctl,402,71,71,304,187,402,69,69,191,191,402,402,187,402,402 +msgget,399,68,68,303,186,399,66,66,190,190,399,399,186,399,399 +msgrcv,401,70,70,302,188,401,68,68,189,189,401,401,188,401,401 +msgsnd,400,69,69,301,189,400,67,67,188,188,400,400,189,400,400 +msync,144,26,26,144,227,144,25,25,144,144,144,144,227,144,144 +multiplexer,PNR,PNR,PNR,PNR,PNR,PNR,PNR,PNR,PNR,PNR,201,201,PNR,PNR,PNR +munlock,151,150,150,151,229,155,147,147,151,151,151,151,229,151,151 +munlockall,153,152,152,153,231,157,149,149,153,153,153,153,231,153,153 +munmap,91,11,11,91,215,91,11,11,91,91,91,91,215,91,91 +name_to_handle_at,341,303,303,370,264,339,298,303,325,325,345,345,264,335,335 +nanosleep,162,35,35,162,101,166,34,34,162,162,162,162,101,162,162 +newfstatat,PNR,262,262,PNR,79,PNR,252,256,PNR,PNR,PNR,291,79,PNR,293 +_newselect,142,PNR,PNR,142,PNR,142,22,22,142,142,142,142,PNR,142,PNR +nfsservctl,169,180,PNR,169,42,189,173,173,PNR,PNR,168,168,42,169,169 +nice,34,PNR,PNR,34,PNR,34,PNR,PNR,34,34,34,34,PNR,34,34 +oldfstat,28,PNR,PNR,PNR,PNR,PNR,PNR,PNR,PNR,PNR,28,28,PNR,PNR,PNR +oldlstat,84,PNR,PNR,PNR,PNR,PNR,PNR,PNR,PNR,PNR,84,84,PNR,PNR,PNR +oldolduname,59,PNR,PNR,PNR,PNR,PNR,PNR,PNR,PNR,PNR,59,59,PNR,PNR,PNR +oldstat,18,PNR,PNR,PNR,PNR,PNR,PNR,PNR,PNR,PNR,18,18,PNR,PNR,PNR +olduname,109,PNR,PNR,PNR,PNR,PNR,PNR,PNR,PNR,PNR,109,109,PNR,PNR,PNR +open,5,2,2,5,PNR,5,2,2,5,5,5,5,PNR,5,5 +openat,295,257,257,322,56,288,247,251,275,275,286,286,56,288,288 +openat2,437,437,437,437,437,437,437,437,437,437,437,437,437,437,437 +open_by_handle_at,342,304,304,371,265,340,299,304,326,326,346,346,265,336,336 +open_tree,428,428,428,428,428,428,428,428,428,428,428,428,428,428,428 +pause,29,34,34,29,PNR,29,33,33,29,29,29,29,PNR,29,29 +pciconfig_iobase,PNR,PNR,PNR,271,PNR,PNR,PNR,PNR,PNR,PNR,200,200,PNR,PNR,PNR +pciconfig_read,PNR,PNR,PNR,272,PNR,PNR,PNR,PNR,PNR,PNR,198,198,PNR,PNR,PNR +pciconfig_write,PNR,PNR,PNR,273,PNR,PNR,PNR,PNR,PNR,PNR,199,199,PNR,PNR,PNR +perf_event_open,336,298,298,364,241,333,292,296,318,318,319,319,241,331,331 +personality,136,135,135,136,92,136,132,132,136,136,136,136,92,136,136 +pidfd_getfd,438,438,438,438,438,438,438,438,438,438,438,438,438,438,438 +pidfd_open,434,434,434,434,434,434,434,434,434,434,434,434,434,434,434 +pidfd_send_signal,424,424,424,424,424,424,424,424,424,424,424,424,424,424,424 +pipe,42,22,22,42,PNR,42,21,21,42,42,42,42,PNR,42,42 +pipe2,331,293,293,359,59,328,287,291,313,313,317,317,59,325,325 +pivot_root,217,155,155,218,41,216,151,151,67,67,203,203,41,217,217 +pkey_alloc,381,330,330,395,289,364,324,328,352,352,384,384,289,385,385 +pkey_free,382,331,331,396,290,365,325,329,353,353,385,385,290,386,386 +pkey_mprotect,380,329,329,394,288,363,323,327,351,351,386,386,288,384,384 +poll,168,7,7,168,PNR,188,7,7,168,168,167,167,PNR,168,168 +ppoll,309,271,271,336,73,302,261,265,274,274,281,281,73,302,302 +ppoll_time64,414,PNR,PNR,414,PNR,414,PNR,414,414,PNR,414,PNR,PNR,414,PNR +prctl,172,157,157,172,167,192,153,153,172,172,171,171,167,172,172 +pread64,180,17,17,180,67,200,16,16,108,108,179,179,67,180,180 +preadv,333,295,534,361,69,330,289,293,315,315,320,320,69,328,328 +preadv2,378,327,546,392,286,361,321,325,347,347,380,380,286,376,376 +prlimit64,340,302,302,369,261,338,297,302,321,321,325,325,261,334,334 +process_madvise,440,440,440,440,440,440,440,440,440,440,440,440,440,440,440 +process_mrelease,448,448,448,448,448,448,448,448,448,448,448,448,448,448,448 +process_vm_readv,347,310,539,376,270,345,304,309,330,330,351,351,270,340,340 +process_vm_writev,348,311,540,377,271,346,305,310,331,331,352,352,271,341,341 +prof,44,PNR,PNR,PNR,PNR,44,PNR,PNR,PNR,PNR,44,44,PNR,PNR,PNR +profil,98,PNR,PNR,PNR,PNR,98,PNR,PNR,PNR,PNR,98,98,PNR,PNR,PNR +pselect6,308,270,270,335,72,301,260,264,273,273,280,280,72,301,301 +pselect6_time64,413,PNR,PNR,413,PNR,413,PNR,413,413,PNR,413,PNR,PNR,413,PNR +ptrace,26,101,521,26,117,26,99,99,26,26,26,26,117,26,26 +putpmsg,189,182,182,PNR,PNR,209,175,175,PNR,PNR,188,188,PNR,189,189 +pwrite64,181,18,18,181,68,201,17,17,109,109,180,180,68,181,181 +pwritev,334,296,535,362,70,331,290,294,316,316,321,321,70,329,329 +pwritev2,379,328,547,393,287,362,322,326,348,348,381,381,287,377,377 +query_module,167,178,PNR,PNR,PNR,187,171,171,PNR,PNR,166,166,PNR,167,167 +quotactl,131,179,179,131,60,131,172,172,131,131,131,131,60,131,131 +quotactl_fd,443,443,443,443,443,443,443,443,443,443,443,443,443,443,443 +read,3,0,0,3,63,3,0,0,3,3,3,3,63,3,3 +readahead,225,187,187,225,213,223,179,179,207,207,191,191,213,222,222 +readdir,89,PNR,PNR,PNR,PNR,89,PNR,PNR,PNR,PNR,89,89,PNR,89,89 +readlink,85,89,89,85,PNR,85,87,87,85,85,85,85,PNR,85,85 +readlinkat,305,267,267,332,78,298,257,261,285,285,296,296,78,298,298 +readv,145,19,515,145,65,145,18,18,145,145,145,145,65,145,145 +reboot,88,169,169,88,142,88,164,164,88,88,88,88,142,88,88 +recv,PNR,PNR,PNR,291,PNR,175,PNR,PNR,98,98,336,336,PNR,PNR,PNR +recvfrom,371,45,517,292,207,176,44,44,123,123,337,337,207,371,371 +recvmmsg,337,299,537,365,243,335,294,298,319,319,343,343,243,357,357 +recvmmsg_time64,417,PNR,PNR,417,PNR,417,PNR,417,417,PNR,417,PNR,PNR,417,PNR +recvmsg,372,47,519,297,212,177,46,46,184,184,342,342,212,372,372 +remap_file_pages,257,216,216,253,234,251,210,210,227,227,239,239,234,267,267 +removexattr,235,197,197,235,14,233,189,189,247,247,218,218,14,233,233 +rename,38,82,82,38,PNR,38,80,80,38,38,38,38,PNR,38,38 +renameat,302,264,264,329,38,295,254,258,282,282,293,293,PNR,295,295 +renameat2,353,316,316,382,276,351,311,315,337,337,357,357,276,347,347 +request_key,287,249,249,310,218,281,240,244,265,265,270,270,218,279,279 +restart_syscall,0,219,219,0,128,253,213,214,0,0,0,0,128,7,7 +riscv_flush_icache,PNR,PNR,PNR,PNR,PNR,PNR,PNR,PNR,PNR,PNR,PNR,PNR,259,PNR,PNR +rmdir,40,84,84,40,PNR,40,82,82,40,40,40,40,PNR,40,40 +rseq,386,334,334,398,293,367,327,331,354,354,387,387,293,383,383 +rtas,PNR,PNR,PNR,PNR,PNR,PNR,PNR,PNR,PNR,PNR,255,255,PNR,PNR,PNR +rt_sigaction,174,13,512,174,134,194,13,13,174,174,173,173,134,174,174 +rt_sigpending,176,127,522,176,136,196,125,125,176,176,175,175,136,176,176 +rt_sigprocmask,175,14,14,175,135,195,14,14,175,175,174,174,135,175,175 +rt_sigqueueinfo,178,129,524,178,138,198,127,127,178,178,177,177,138,178,178 +rt_sigreturn,173,15,513,173,139,193,211,211,173,173,172,172,139,173,173 +rt_sigsuspend,179,130,130,179,133,199,128,128,179,179,178,178,133,179,179 +rt_sigtimedwait,177,128,523,177,137,197,126,126,177,177,176,176,137,177,177 +rt_sigtimedwait_time64,421,PNR,PNR,421,PNR,421,PNR,421,421,PNR,421,PNR,PNR,421,PNR +rt_tgsigqueueinfo,335,297,536,363,240,332,291,295,317,317,322,322,240,330,330 +s390_guarded_storage,PNR,PNR,PNR,PNR,PNR,PNR,PNR,PNR,PNR,PNR,PNR,PNR,PNR,378,378 +s390_pci_mmio_read,PNR,PNR,PNR,PNR,PNR,PNR,PNR,PNR,PNR,PNR,PNR,PNR,PNR,353,353 +s390_pci_mmio_write,PNR,PNR,PNR,PNR,PNR,PNR,PNR,PNR,PNR,PNR,PNR,PNR,PNR,352,352 +s390_runtime_instr,PNR,PNR,PNR,PNR,PNR,PNR,PNR,PNR,PNR,PNR,PNR,PNR,PNR,342,342 +s390_sthyi,PNR,PNR,PNR,PNR,PNR,PNR,PNR,PNR,PNR,PNR,PNR,PNR,PNR,380,380 +sched_getaffinity,242,204,204,242,123,240,196,196,212,212,223,223,123,240,240 +sched_getattr,352,315,315,381,275,350,310,314,335,335,356,356,275,346,346 +sched_getparam,155,143,143,155,121,159,140,140,155,155,155,155,121,155,155 +sched_get_priority_max,159,146,146,159,125,163,143,143,159,159,159,159,125,159,159 +sched_get_priority_min,160,147,147,160,126,164,144,144,160,160,160,160,126,160,160 +sched_getscheduler,157,145,145,157,120,161,142,142,157,157,157,157,120,157,157 +sched_rr_get_interval,161,148,148,161,127,165,145,145,161,161,161,161,127,161,161 +sched_rr_get_interval_time64,423,PNR,PNR,423,PNR,423,PNR,423,423,PNR,423,PNR,PNR,423,PNR +sched_setaffinity,241,203,203,241,122,239,195,195,211,211,222,222,122,239,239 +sched_setattr,351,314,314,380,274,349,309,313,334,334,355,355,274,345,345 +sched_setparam,154,142,142,154,118,158,139,139,154,154,154,154,118,154,154 +sched_setscheduler,156,144,144,156,119,160,141,141,156,156,156,156,119,156,156 +sched_yield,158,24,24,158,124,162,23,23,158,158,158,158,124,158,158 +seccomp,354,317,317,383,277,352,312,316,338,338,358,358,277,348,348 +security,PNR,185,185,PNR,PNR,PNR,PNR,PNR,PNR,PNR,PNR,PNR,PNR,PNR,PNR +select,82,23,23,PNR,PNR,PNR,PNR,PNR,PNR,PNR,82,82,PNR,PNR,142 +semctl,394,66,66,300,191,394,64,64,187,187,394,394,191,394,394 +semget,393,64,64,299,190,393,62,62,186,186,393,393,190,393,393 +semop,PNR,65,65,298,193,PNR,63,63,185,185,PNR,PNR,193,PNR,PNR +semtimedop,PNR,220,220,312,192,PNR,214,215,228,228,PNR,392,192,PNR,392 +semtimedop_time64,420,PNR,PNR,420,PNR,420,PNR,420,420,PNR,420,PNR,PNR,420,PNR +send,PNR,PNR,PNR,289,PNR,178,PNR,PNR,58,58,334,334,PNR,PNR,PNR +sendfile,187,40,40,187,71,207,39,39,122,122,186,186,71,187,187 +sendfile64,239,PNR,PNR,239,PNR,237,PNR,219,209,209,226,PNR,PNR,223,PNR +sendmmsg,345,307,538,374,269,343,302,307,329,329,349,349,269,358,358 +sendmsg,370,46,518,296,211,179,45,45,183,183,341,341,211,370,370 +sendto,369,44,44,290,206,180,43,43,82,82,335,335,206,369,369 +setdomainname,121,171,171,121,162,121,166,166,121,121,121,121,162,121,121 +setfsgid,139,123,123,139,152,139,121,121,139,139,139,139,152,139,216 +setfsgid32,216,PNR,PNR,216,PNR,PNR,PNR,PNR,PNR,PNR,PNR,PNR,PNR,216,PNR +setfsuid,138,122,122,138,151,138,120,120,138,138,138,138,151,138,215 +setfsuid32,215,PNR,PNR,215,PNR,PNR,PNR,PNR,PNR,PNR,PNR,PNR,PNR,215,PNR +setgid,46,106,106,46,144,46,104,104,46,46,46,46,144,46,214 +setgid32,214,PNR,PNR,214,PNR,PNR,PNR,PNR,PNR,PNR,PNR,PNR,PNR,214,PNR +setgroups,81,116,116,81,159,81,114,114,81,81,81,81,159,81,206 +setgroups32,206,PNR,PNR,206,PNR,PNR,PNR,PNR,PNR,PNR,PNR,PNR,PNR,206,PNR +sethostname,74,170,170,74,161,74,165,165,74,74,74,74,161,74,74 +setitimer,104,38,38,104,103,104,36,36,104,104,104,104,103,104,104 +set_mempolicy,276,238,238,321,237,270,229,233,262,262,261,261,237,270,270 +set_mempolicy_home_node,450,450,450,450,450,450,450,450,450,450,450,450,450,450,450 +setns,346,308,308,375,268,344,303,308,328,328,350,350,268,339,339 +setpgid,57,109,109,57,154,57,107,107,57,57,57,57,154,57,57 +setpriority,97,141,141,97,140,97,138,138,97,97,97,97,140,97,97 +setregid,71,114,114,71,143,71,112,112,71,71,71,71,143,71,204 +setregid32,204,PNR,PNR,204,PNR,PNR,PNR,PNR,PNR,PNR,PNR,PNR,PNR,204,PNR +setresgid,170,119,119,170,149,190,117,117,170,170,169,169,149,170,210 +setresgid32,210,PNR,PNR,210,PNR,PNR,PNR,PNR,PNR,PNR,PNR,PNR,PNR,210,PNR +setresuid,164,117,117,164,147,185,115,115,164,164,164,164,147,164,208 +setresuid32,208,PNR,PNR,208,PNR,PNR,PNR,PNR,PNR,PNR,PNR,PNR,PNR,208,PNR +setreuid,70,113,113,70,145,70,111,111,70,70,70,70,145,70,203 +setreuid32,203,PNR,PNR,203,PNR,PNR,PNR,PNR,PNR,PNR,PNR,PNR,PNR,203,PNR +setrlimit,75,160,160,75,164,75,155,155,75,75,75,75,164,75,75 +set_robust_list,311,273,530,338,99,309,268,272,289,289,300,300,99,304,304 +setsid,66,112,112,66,157,66,110,110,66,66,66,66,157,66,66 +setsockopt,366,54,541,294,208,181,53,53,181,181,339,339,208,366,366 +set_thread_area,243,205,PNR,PNR,PNR,283,242,246,PNR,PNR,PNR,PNR,PNR,PNR,PNR +set_tid_address,258,218,218,256,96,252,212,213,237,237,232,232,96,252,252 +settimeofday,79,164,164,79,170,79,159,159,79,79,79,79,170,79,79 +set_tls,PNR,PNR,PNR,983045,PNR,PNR,PNR,PNR,PNR,PNR,PNR,PNR,PNR,PNR,PNR +setuid,23,105,105,23,146,23,103,103,23,23,23,23,146,23,213 +setuid32,213,PNR,PNR,213,PNR,PNR,PNR,PNR,PNR,PNR,PNR,PNR,PNR,213,PNR +setxattr,226,188,188,226,5,224,180,180,238,238,209,209,5,224,224 +sgetmask,68,PNR,PNR,PNR,PNR,68,PNR,PNR,68,68,68,68,PNR,PNR,PNR +shmat,397,30,30,305,196,397,29,29,192,192,397,397,196,397,397 +shmctl,396,31,31,308,195,396,30,30,195,195,396,396,195,396,396 +shmdt,398,67,67,306,197,398,65,65,193,193,398,398,197,398,398 +shmget,395,29,29,307,194,395,28,28,194,194,395,395,194,395,395 +shutdown,373,48,48,293,210,182,47,47,117,117,338,338,210,373,373 +sigaction,67,PNR,PNR,67,PNR,67,PNR,PNR,PNR,PNR,67,67,PNR,67,67 +sigaltstack,186,131,525,186,132,206,129,129,166,166,185,185,132,186,186 +signal,48,PNR,PNR,PNR,PNR,48,PNR,PNR,48,48,48,48,PNR,48,48 +signalfd,321,282,282,349,PNR,317,276,280,302,302,305,305,PNR,316,316 +signalfd4,327,289,289,355,74,324,283,287,309,309,313,313,74,322,322 +sigpending,73,PNR,PNR,73,PNR,73,PNR,PNR,73,73,73,73,PNR,73,73 +sigprocmask,126,PNR,PNR,126,PNR,126,PNR,PNR,126,126,126,126,PNR,126,126 +sigreturn,119,PNR,PNR,119,PNR,119,PNR,PNR,PNR,PNR,119,119,PNR,119,119 +sigsuspend,72,PNR,PNR,72,PNR,72,PNR,PNR,PNR,PNR,72,72,PNR,72,72 +socket,359,41,41,281,198,183,40,40,17,17,326,326,198,359,359 +socketcall,102,PNR,PNR,PNR,PNR,102,PNR,PNR,PNR,PNR,102,102,PNR,102,102 +socketpair,360,53,53,288,199,184,52,52,56,56,333,333,199,360,360 +splice,313,275,275,340,76,304,263,267,291,291,283,283,76,306,306 +spu_create,PNR,PNR,PNR,PNR,PNR,PNR,PNR,PNR,PNR,PNR,279,279,PNR,PNR,PNR +spu_run,PNR,PNR,PNR,PNR,PNR,PNR,PNR,PNR,PNR,PNR,278,278,PNR,PNR,PNR +ssetmask,69,PNR,PNR,PNR,PNR,69,PNR,PNR,69,69,69,69,PNR,PNR,PNR +stat,106,4,4,106,PNR,106,4,4,18,18,106,106,PNR,106,106 +stat64,195,PNR,PNR,195,PNR,213,PNR,PNR,101,101,195,PNR,PNR,195,PNR +statfs,99,137,137,99,43,99,134,134,99,99,99,99,43,99,99 +statfs64,268,PNR,PNR,266,PNR,255,PNR,217,298,298,252,252,PNR,265,265 +statx,383,332,332,397,291,366,326,330,349,349,383,383,291,379,379 +stime,25,PNR,PNR,PNR,PNR,25,PNR,PNR,25,25,25,25,PNR,25,PNR +stty,31,PNR,PNR,PNR,PNR,31,PNR,PNR,PNR,PNR,31,31,PNR,PNR,PNR +subpage_prot,PNR,PNR,PNR,PNR,PNR,PNR,PNR,PNR,PNR,PNR,310,310,PNR,PNR,PNR +swapcontext,PNR,PNR,PNR,PNR,PNR,PNR,PNR,PNR,PNR,PNR,249,249,PNR,PNR,PNR +swapoff,115,168,168,115,225,115,163,163,115,115,115,115,225,115,115 +swapon,87,167,167,87,224,87,162,162,87,87,87,87,224,87,87 +switch_endian,PNR,PNR,PNR,PNR,PNR,PNR,PNR,PNR,PNR,PNR,363,363,PNR,PNR,PNR +symlink,83,88,88,83,PNR,83,86,86,83,83,83,83,PNR,83,83 +symlinkat,304,266,266,331,36,297,256,260,284,284,295,295,36,297,297 +sync,36,162,162,36,81,36,157,157,36,36,36,36,81,36,36 +sync_file_range,314,277,277,PNR,84,305,264,268,292,292,PNR,PNR,84,307,307 +sync_file_range2,PNR,PNR,PNR,PNR,PNR,PNR,PNR,PNR,PNR,PNR,308,308,PNR,PNR,PNR +syncfs,344,306,306,373,267,342,301,306,327,327,348,348,267,338,338 +syscall,PNR,PNR,PNR,PNR,PNR,0,PNR,PNR,PNR,PNR,PNR,PNR,PNR,PNR,PNR +_sysctl,149,156,PNR,149,PNR,153,152,152,149,149,149,149,PNR,149,149 +sys_debug_setcontext,PNR,PNR,PNR,PNR,PNR,PNR,PNR,PNR,PNR,PNR,256,256,PNR,PNR,PNR +sysfs,135,139,139,135,PNR,135,136,136,135,135,135,135,PNR,135,135 +sysinfo,116,99,99,116,179,116,97,97,116,116,116,116,179,116,116 +syslog,103,103,103,103,116,103,101,101,103,103,103,103,116,103,103 +sysmips,PNR,PNR,PNR,PNR,PNR,149,199,199,PNR,PNR,PNR,PNR,PNR,PNR,PNR +tee,315,276,276,342,77,306,265,269,293,293,284,284,77,308,308 +tgkill,270,234,234,268,131,266,225,229,259,259,250,250,131,241,241 +time,13,201,201,PNR,PNR,13,PNR,PNR,13,13,13,13,PNR,13,PNR +timer_create,259,222,526,257,107,257,216,220,250,250,240,240,107,254,254 +timer_delete,263,226,226,261,111,261,220,224,254,254,244,244,111,258,258 +timerfd,PNR,PNR,PNR,PNR,PNR,318,277,281,PNR,PNR,PNR,PNR,PNR,317,317 +timerfd_create,322,283,283,350,85,321,280,284,306,306,306,306,85,319,319 +timerfd_gettime,326,287,287,354,87,322,281,285,308,308,312,312,87,321,321 +timerfd_gettime64,410,PNR,PNR,410,PNR,410,PNR,410,410,PNR,410,PNR,PNR,410,PNR +timerfd_settime,325,286,286,353,86,323,282,286,307,307,311,311,86,320,320 +timerfd_settime64,411,PNR,PNR,411,PNR,411,PNR,411,411,PNR,411,PNR,PNR,411,PNR +timer_getoverrun,262,225,225,260,109,260,219,223,253,253,243,243,109,257,257 +timer_gettime,261,224,224,259,108,259,218,222,252,252,242,242,108,256,256 +timer_gettime64,408,PNR,PNR,408,PNR,408,PNR,408,408,PNR,408,PNR,PNR,408,PNR +timer_settime,260,223,223,258,110,258,217,221,251,251,241,241,110,255,255 +timer_settime64,409,PNR,PNR,409,PNR,409,PNR,409,409,PNR,409,PNR,PNR,409,PNR +times,43,100,100,43,153,43,98,98,43,43,43,43,153,43,43 +tkill,238,200,200,238,130,236,192,192,208,208,208,208,130,237,237 +truncate,92,76,76,92,45,92,74,74,92,92,92,92,45,92,92 +truncate64,193,PNR,PNR,193,PNR,211,PNR,PNR,199,199,193,PNR,PNR,193,PNR +tuxcall,PNR,184,184,PNR,PNR,PNR,PNR,PNR,PNR,PNR,225,225,PNR,PNR,PNR +ugetrlimit,191,PNR,PNR,191,PNR,PNR,PNR,PNR,PNR,PNR,190,190,PNR,191,PNR +ulimit,58,PNR,PNR,PNR,PNR,58,PNR,PNR,PNR,PNR,58,58,PNR,PNR,PNR +umask,60,95,95,60,166,60,93,93,60,60,60,60,166,60,60 +umount,22,PNR,PNR,PNR,PNR,22,PNR,PNR,PNR,PNR,22,22,PNR,22,22 +umount2,52,166,166,52,39,52,161,161,52,52,52,52,39,52,52 +uname,122,63,63,122,160,122,61,61,59,59,122,122,160,122,122 +unlink,10,87,87,10,PNR,10,85,85,10,10,10,10,PNR,10,10 +unlinkat,301,263,263,328,35,294,253,257,281,281,292,292,35,294,294 +unshare,310,272,272,337,97,303,262,266,288,288,282,282,97,303,303 +uselib,86,134,PNR,86,PNR,86,PNR,PNR,86,86,86,86,PNR,86,86 +userfaultfd,374,323,323,388,282,357,317,321,344,344,364,364,282,355,355 +usr26,PNR,PNR,PNR,983043,PNR,PNR,PNR,PNR,PNR,PNR,PNR,PNR,PNR,PNR,PNR +usr32,PNR,PNR,PNR,983044,PNR,PNR,PNR,PNR,PNR,PNR,PNR,PNR,PNR,PNR,PNR +ustat,62,136,136,62,PNR,62,133,133,62,62,62,62,PNR,62,62 +utime,30,132,132,PNR,PNR,30,130,130,30,30,30,30,PNR,30,30 +utimensat,320,280,280,348,88,316,275,279,301,301,304,304,88,315,315 +utimensat_time64,412,PNR,PNR,412,PNR,412,PNR,412,412,PNR,412,PNR,PNR,412,PNR +utimes,271,235,235,269,PNR,267,226,230,336,336,251,251,PNR,313,313 +vfork,190,58,58,190,PNR,PNR,PNR,PNR,113,113,189,189,PNR,190,190 +vhangup,111,153,153,111,58,111,150,150,111,111,111,111,58,111,111 +vm86,166,PNR,PNR,PNR,PNR,113,PNR,PNR,PNR,PNR,113,113,PNR,PNR,PNR +vm86old,113,PNR,PNR,PNR,PNR,PNR,PNR,PNR,PNR,PNR,PNR,PNR,PNR,PNR,PNR +vmsplice,316,278,532,343,75,307,266,270,294,294,285,285,75,309,309 +vserver,273,236,PNR,313,PNR,277,236,240,PNR,PNR,PNR,PNR,PNR,PNR,PNR +wait4,114,61,61,114,260,114,59,59,114,114,114,114,260,114,114 +waitid,284,247,529,280,95,278,237,241,235,235,272,272,95,281,281 +waitpid,7,PNR,PNR,PNR,PNR,7,PNR,PNR,7,7,7,7,PNR,PNR,PNR +write,4,1,1,4,64,4,1,1,4,4,4,4,64,4,4 +writev,146,20,516,146,66,146,19,19,146,146,146,146,66,146,146 diff --git a/src/syscalls.h b/src/syscalls.h new file mode 100644 index 0000000..af468a1 --- /dev/null +++ b/src/syscalls.h @@ -0,0 +1,70 @@ +/** + * Enhanced Seccomp x86_64 Syscall Table + * + * Copyright (c) 2012, 2020 Red Hat <pmoore@redhat.com> + * Author: Paul Moore <paul@paul-moore.com> + * gperf support: Giuseppe Scrivano <gscrivan@redhat.com> + */ + +#ifndef _SYSCALLS_H +#define _SYSCALLS_H + +#include <stddef.h> + +#include "arch-aarch64.h" +#include "arch-arm.h" +#include "arch.h" +#include "arch-mips64.h" +#include "arch-mips64n32.h" +#include "arch-mips.h" +#include "arch-parisc.h" +#include "arch-ppc64.h" +#include "arch-ppc.h" +#include "arch-s390.h" +#include "arch-s390x.h" +#include "arch-x32.h" +#include "arch-x86_64.h" +#include "arch-x86.h" +#include "arch-x86.h" +#include "arch-riscv64.h" + +/* NOTE: changes to the arch_syscall_table layout may require changes to the + * generate_syscalls_perf.sh and arch-syscall-validate scripts */ +struct arch_syscall_table { + int name; + int index; + + /* each arch listed here must be defined in syscalls.c */ + /* NOTE: see the warning above - BEWARE! */ + int x86; + int x86_64; + int x32; + int arm; + int aarch64; + int mips; + int mips64; + int mips64n32; + int parisc; + int parisc64; + int ppc; + int ppc64; + int riscv64; + int s390; + int s390x; +}; +#define OFFSET_ARCH(NAME) offsetof(struct arch_syscall_table, NAME) + +/* defined in syscalls.perf.template */ +int syscall_resolve_name(const char *name, int offset); +const char *syscall_resolve_num(int num, int offset); +const struct arch_syscall_def *syscall_iterate(unsigned int spot, int offset); + +/* helper functions for multiplexed syscalls, e.g. socketcall(2) and ipc(2) */ +int abi_syscall_resolve_name_munge(const struct arch_def *arch, + const char *name); +const char *abi_syscall_resolve_num_munge(const struct arch_def *arch, int num); +int abi_syscall_rewrite(const struct arch_def *arch, int *syscall); +int abi_rule_add(struct db_filter *db, struct db_api_rule_list *rule); + + +#endif diff --git a/src/syscalls.perf b/src/syscalls.perf new file mode 100644 index 0000000..0d5459a --- /dev/null +++ b/src/syscalls.perf @@ -0,0 +1,568 @@ +%{ +/** + * Copyright (c) 2012 Red Hat <pmoore@redhat.com> + * Copyright (c) 2020 Red Hat <gscrivan@redhat.com> + * Authors: Paul Moore <paul@paul-moore.com> + * Giuseppe Scrivano <gscrivan@redhat.com> + */ + +/* + * 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 <seccomp.h> +#include <string.h> +#include "syscalls.h" + +%} +struct arch_syscall_table; + +%% +accept,0,__PNR_accept,43,43,285,202,168,42,42,35,35,330,330,202,__PNR_accept,__PNR_accept +accept4,1,364,288,288,366,242,334,293,297,320,320,344,344,242,364,364 +access,2,33,21,21,33,__PNR_access,33,20,20,33,33,33,33,__PNR_access,33,33 +acct,3,51,163,163,51,89,51,158,158,51,51,51,51,89,51,51 +add_key,4,286,248,248,309,217,280,239,243,264,264,269,269,217,278,278 +adjtimex,5,124,159,159,124,171,124,154,154,124,124,124,124,171,124,124 +afs_syscall,6,137,183,183,__PNR_afs_syscall,__PNR_afs_syscall,137,176,176,__PNR_afs_syscall,__PNR_afs_syscall,137,137,__PNR_afs_syscall,137,137 +alarm,7,27,37,37,__PNR_alarm,__PNR_alarm,27,37,37,27,27,27,27,__PNR_alarm,27,27 +arch_prctl,8,384,158,158,__PNR_arch_prctl,__PNR_arch_prctl,__PNR_arch_prctl,__PNR_arch_prctl,__PNR_arch_prctl,__PNR_arch_prctl,__PNR_arch_prctl,__PNR_arch_prctl,__PNR_arch_prctl,__PNR_arch_prctl,__PNR_arch_prctl,__PNR_arch_prctl +arm_fadvise64_64,9,__PNR_arm_fadvise64_64,__PNR_arm_fadvise64_64,__PNR_arm_fadvise64_64,270,__PNR_arm_fadvise64_64,__PNR_arm_fadvise64_64,__PNR_arm_fadvise64_64,__PNR_arm_fadvise64_64,__PNR_arm_fadvise64_64,__PNR_arm_fadvise64_64,__PNR_arm_fadvise64_64,__PNR_arm_fadvise64_64,__PNR_arm_fadvise64_64,__PNR_arm_fadvise64_64,__PNR_arm_fadvise64_64 +arm_sync_file_range,10,__PNR_arm_sync_file_range,__PNR_arm_sync_file_range,__PNR_arm_sync_file_range,341,__PNR_arm_sync_file_range,__PNR_arm_sync_file_range,__PNR_arm_sync_file_range,__PNR_arm_sync_file_range,__PNR_arm_sync_file_range,__PNR_arm_sync_file_range,__PNR_arm_sync_file_range,__PNR_arm_sync_file_range,__PNR_arm_sync_file_range,__PNR_arm_sync_file_range,__PNR_arm_sync_file_range +bdflush,11,134,__PNR_bdflush,__PNR_bdflush,134,__PNR_bdflush,134,__PNR_bdflush,__PNR_bdflush,134,134,134,134,__PNR_bdflush,134,134 +bind,12,361,49,49,282,200,169,48,48,22,22,327,327,200,361,361 +bpf,13,357,321,321,386,280,355,315,319,341,341,361,361,280,351,351 +break,14,17,__PNR_break,__PNR_break,__PNR_break,__PNR_break,17,__PNR_break,__PNR_break,__PNR_break,__PNR_break,17,17,__PNR_break,__PNR_break,__PNR_break +breakpoint,15,__PNR_breakpoint,__PNR_breakpoint,__PNR_breakpoint,983041,__PNR_breakpoint,__PNR_breakpoint,__PNR_breakpoint,__PNR_breakpoint,__PNR_breakpoint,__PNR_breakpoint,__PNR_breakpoint,__PNR_breakpoint,__PNR_breakpoint,__PNR_breakpoint,__PNR_breakpoint +brk,16,45,12,12,45,214,45,12,12,45,45,45,45,214,45,45 +cachectl,17,__PNR_cachectl,__PNR_cachectl,__PNR_cachectl,__PNR_cachectl,__PNR_cachectl,148,198,198,__PNR_cachectl,__PNR_cachectl,__PNR_cachectl,__PNR_cachectl,__PNR_cachectl,__PNR_cachectl,__PNR_cachectl +cacheflush,18,__PNR_cacheflush,__PNR_cacheflush,__PNR_cacheflush,983042,__PNR_cacheflush,147,197,197,356,356,__PNR_cacheflush,__PNR_cacheflush,__PNR_cacheflush,__PNR_cacheflush,__PNR_cacheflush +cachestat,19,451,451,451,451,451,451,451,451,451,451,451,451,451,451,451 +capget,20,184,125,125,184,90,204,123,123,106,106,183,183,90,184,184 +capset,21,185,126,126,185,91,205,124,124,107,107,184,184,91,185,185 +chdir,22,12,80,80,12,49,12,78,78,12,12,12,12,49,12,12 +chmod,23,15,90,90,15,__PNR_chmod,15,88,88,15,15,15,15,__PNR_chmod,15,15 +chown,24,182,92,92,182,__PNR_chown,202,90,90,180,180,181,181,__PNR_chown,182,212 +chown32,25,212,__PNR_chown32,__PNR_chown32,212,__PNR_chown32,__PNR_chown32,__PNR_chown32,__PNR_chown32,__PNR_chown32,__PNR_chown32,__PNR_chown32,__PNR_chown32,__PNR_chown32,212,__PNR_chown32 +chroot,26,61,161,161,61,51,61,156,156,61,61,61,61,51,61,61 +clock_adjtime,27,343,305,305,372,266,341,300,305,324,324,347,347,266,337,337 +clock_adjtime64,28,405,__PNR_clock_adjtime64,__PNR_clock_adjtime64,405,__PNR_clock_adjtime64,405,__PNR_clock_adjtime64,405,405,__PNR_clock_adjtime64,405,__PNR_clock_adjtime64,__PNR_clock_adjtime64,405,__PNR_clock_adjtime64 +clock_getres,29,266,229,229,264,114,264,223,227,257,257,247,247,114,261,261 +clock_getres_time64,30,406,__PNR_clock_getres_time64,__PNR_clock_getres_time64,406,__PNR_clock_getres_time64,406,__PNR_clock_getres_time64,406,406,__PNR_clock_getres_time64,406,__PNR_clock_getres_time64,__PNR_clock_getres_time64,406,__PNR_clock_getres_time64 +clock_gettime,31,265,228,228,263,113,263,222,226,256,256,246,246,113,260,260 +clock_gettime64,32,403,__PNR_clock_gettime64,__PNR_clock_gettime64,403,__PNR_clock_gettime64,403,__PNR_clock_gettime64,403,403,__PNR_clock_gettime64,403,__PNR_clock_gettime64,__PNR_clock_gettime64,403,__PNR_clock_gettime64 +clock_nanosleep,33,267,230,230,265,115,265,224,228,258,258,248,248,115,262,262 +clock_nanosleep_time64,34,407,__PNR_clock_nanosleep_time64,__PNR_clock_nanosleep_time64,407,__PNR_clock_nanosleep_time64,407,__PNR_clock_nanosleep_time64,407,407,__PNR_clock_nanosleep_time64,407,__PNR_clock_nanosleep_time64,__PNR_clock_nanosleep_time64,407,__PNR_clock_nanosleep_time64 +clock_settime,35,264,227,227,262,112,262,221,225,255,255,245,245,112,259,259 +clock_settime64,36,404,__PNR_clock_settime64,__PNR_clock_settime64,404,__PNR_clock_settime64,404,__PNR_clock_settime64,404,404,__PNR_clock_settime64,404,__PNR_clock_settime64,__PNR_clock_settime64,404,__PNR_clock_settime64 +clone,37,120,56,56,120,220,120,55,55,120,120,120,120,220,120,120 +clone3,38,435,435,435,435,435,435,435,435,435,435,435,435,435,435,435 +close,39,6,3,3,6,57,6,3,3,6,6,6,6,57,6,6 +close_range,40,436,436,436,436,436,436,436,436,436,436,436,436,436,436,436 +connect,41,362,42,42,283,203,170,41,41,31,31,328,328,203,362,362 +copy_file_range,42,377,326,326,391,285,360,320,324,346,346,379,379,285,375,375 +creat,43,8,85,85,8,__PNR_creat,8,83,83,8,8,8,8,__PNR_creat,8,8 +create_module,44,127,174,__PNR_create_module,__PNR_create_module,__PNR_create_module,127,167,167,__PNR_create_module,__PNR_create_module,127,127,__PNR_create_module,127,127 +delete_module,45,129,176,176,129,106,129,169,169,129,129,129,129,106,129,129 +dup,46,41,32,32,41,23,41,31,31,41,41,41,41,23,41,41 +dup2,47,63,33,33,63,__PNR_dup2,63,32,32,63,63,63,63,__PNR_dup2,63,63 +dup3,48,330,292,292,358,24,327,286,290,312,312,316,316,24,326,326 +epoll_create,49,254,213,213,250,__PNR_epoll_create,248,207,207,224,224,236,236,__PNR_epoll_create,249,249 +epoll_create1,50,329,291,291,357,20,326,285,289,311,311,315,315,20,327,327 +epoll_ctl,51,255,233,233,251,21,249,208,208,225,225,237,237,21,250,250 +epoll_ctl_old,52,__PNR_epoll_ctl_old,214,__PNR_epoll_ctl_old,__PNR_epoll_ctl_old,__PNR_epoll_ctl_old,__PNR_epoll_ctl_old,__PNR_epoll_ctl_old,__PNR_epoll_ctl_old,__PNR_epoll_ctl_old,__PNR_epoll_ctl_old,__PNR_epoll_ctl_old,__PNR_epoll_ctl_old,__PNR_epoll_ctl_old,__PNR_epoll_ctl_old,__PNR_epoll_ctl_old +epoll_pwait,53,319,281,281,346,22,313,272,276,297,297,303,303,22,312,312 +epoll_pwait2,54,441,441,441,441,441,441,441,441,441,441,441,441,441,441,441 +epoll_wait,55,256,232,232,252,__PNR_epoll_wait,250,209,209,226,226,238,238,__PNR_epoll_wait,251,251 +epoll_wait_old,56,__PNR_epoll_wait_old,215,__PNR_epoll_wait_old,__PNR_epoll_wait_old,__PNR_epoll_wait_old,__PNR_epoll_wait_old,__PNR_epoll_wait_old,__PNR_epoll_wait_old,__PNR_epoll_wait_old,__PNR_epoll_wait_old,__PNR_epoll_wait_old,__PNR_epoll_wait_old,__PNR_epoll_wait_old,__PNR_epoll_wait_old,__PNR_epoll_wait_old +eventfd,57,323,284,284,351,__PNR_eventfd,319,278,282,304,304,307,307,__PNR_eventfd,318,318 +eventfd2,58,328,290,290,356,19,325,284,288,310,310,314,314,19,323,323 +execve,59,11,59,520,11,221,11,57,57,11,11,11,11,221,11,11 +execveat,60,358,322,545,387,281,356,316,320,342,342,362,362,281,354,354 +exit,61,1,60,60,1,93,1,58,58,1,1,1,1,93,1,1 +exit_group,62,252,231,231,248,94,246,205,205,222,222,234,234,94,248,248 +faccessat,63,307,269,269,334,48,300,259,263,287,287,298,298,48,300,300 +faccessat2,64,439,439,439,439,439,439,439,439,439,439,439,439,439,439,439 +fadvise64,65,250,221,221,__PNR_fadvise64,223,254,215,216,__PNR_fadvise64,__PNR_fadvise64,233,233,223,253,253 +fadvise64_64,66,272,__PNR_fadvise64_64,__PNR_fadvise64_64,__PNR_fadvise64_64,__PNR_fadvise64_64,__PNR_fadvise64_64,__PNR_fadvise64_64,__PNR_fadvise64_64,236,236,254,__PNR_fadvise64_64,__PNR_fadvise64_64,264,__PNR_fadvise64_64 +fallocate,67,324,285,285,352,47,320,279,283,305,305,309,309,47,314,314 +fanotify_init,68,338,300,300,367,262,336,295,300,322,322,323,323,262,332,332 +fanotify_mark,69,339,301,301,368,263,337,296,301,323,323,324,324,263,333,333 +fchdir,70,133,81,81,133,50,133,79,79,133,133,133,133,50,133,133 +fchmod,71,94,91,91,94,52,94,89,89,94,94,94,94,52,94,94 +fchmodat,72,306,268,268,333,53,299,258,262,286,286,297,297,53,299,299 +fchmodat2,73,452,452,452,452,452,452,452,452,452,452,452,452,452,452,452 +fchown,74,95,93,93,95,55,95,91,91,95,95,95,95,55,95,207 +fchown32,75,207,__PNR_fchown32,__PNR_fchown32,207,__PNR_fchown32,__PNR_fchown32,__PNR_fchown32,__PNR_fchown32,__PNR_fchown32,__PNR_fchown32,__PNR_fchown32,__PNR_fchown32,__PNR_fchown32,207,__PNR_fchown32 +fchownat,76,298,260,260,325,54,291,250,254,278,278,289,289,54,291,291 +fcntl,77,55,72,72,55,25,55,70,70,55,55,55,55,25,55,55 +fcntl64,78,221,__PNR_fcntl64,__PNR_fcntl64,221,__PNR_fcntl64,220,__PNR_fcntl64,212,202,202,204,__PNR_fcntl64,__PNR_fcntl64,221,__PNR_fcntl64 +fdatasync,79,148,75,75,148,83,152,73,73,148,148,148,148,83,148,148 +fgetxattr,80,231,193,193,231,10,229,185,185,243,243,214,214,10,229,229 +finit_module,81,350,313,313,379,273,348,307,312,333,333,353,353,273,344,344 +flistxattr,82,234,196,196,234,13,232,188,188,246,246,217,217,13,232,232 +flock,83,143,73,73,143,32,143,71,71,143,143,143,143,32,143,143 +fork,84,2,57,57,2,__PNR_fork,2,56,56,2,2,2,2,__PNR_fork,2,2 +fremovexattr,85,237,199,199,237,16,235,191,191,249,249,220,220,16,235,235 +fsconfig,86,431,431,431,431,431,431,431,431,431,431,431,431,431,431,431 +fsetxattr,87,228,190,190,228,7,226,182,182,240,240,211,211,7,226,226 +fsmount,88,432,432,432,432,432,432,432,432,432,432,432,432,432,432,432 +fsopen,89,430,430,430,430,430,430,430,430,430,430,430,430,430,430,430 +fspick,90,433,433,433,433,433,433,433,433,433,433,433,433,433,433,433 +fstat,91,108,5,5,108,80,108,5,5,28,28,108,108,80,108,108 +fstat64,92,197,__PNR_fstat64,__PNR_fstat64,197,__PNR_fstat64,215,__PNR_fstat64,__PNR_fstat64,112,112,197,__PNR_fstat64,__PNR_fstat64,197,__PNR_fstat64 +fstatat64,93,300,__PNR_fstatat64,__PNR_fstatat64,327,__PNR_fstatat64,293,__PNR_fstatat64,__PNR_fstatat64,280,280,291,__PNR_fstatat64,__PNR_fstatat64,293,__PNR_fstatat64 +fstatfs,94,100,138,138,100,44,100,135,135,100,100,100,100,44,100,100 +fstatfs64,95,269,__PNR_fstatfs64,__PNR_fstatfs64,267,__PNR_fstatfs64,256,__PNR_fstatfs64,218,299,299,253,253,__PNR_fstatfs64,266,266 +fsync,96,118,74,74,118,82,118,72,72,118,118,118,118,82,118,118 +ftime,97,35,__PNR_ftime,__PNR_ftime,__PNR_ftime,__PNR_ftime,35,__PNR_ftime,__PNR_ftime,__PNR_ftime,__PNR_ftime,35,35,__PNR_ftime,__PNR_ftime,__PNR_ftime +ftruncate,98,93,77,77,93,46,93,75,75,93,93,93,93,46,93,93 +ftruncate64,99,194,__PNR_ftruncate64,__PNR_ftruncate64,194,__PNR_ftruncate64,212,__PNR_ftruncate64,__PNR_ftruncate64,200,200,194,__PNR_ftruncate64,__PNR_ftruncate64,194,__PNR_ftruncate64 +futex,100,240,202,202,240,98,238,194,194,210,210,221,221,98,238,238 +futex_requeue,101,456,456,456,456,456,456,456,456,456,456,456,456,456,456,456 +futex_time64,102,422,__PNR_futex_time64,__PNR_futex_time64,422,__PNR_futex_time64,422,__PNR_futex_time64,422,422,__PNR_futex_time64,422,__PNR_futex_time64,__PNR_futex_time64,422,__PNR_futex_time64 +futex_wait,103,455,455,455,455,455,455,455,455,455,455,455,455,455,455,455 +futex_waitv,104,449,449,449,449,449,449,449,449,449,449,449,449,449,449,449 +futex_wake,105,454,454,454,454,454,454,454,454,454,454,454,454,454,454,454 +futimesat,106,299,261,261,326,__PNR_futimesat,292,251,255,279,279,290,290,__PNR_futimesat,292,292 +getcpu,107,318,309,309,345,168,312,271,275,296,296,302,302,168,311,311 +getcwd,108,183,79,79,183,17,203,77,77,110,110,182,182,17,183,183 +getdents,109,141,78,78,141,__PNR_getdents,141,76,76,141,141,141,141,__PNR_getdents,141,141 +getdents64,110,220,217,217,217,61,219,308,299,201,201,202,202,61,220,220 +getegid,111,50,108,108,50,177,50,106,106,50,50,50,50,177,50,202 +getegid32,112,202,__PNR_getegid32,__PNR_getegid32,202,__PNR_getegid32,__PNR_getegid32,__PNR_getegid32,__PNR_getegid32,__PNR_getegid32,__PNR_getegid32,__PNR_getegid32,__PNR_getegid32,__PNR_getegid32,202,__PNR_getegid32 +geteuid,113,49,107,107,49,175,49,105,105,49,49,49,49,175,49,201 +geteuid32,114,201,__PNR_geteuid32,__PNR_geteuid32,201,__PNR_geteuid32,__PNR_geteuid32,__PNR_geteuid32,__PNR_geteuid32,__PNR_geteuid32,__PNR_geteuid32,__PNR_geteuid32,__PNR_geteuid32,__PNR_geteuid32,201,__PNR_geteuid32 +getgid,115,47,104,104,47,176,47,102,102,47,47,47,47,176,47,200 +getgid32,116,200,__PNR_getgid32,__PNR_getgid32,200,__PNR_getgid32,__PNR_getgid32,__PNR_getgid32,__PNR_getgid32,__PNR_getgid32,__PNR_getgid32,__PNR_getgid32,__PNR_getgid32,__PNR_getgid32,200,__PNR_getgid32 +getgroups,117,80,115,115,80,158,80,113,113,80,80,80,80,158,80,205 +getgroups32,118,205,__PNR_getgroups32,__PNR_getgroups32,205,__PNR_getgroups32,__PNR_getgroups32,__PNR_getgroups32,__PNR_getgroups32,__PNR_getgroups32,__PNR_getgroups32,__PNR_getgroups32,__PNR_getgroups32,__PNR_getgroups32,205,__PNR_getgroups32 +getitimer,119,105,36,36,105,102,105,35,35,105,105,105,105,102,105,105 +get_kernel_syms,120,130,177,__PNR_get_kernel_syms,__PNR_get_kernel_syms,__PNR_get_kernel_syms,130,170,170,__PNR_get_kernel_syms,__PNR_get_kernel_syms,130,130,__PNR_get_kernel_syms,130,130 +get_mempolicy,121,275,239,239,320,236,269,228,232,261,261,260,260,236,269,269 +getpeername,122,368,52,52,287,205,171,51,51,53,53,332,332,205,368,368 +getpgid,123,132,121,121,132,155,132,119,119,132,132,132,132,155,132,132 +getpgrp,124,65,111,111,65,__PNR_getpgrp,65,109,109,65,65,65,65,__PNR_getpgrp,65,65 +getpid,125,20,39,39,20,172,20,38,38,20,20,20,20,172,20,20 +getpmsg,126,188,181,181,__PNR_getpmsg,__PNR_getpmsg,208,174,174,__PNR_getpmsg,__PNR_getpmsg,187,187,__PNR_getpmsg,188,188 +getppid,127,64,110,110,64,173,64,108,108,64,64,64,64,173,64,64 +getpriority,128,96,140,140,96,141,96,137,137,96,96,96,96,141,96,96 +getrandom,129,355,318,318,384,278,353,313,317,339,339,359,359,278,349,349 +getresgid,130,171,120,120,171,150,191,118,118,171,171,170,170,150,171,211 +getresgid32,131,211,__PNR_getresgid32,__PNR_getresgid32,211,__PNR_getresgid32,__PNR_getresgid32,__PNR_getresgid32,__PNR_getresgid32,__PNR_getresgid32,__PNR_getresgid32,__PNR_getresgid32,__PNR_getresgid32,__PNR_getresgid32,211,__PNR_getresgid32 +getresuid,132,165,118,118,165,148,186,116,116,165,165,165,165,148,165,209 +getresuid32,133,209,__PNR_getresuid32,__PNR_getresuid32,209,__PNR_getresuid32,__PNR_getresuid32,__PNR_getresuid32,__PNR_getresuid32,__PNR_getresuid32,__PNR_getresuid32,__PNR_getresuid32,__PNR_getresuid32,__PNR_getresuid32,209,__PNR_getresuid32 +getrlimit,134,76,97,97,__PNR_getrlimit,163,76,95,95,76,76,76,76,163,76,191 +get_robust_list,135,312,274,531,339,100,310,269,273,290,290,299,299,100,305,305 +getrusage,136,77,98,98,77,165,77,96,96,77,77,77,77,165,77,77 +getsid,137,147,124,124,147,156,151,122,122,147,147,147,147,156,147,147 +getsockname,138,367,51,51,286,204,172,50,50,44,44,331,331,204,367,367 +getsockopt,139,365,55,542,295,209,173,54,54,182,182,340,340,209,365,365 +get_thread_area,140,244,211,__PNR_get_thread_area,__PNR_get_thread_area,__PNR_get_thread_area,__PNR_get_thread_area,__PNR_get_thread_area,__PNR_get_thread_area,__PNR_get_thread_area,__PNR_get_thread_area,__PNR_get_thread_area,__PNR_get_thread_area,__PNR_get_thread_area,__PNR_get_thread_area,__PNR_get_thread_area +gettid,141,224,186,186,224,178,222,178,178,206,206,207,207,178,236,236 +gettimeofday,142,78,96,96,78,169,78,94,94,78,78,78,78,169,78,78 +get_tls,143,__PNR_get_tls,__PNR_get_tls,__PNR_get_tls,983046,__PNR_get_tls,__PNR_get_tls,__PNR_get_tls,__PNR_get_tls,__PNR_get_tls,__PNR_get_tls,__PNR_get_tls,__PNR_get_tls,__PNR_get_tls,__PNR_get_tls,__PNR_get_tls +getuid,144,24,102,102,24,174,24,100,100,24,24,24,24,174,24,199 +getuid32,145,199,__PNR_getuid32,__PNR_getuid32,199,__PNR_getuid32,__PNR_getuid32,__PNR_getuid32,__PNR_getuid32,__PNR_getuid32,__PNR_getuid32,__PNR_getuid32,__PNR_getuid32,__PNR_getuid32,199,__PNR_getuid32 +getxattr,146,229,191,191,229,8,227,183,183,241,241,212,212,8,227,227 +gtty,147,32,__PNR_gtty,__PNR_gtty,__PNR_gtty,__PNR_gtty,32,__PNR_gtty,__PNR_gtty,__PNR_gtty,__PNR_gtty,32,32,__PNR_gtty,__PNR_gtty,__PNR_gtty +idle,148,112,__PNR_idle,__PNR_idle,__PNR_idle,__PNR_idle,112,__PNR_idle,__PNR_idle,__PNR_idle,__PNR_idle,112,112,__PNR_idle,112,112 +init_module,149,128,175,175,128,105,128,168,168,128,128,128,128,105,128,128 +inotify_add_watch,150,292,254,254,317,27,285,244,248,270,270,276,276,27,285,285 +inotify_init,151,291,253,253,316,__PNR_inotify_init,284,243,247,269,269,275,275,__PNR_inotify_init,284,284 +inotify_init1,152,332,294,294,360,26,329,288,292,314,314,318,318,26,324,324 +inotify_rm_watch,153,293,255,255,318,28,286,245,249,271,271,277,277,28,286,286 +io_cancel,154,249,210,210,247,3,245,204,204,219,219,231,231,3,247,247 +ioctl,155,54,16,514,54,29,54,15,15,54,54,54,54,29,54,54 +io_destroy,156,246,207,207,244,1,242,201,201,216,216,228,228,1,244,244 +io_getevents,157,247,208,208,245,4,243,202,202,217,217,229,229,4,245,245 +ioperm,158,101,173,173,__PNR_ioperm,__PNR_ioperm,101,__PNR_ioperm,__PNR_ioperm,__PNR_ioperm,__PNR_ioperm,101,101,__PNR_ioperm,101,__PNR_ioperm +io_pgetevents,159,385,333,333,399,292,368,328,332,350,350,388,388,292,382,382 +io_pgetevents_time64,160,416,__PNR_io_pgetevents_time64,__PNR_io_pgetevents_time64,416,__PNR_io_pgetevents_time64,416,__PNR_io_pgetevents_time64,416,416,__PNR_io_pgetevents_time64,416,__PNR_io_pgetevents_time64,__PNR_io_pgetevents_time64,416,__PNR_io_pgetevents_time64 +iopl,161,110,172,172,__PNR_iopl,__PNR_iopl,110,__PNR_iopl,__PNR_iopl,__PNR_iopl,__PNR_iopl,110,110,__PNR_iopl,__PNR_iopl,__PNR_iopl +ioprio_get,162,290,252,252,315,31,315,274,278,268,268,274,274,31,283,283 +ioprio_set,163,289,251,251,314,30,314,273,277,267,267,273,273,30,282,282 +io_setup,164,245,206,543,243,0,241,200,200,215,215,227,227,0,243,243 +io_submit,165,248,209,544,246,2,244,203,203,218,218,230,230,2,246,246 +io_uring_enter,166,426,426,426,426,426,426,426,426,426,426,426,426,426,426,426 +io_uring_register,167,427,427,427,427,427,427,427,427,427,427,427,427,427,427,427 +io_uring_setup,168,425,425,425,425,425,425,425,425,425,425,425,425,425,425,425 +ipc,169,117,__PNR_ipc,__PNR_ipc,__PNR_ipc,__PNR_ipc,117,__PNR_ipc,__PNR_ipc,__PNR_ipc,__PNR_ipc,117,117,__PNR_ipc,117,117 +kcmp,170,349,312,312,378,272,347,306,311,332,332,354,354,272,343,343 +kexec_file_load,171,__PNR_kexec_file_load,320,320,401,294,__PNR_kexec_file_load,__PNR_kexec_file_load,__PNR_kexec_file_load,355,355,382,382,294,381,381 +kexec_load,172,283,246,528,347,104,311,270,274,300,300,268,268,104,277,277 +keyctl,173,288,250,250,311,219,282,241,245,266,266,271,271,219,280,280 +kill,174,37,62,62,37,129,37,60,60,37,37,37,37,129,37,37 +landlock_add_rule,175,445,445,445,445,445,445,445,445,445,445,445,445,445,445,445 +landlock_create_ruleset,176,444,444,444,444,444,444,444,444,444,444,444,444,444,444,444 +landlock_restrict_self,177,446,446,446,446,446,446,446,446,446,446,446,446,446,446,446 +lchown,178,16,94,94,16,__PNR_lchown,16,92,92,16,16,16,16,__PNR_lchown,16,198 +lchown32,179,198,__PNR_lchown32,__PNR_lchown32,198,__PNR_lchown32,__PNR_lchown32,__PNR_lchown32,__PNR_lchown32,__PNR_lchown32,__PNR_lchown32,__PNR_lchown32,__PNR_lchown32,__PNR_lchown32,198,__PNR_lchown32 +lgetxattr,180,230,192,192,230,9,228,184,184,242,242,213,213,9,228,228 +link,181,9,86,86,9,__PNR_link,9,84,84,9,9,9,9,__PNR_link,9,9 +linkat,182,303,265,265,330,37,296,255,259,283,283,294,294,37,296,296 +listen,183,363,50,50,284,201,174,49,49,32,32,329,329,201,363,363 +listxattr,184,232,194,194,232,11,230,186,186,244,244,215,215,11,230,230 +llistxattr,185,233,195,195,233,12,231,187,187,245,245,216,216,12,231,231 +_llseek,186,140,__PNR__llseek,__PNR__llseek,140,__PNR__llseek,140,__PNR__llseek,__PNR__llseek,140,140,140,140,__PNR__llseek,140,__PNR__llseek +lock,187,53,__PNR_lock,__PNR_lock,__PNR_lock,__PNR_lock,53,__PNR_lock,__PNR_lock,__PNR_lock,__PNR_lock,53,53,__PNR_lock,__PNR_lock,__PNR_lock +lookup_dcookie,188,253,212,212,249,18,247,206,206,223,223,235,235,18,110,110 +lremovexattr,189,236,198,198,236,15,234,190,190,248,248,219,219,15,234,234 +lseek,190,19,8,8,19,62,19,8,8,19,19,19,19,62,19,19 +lsetxattr,191,227,189,189,227,6,225,181,181,239,239,210,210,6,225,225 +lstat,192,107,6,6,107,__PNR_lstat,107,6,6,84,84,107,107,__PNR_lstat,107,107 +lstat64,193,196,__PNR_lstat64,__PNR_lstat64,196,__PNR_lstat64,214,__PNR_lstat64,__PNR_lstat64,198,198,196,__PNR_lstat64,__PNR_lstat64,196,__PNR_lstat64 +madvise,194,219,28,28,220,233,218,27,27,119,119,205,205,233,219,219 +map_shadow_stack,195,453,453,__PNR_map_shadow_stack,453,453,453,453,453,453,453,453,453,453,453,453 +mbind,196,274,237,237,319,235,268,227,231,260,260,259,259,235,268,268 +membarrier,197,375,324,324,389,283,358,318,322,343,343,365,365,283,356,356 +memfd_create,198,356,319,319,385,279,354,314,318,340,340,360,360,279,350,350 +memfd_secret,199,447,447,447,__PNR_memfd_secret,447,__PNR_memfd_secret,__PNR_memfd_secret,__PNR_memfd_secret,__PNR_memfd_secret,__PNR_memfd_secret,__PNR_memfd_secret,__PNR_memfd_secret,447,447,447 +migrate_pages,200,294,256,256,400,238,287,246,250,272,272,258,258,238,287,287 +mincore,201,218,27,27,219,232,217,26,26,72,72,206,206,232,218,218 +mkdir,202,39,83,83,39,__PNR_mkdir,39,81,81,39,39,39,39,__PNR_mkdir,39,39 +mkdirat,203,296,258,258,323,34,289,248,252,276,276,287,287,34,289,289 +mknod,204,14,133,133,14,__PNR_mknod,14,131,131,14,14,14,14,__PNR_mknod,14,14 +mknodat,205,297,259,259,324,33,290,249,253,277,277,288,288,33,290,290 +mlock,206,150,149,149,150,228,154,146,146,150,150,150,150,228,150,150 +mlock2,207,376,325,325,390,284,359,319,323,345,345,378,378,284,374,374 +mlockall,208,152,151,151,152,230,156,148,148,152,152,152,152,230,152,152 +mmap,209,90,9,9,__PNR_mmap,222,90,9,9,90,90,90,90,222,90,90 +mmap2,210,192,__PNR_mmap2,__PNR_mmap2,192,__PNR_mmap2,210,__PNR_mmap2,__PNR_mmap2,89,89,192,__PNR_mmap2,__PNR_mmap2,192,__PNR_mmap2 +modify_ldt,211,123,154,154,__PNR_modify_ldt,__PNR_modify_ldt,123,__PNR_modify_ldt,__PNR_modify_ldt,__PNR_modify_ldt,__PNR_modify_ldt,123,123,__PNR_modify_ldt,__PNR_modify_ldt,__PNR_modify_ldt +mount,212,21,165,165,21,40,21,160,160,21,21,21,21,40,21,21 +mount_setattr,213,442,442,442,442,442,442,442,442,442,442,442,442,442,442,442 +move_mount,214,429,429,429,429,429,429,429,429,429,429,429,429,429,429,429 +move_pages,215,317,279,533,344,239,308,267,271,295,295,301,301,239,310,310 +mprotect,216,125,10,10,125,226,125,10,10,125,125,125,125,226,125,125 +mpx,217,56,__PNR_mpx,__PNR_mpx,__PNR_mpx,__PNR_mpx,56,__PNR_mpx,__PNR_mpx,__PNR_mpx,__PNR_mpx,56,56,__PNR_mpx,__PNR_mpx,__PNR_mpx +mq_getsetattr,218,282,245,245,279,185,276,235,239,234,234,267,267,185,276,276 +mq_notify,219,281,244,527,278,184,275,234,238,233,233,266,266,184,275,275 +mq_open,220,277,240,240,274,180,271,230,234,229,229,262,262,180,271,271 +mq_timedreceive,221,280,243,243,277,183,274,233,237,232,232,265,265,183,274,274 +mq_timedreceive_time64,222,419,__PNR_mq_timedreceive_time64,__PNR_mq_timedreceive_time64,419,__PNR_mq_timedreceive_time64,419,__PNR_mq_timedreceive_time64,419,419,__PNR_mq_timedreceive_time64,419,__PNR_mq_timedreceive_time64,__PNR_mq_timedreceive_time64,419,__PNR_mq_timedreceive_time64 +mq_timedsend,223,279,242,242,276,182,273,232,236,231,231,264,264,182,273,273 +mq_timedsend_time64,224,418,__PNR_mq_timedsend_time64,__PNR_mq_timedsend_time64,418,__PNR_mq_timedsend_time64,418,__PNR_mq_timedsend_time64,418,418,__PNR_mq_timedsend_time64,418,__PNR_mq_timedsend_time64,__PNR_mq_timedsend_time64,418,__PNR_mq_timedsend_time64 +mq_unlink,225,278,241,241,275,181,272,231,235,230,230,263,263,181,272,272 +mremap,226,163,25,25,163,216,167,24,24,163,163,163,163,216,163,163 +msgctl,227,402,71,71,304,187,402,69,69,191,191,402,402,187,402,402 +msgget,228,399,68,68,303,186,399,66,66,190,190,399,399,186,399,399 +msgrcv,229,401,70,70,302,188,401,68,68,189,189,401,401,188,401,401 +msgsnd,230,400,69,69,301,189,400,67,67,188,188,400,400,189,400,400 +msync,231,144,26,26,144,227,144,25,25,144,144,144,144,227,144,144 +multiplexer,232,__PNR_multiplexer,__PNR_multiplexer,__PNR_multiplexer,__PNR_multiplexer,__PNR_multiplexer,__PNR_multiplexer,__PNR_multiplexer,__PNR_multiplexer,__PNR_multiplexer,__PNR_multiplexer,201,201,__PNR_multiplexer,__PNR_multiplexer,__PNR_multiplexer +munlock,233,151,150,150,151,229,155,147,147,151,151,151,151,229,151,151 +munlockall,234,153,152,152,153,231,157,149,149,153,153,153,153,231,153,153 +munmap,235,91,11,11,91,215,91,11,11,91,91,91,91,215,91,91 +name_to_handle_at,236,341,303,303,370,264,339,298,303,325,325,345,345,264,335,335 +nanosleep,237,162,35,35,162,101,166,34,34,162,162,162,162,101,162,162 +newfstatat,238,__PNR_newfstatat,262,262,__PNR_newfstatat,79,__PNR_newfstatat,252,256,__PNR_newfstatat,__PNR_newfstatat,__PNR_newfstatat,291,79,__PNR_newfstatat,293 +_newselect,239,142,__PNR__newselect,__PNR__newselect,142,__PNR__newselect,142,22,22,142,142,142,142,__PNR__newselect,142,__PNR__newselect +nfsservctl,240,169,180,__PNR_nfsservctl,169,42,189,173,173,__PNR_nfsservctl,__PNR_nfsservctl,168,168,42,169,169 +nice,241,34,__PNR_nice,__PNR_nice,34,__PNR_nice,34,__PNR_nice,__PNR_nice,34,34,34,34,__PNR_nice,34,34 +oldfstat,242,28,__PNR_oldfstat,__PNR_oldfstat,__PNR_oldfstat,__PNR_oldfstat,__PNR_oldfstat,__PNR_oldfstat,__PNR_oldfstat,__PNR_oldfstat,__PNR_oldfstat,28,28,__PNR_oldfstat,__PNR_oldfstat,__PNR_oldfstat +oldlstat,243,84,__PNR_oldlstat,__PNR_oldlstat,__PNR_oldlstat,__PNR_oldlstat,__PNR_oldlstat,__PNR_oldlstat,__PNR_oldlstat,__PNR_oldlstat,__PNR_oldlstat,84,84,__PNR_oldlstat,__PNR_oldlstat,__PNR_oldlstat +oldolduname,244,59,__PNR_oldolduname,__PNR_oldolduname,__PNR_oldolduname,__PNR_oldolduname,__PNR_oldolduname,__PNR_oldolduname,__PNR_oldolduname,__PNR_oldolduname,__PNR_oldolduname,59,59,__PNR_oldolduname,__PNR_oldolduname,__PNR_oldolduname +oldstat,245,18,__PNR_oldstat,__PNR_oldstat,__PNR_oldstat,__PNR_oldstat,__PNR_oldstat,__PNR_oldstat,__PNR_oldstat,__PNR_oldstat,__PNR_oldstat,18,18,__PNR_oldstat,__PNR_oldstat,__PNR_oldstat +olduname,246,109,__PNR_olduname,__PNR_olduname,__PNR_olduname,__PNR_olduname,__PNR_olduname,__PNR_olduname,__PNR_olduname,__PNR_olduname,__PNR_olduname,109,109,__PNR_olduname,__PNR_olduname,__PNR_olduname +open,247,5,2,2,5,__PNR_open,5,2,2,5,5,5,5,__PNR_open,5,5 +openat,248,295,257,257,322,56,288,247,251,275,275,286,286,56,288,288 +openat2,249,437,437,437,437,437,437,437,437,437,437,437,437,437,437,437 +open_by_handle_at,250,342,304,304,371,265,340,299,304,326,326,346,346,265,336,336 +open_tree,251,428,428,428,428,428,428,428,428,428,428,428,428,428,428,428 +pause,252,29,34,34,29,__PNR_pause,29,33,33,29,29,29,29,__PNR_pause,29,29 +pciconfig_iobase,253,__PNR_pciconfig_iobase,__PNR_pciconfig_iobase,__PNR_pciconfig_iobase,271,__PNR_pciconfig_iobase,__PNR_pciconfig_iobase,__PNR_pciconfig_iobase,__PNR_pciconfig_iobase,__PNR_pciconfig_iobase,__PNR_pciconfig_iobase,200,200,__PNR_pciconfig_iobase,__PNR_pciconfig_iobase,__PNR_pciconfig_iobase +pciconfig_read,254,__PNR_pciconfig_read,__PNR_pciconfig_read,__PNR_pciconfig_read,272,__PNR_pciconfig_read,__PNR_pciconfig_read,__PNR_pciconfig_read,__PNR_pciconfig_read,__PNR_pciconfig_read,__PNR_pciconfig_read,198,198,__PNR_pciconfig_read,__PNR_pciconfig_read,__PNR_pciconfig_read +pciconfig_write,255,__PNR_pciconfig_write,__PNR_pciconfig_write,__PNR_pciconfig_write,273,__PNR_pciconfig_write,__PNR_pciconfig_write,__PNR_pciconfig_write,__PNR_pciconfig_write,__PNR_pciconfig_write,__PNR_pciconfig_write,199,199,__PNR_pciconfig_write,__PNR_pciconfig_write,__PNR_pciconfig_write +perf_event_open,256,336,298,298,364,241,333,292,296,318,318,319,319,241,331,331 +personality,257,136,135,135,136,92,136,132,132,136,136,136,136,92,136,136 +pidfd_getfd,258,438,438,438,438,438,438,438,438,438,438,438,438,438,438,438 +pidfd_open,259,434,434,434,434,434,434,434,434,434,434,434,434,434,434,434 +pidfd_send_signal,260,424,424,424,424,424,424,424,424,424,424,424,424,424,424,424 +pipe,261,42,22,22,42,__PNR_pipe,42,21,21,42,42,42,42,__PNR_pipe,42,42 +pipe2,262,331,293,293,359,59,328,287,291,313,313,317,317,59,325,325 +pivot_root,263,217,155,155,218,41,216,151,151,67,67,203,203,41,217,217 +pkey_alloc,264,381,330,330,395,289,364,324,328,352,352,384,384,289,385,385 +pkey_free,265,382,331,331,396,290,365,325,329,353,353,385,385,290,386,386 +pkey_mprotect,266,380,329,329,394,288,363,323,327,351,351,386,386,288,384,384 +poll,267,168,7,7,168,__PNR_poll,188,7,7,168,168,167,167,__PNR_poll,168,168 +ppoll,268,309,271,271,336,73,302,261,265,274,274,281,281,73,302,302 +ppoll_time64,269,414,__PNR_ppoll_time64,__PNR_ppoll_time64,414,__PNR_ppoll_time64,414,__PNR_ppoll_time64,414,414,__PNR_ppoll_time64,414,__PNR_ppoll_time64,__PNR_ppoll_time64,414,__PNR_ppoll_time64 +prctl,270,172,157,157,172,167,192,153,153,172,172,171,171,167,172,172 +pread64,271,180,17,17,180,67,200,16,16,108,108,179,179,67,180,180 +preadv,272,333,295,534,361,69,330,289,293,315,315,320,320,69,328,328 +preadv2,273,378,327,546,392,286,361,321,325,347,347,380,380,286,376,376 +prlimit64,274,340,302,302,369,261,338,297,302,321,321,325,325,261,334,334 +process_madvise,275,440,440,440,440,440,440,440,440,440,440,440,440,440,440,440 +process_mrelease,276,448,448,448,448,448,448,448,448,448,448,448,448,448,448,448 +process_vm_readv,277,347,310,539,376,270,345,304,309,330,330,351,351,270,340,340 +process_vm_writev,278,348,311,540,377,271,346,305,310,331,331,352,352,271,341,341 +prof,279,44,__PNR_prof,__PNR_prof,__PNR_prof,__PNR_prof,44,__PNR_prof,__PNR_prof,__PNR_prof,__PNR_prof,44,44,__PNR_prof,__PNR_prof,__PNR_prof +profil,280,98,__PNR_profil,__PNR_profil,__PNR_profil,__PNR_profil,98,__PNR_profil,__PNR_profil,__PNR_profil,__PNR_profil,98,98,__PNR_profil,__PNR_profil,__PNR_profil +pselect6,281,308,270,270,335,72,301,260,264,273,273,280,280,72,301,301 +pselect6_time64,282,413,__PNR_pselect6_time64,__PNR_pselect6_time64,413,__PNR_pselect6_time64,413,__PNR_pselect6_time64,413,413,__PNR_pselect6_time64,413,__PNR_pselect6_time64,__PNR_pselect6_time64,413,__PNR_pselect6_time64 +ptrace,283,26,101,521,26,117,26,99,99,26,26,26,26,117,26,26 +putpmsg,284,189,182,182,__PNR_putpmsg,__PNR_putpmsg,209,175,175,__PNR_putpmsg,__PNR_putpmsg,188,188,__PNR_putpmsg,189,189 +pwrite64,285,181,18,18,181,68,201,17,17,109,109,180,180,68,181,181 +pwritev,286,334,296,535,362,70,331,290,294,316,316,321,321,70,329,329 +pwritev2,287,379,328,547,393,287,362,322,326,348,348,381,381,287,377,377 +query_module,288,167,178,__PNR_query_module,__PNR_query_module,__PNR_query_module,187,171,171,__PNR_query_module,__PNR_query_module,166,166,__PNR_query_module,167,167 +quotactl,289,131,179,179,131,60,131,172,172,131,131,131,131,60,131,131 +quotactl_fd,290,443,443,443,443,443,443,443,443,443,443,443,443,443,443,443 +read,291,3,0,0,3,63,3,0,0,3,3,3,3,63,3,3 +readahead,292,225,187,187,225,213,223,179,179,207,207,191,191,213,222,222 +readdir,293,89,__PNR_readdir,__PNR_readdir,__PNR_readdir,__PNR_readdir,89,__PNR_readdir,__PNR_readdir,__PNR_readdir,__PNR_readdir,89,89,__PNR_readdir,89,89 +readlink,294,85,89,89,85,__PNR_readlink,85,87,87,85,85,85,85,__PNR_readlink,85,85 +readlinkat,295,305,267,267,332,78,298,257,261,285,285,296,296,78,298,298 +readv,296,145,19,515,145,65,145,18,18,145,145,145,145,65,145,145 +reboot,297,88,169,169,88,142,88,164,164,88,88,88,88,142,88,88 +recv,298,__PNR_recv,__PNR_recv,__PNR_recv,291,__PNR_recv,175,__PNR_recv,__PNR_recv,98,98,336,336,__PNR_recv,__PNR_recv,__PNR_recv +recvfrom,299,371,45,517,292,207,176,44,44,123,123,337,337,207,371,371 +recvmmsg,300,337,299,537,365,243,335,294,298,319,319,343,343,243,357,357 +recvmmsg_time64,301,417,__PNR_recvmmsg_time64,__PNR_recvmmsg_time64,417,__PNR_recvmmsg_time64,417,__PNR_recvmmsg_time64,417,417,__PNR_recvmmsg_time64,417,__PNR_recvmmsg_time64,__PNR_recvmmsg_time64,417,__PNR_recvmmsg_time64 +recvmsg,302,372,47,519,297,212,177,46,46,184,184,342,342,212,372,372 +remap_file_pages,303,257,216,216,253,234,251,210,210,227,227,239,239,234,267,267 +removexattr,304,235,197,197,235,14,233,189,189,247,247,218,218,14,233,233 +rename,305,38,82,82,38,__PNR_rename,38,80,80,38,38,38,38,__PNR_rename,38,38 +renameat,306,302,264,264,329,38,295,254,258,282,282,293,293,__PNR_renameat,295,295 +renameat2,307,353,316,316,382,276,351,311,315,337,337,357,357,276,347,347 +request_key,308,287,249,249,310,218,281,240,244,265,265,270,270,218,279,279 +restart_syscall,309,0,219,219,0,128,253,213,214,0,0,0,0,128,7,7 +riscv_flush_icache,310,__PNR_riscv_flush_icache,__PNR_riscv_flush_icache,__PNR_riscv_flush_icache,__PNR_riscv_flush_icache,__PNR_riscv_flush_icache,__PNR_riscv_flush_icache,__PNR_riscv_flush_icache,__PNR_riscv_flush_icache,__PNR_riscv_flush_icache,__PNR_riscv_flush_icache,__PNR_riscv_flush_icache,__PNR_riscv_flush_icache,259,__PNR_riscv_flush_icache,__PNR_riscv_flush_icache +rmdir,311,40,84,84,40,__PNR_rmdir,40,82,82,40,40,40,40,__PNR_rmdir,40,40 +rseq,312,386,334,334,398,293,367,327,331,354,354,387,387,293,383,383 +rtas,313,__PNR_rtas,__PNR_rtas,__PNR_rtas,__PNR_rtas,__PNR_rtas,__PNR_rtas,__PNR_rtas,__PNR_rtas,__PNR_rtas,__PNR_rtas,255,255,__PNR_rtas,__PNR_rtas,__PNR_rtas +rt_sigaction,314,174,13,512,174,134,194,13,13,174,174,173,173,134,174,174 +rt_sigpending,315,176,127,522,176,136,196,125,125,176,176,175,175,136,176,176 +rt_sigprocmask,316,175,14,14,175,135,195,14,14,175,175,174,174,135,175,175 +rt_sigqueueinfo,317,178,129,524,178,138,198,127,127,178,178,177,177,138,178,178 +rt_sigreturn,318,173,15,513,173,139,193,211,211,173,173,172,172,139,173,173 +rt_sigsuspend,319,179,130,130,179,133,199,128,128,179,179,178,178,133,179,179 +rt_sigtimedwait,320,177,128,523,177,137,197,126,126,177,177,176,176,137,177,177 +rt_sigtimedwait_time64,321,421,__PNR_rt_sigtimedwait_time64,__PNR_rt_sigtimedwait_time64,421,__PNR_rt_sigtimedwait_time64,421,__PNR_rt_sigtimedwait_time64,421,421,__PNR_rt_sigtimedwait_time64,421,__PNR_rt_sigtimedwait_time64,__PNR_rt_sigtimedwait_time64,421,__PNR_rt_sigtimedwait_time64 +rt_tgsigqueueinfo,322,335,297,536,363,240,332,291,295,317,317,322,322,240,330,330 +s390_guarded_storage,323,__PNR_s390_guarded_storage,__PNR_s390_guarded_storage,__PNR_s390_guarded_storage,__PNR_s390_guarded_storage,__PNR_s390_guarded_storage,__PNR_s390_guarded_storage,__PNR_s390_guarded_storage,__PNR_s390_guarded_storage,__PNR_s390_guarded_storage,__PNR_s390_guarded_storage,__PNR_s390_guarded_storage,__PNR_s390_guarded_storage,__PNR_s390_guarded_storage,378,378 +s390_pci_mmio_read,324,__PNR_s390_pci_mmio_read,__PNR_s390_pci_mmio_read,__PNR_s390_pci_mmio_read,__PNR_s390_pci_mmio_read,__PNR_s390_pci_mmio_read,__PNR_s390_pci_mmio_read,__PNR_s390_pci_mmio_read,__PNR_s390_pci_mmio_read,__PNR_s390_pci_mmio_read,__PNR_s390_pci_mmio_read,__PNR_s390_pci_mmio_read,__PNR_s390_pci_mmio_read,__PNR_s390_pci_mmio_read,353,353 +s390_pci_mmio_write,325,__PNR_s390_pci_mmio_write,__PNR_s390_pci_mmio_write,__PNR_s390_pci_mmio_write,__PNR_s390_pci_mmio_write,__PNR_s390_pci_mmio_write,__PNR_s390_pci_mmio_write,__PNR_s390_pci_mmio_write,__PNR_s390_pci_mmio_write,__PNR_s390_pci_mmio_write,__PNR_s390_pci_mmio_write,__PNR_s390_pci_mmio_write,__PNR_s390_pci_mmio_write,__PNR_s390_pci_mmio_write,352,352 +s390_runtime_instr,326,__PNR_s390_runtime_instr,__PNR_s390_runtime_instr,__PNR_s390_runtime_instr,__PNR_s390_runtime_instr,__PNR_s390_runtime_instr,__PNR_s390_runtime_instr,__PNR_s390_runtime_instr,__PNR_s390_runtime_instr,__PNR_s390_runtime_instr,__PNR_s390_runtime_instr,__PNR_s390_runtime_instr,__PNR_s390_runtime_instr,__PNR_s390_runtime_instr,342,342 +s390_sthyi,327,__PNR_s390_sthyi,__PNR_s390_sthyi,__PNR_s390_sthyi,__PNR_s390_sthyi,__PNR_s390_sthyi,__PNR_s390_sthyi,__PNR_s390_sthyi,__PNR_s390_sthyi,__PNR_s390_sthyi,__PNR_s390_sthyi,__PNR_s390_sthyi,__PNR_s390_sthyi,__PNR_s390_sthyi,380,380 +sched_getaffinity,328,242,204,204,242,123,240,196,196,212,212,223,223,123,240,240 +sched_getattr,329,352,315,315,381,275,350,310,314,335,335,356,356,275,346,346 +sched_getparam,330,155,143,143,155,121,159,140,140,155,155,155,155,121,155,155 +sched_get_priority_max,331,159,146,146,159,125,163,143,143,159,159,159,159,125,159,159 +sched_get_priority_min,332,160,147,147,160,126,164,144,144,160,160,160,160,126,160,160 +sched_getscheduler,333,157,145,145,157,120,161,142,142,157,157,157,157,120,157,157 +sched_rr_get_interval,334,161,148,148,161,127,165,145,145,161,161,161,161,127,161,161 +sched_rr_get_interval_time64,335,423,__PNR_sched_rr_get_interval_time64,__PNR_sched_rr_get_interval_time64,423,__PNR_sched_rr_get_interval_time64,423,__PNR_sched_rr_get_interval_time64,423,423,__PNR_sched_rr_get_interval_time64,423,__PNR_sched_rr_get_interval_time64,__PNR_sched_rr_get_interval_time64,423,__PNR_sched_rr_get_interval_time64 +sched_setaffinity,336,241,203,203,241,122,239,195,195,211,211,222,222,122,239,239 +sched_setattr,337,351,314,314,380,274,349,309,313,334,334,355,355,274,345,345 +sched_setparam,338,154,142,142,154,118,158,139,139,154,154,154,154,118,154,154 +sched_setscheduler,339,156,144,144,156,119,160,141,141,156,156,156,156,119,156,156 +sched_yield,340,158,24,24,158,124,162,23,23,158,158,158,158,124,158,158 +seccomp,341,354,317,317,383,277,352,312,316,338,338,358,358,277,348,348 +security,342,__PNR_security,185,185,__PNR_security,__PNR_security,__PNR_security,__PNR_security,__PNR_security,__PNR_security,__PNR_security,__PNR_security,__PNR_security,__PNR_security,__PNR_security,__PNR_security +select,343,82,23,23,__PNR_select,__PNR_select,__PNR_select,__PNR_select,__PNR_select,__PNR_select,__PNR_select,82,82,__PNR_select,__PNR_select,142 +semctl,344,394,66,66,300,191,394,64,64,187,187,394,394,191,394,394 +semget,345,393,64,64,299,190,393,62,62,186,186,393,393,190,393,393 +semop,346,__PNR_semop,65,65,298,193,__PNR_semop,63,63,185,185,__PNR_semop,__PNR_semop,193,__PNR_semop,__PNR_semop +semtimedop,347,__PNR_semtimedop,220,220,312,192,__PNR_semtimedop,214,215,228,228,__PNR_semtimedop,392,192,__PNR_semtimedop,392 +semtimedop_time64,348,420,__PNR_semtimedop_time64,__PNR_semtimedop_time64,420,__PNR_semtimedop_time64,420,__PNR_semtimedop_time64,420,420,__PNR_semtimedop_time64,420,__PNR_semtimedop_time64,__PNR_semtimedop_time64,420,__PNR_semtimedop_time64 +send,349,__PNR_send,__PNR_send,__PNR_send,289,__PNR_send,178,__PNR_send,__PNR_send,58,58,334,334,__PNR_send,__PNR_send,__PNR_send +sendfile,350,187,40,40,187,71,207,39,39,122,122,186,186,71,187,187 +sendfile64,351,239,__PNR_sendfile64,__PNR_sendfile64,239,__PNR_sendfile64,237,__PNR_sendfile64,219,209,209,226,__PNR_sendfile64,__PNR_sendfile64,223,__PNR_sendfile64 +sendmmsg,352,345,307,538,374,269,343,302,307,329,329,349,349,269,358,358 +sendmsg,353,370,46,518,296,211,179,45,45,183,183,341,341,211,370,370 +sendto,354,369,44,44,290,206,180,43,43,82,82,335,335,206,369,369 +setdomainname,355,121,171,171,121,162,121,166,166,121,121,121,121,162,121,121 +setfsgid,356,139,123,123,139,152,139,121,121,139,139,139,139,152,139,216 +setfsgid32,357,216,__PNR_setfsgid32,__PNR_setfsgid32,216,__PNR_setfsgid32,__PNR_setfsgid32,__PNR_setfsgid32,__PNR_setfsgid32,__PNR_setfsgid32,__PNR_setfsgid32,__PNR_setfsgid32,__PNR_setfsgid32,__PNR_setfsgid32,216,__PNR_setfsgid32 +setfsuid,358,138,122,122,138,151,138,120,120,138,138,138,138,151,138,215 +setfsuid32,359,215,__PNR_setfsuid32,__PNR_setfsuid32,215,__PNR_setfsuid32,__PNR_setfsuid32,__PNR_setfsuid32,__PNR_setfsuid32,__PNR_setfsuid32,__PNR_setfsuid32,__PNR_setfsuid32,__PNR_setfsuid32,__PNR_setfsuid32,215,__PNR_setfsuid32 +setgid,360,46,106,106,46,144,46,104,104,46,46,46,46,144,46,214 +setgid32,361,214,__PNR_setgid32,__PNR_setgid32,214,__PNR_setgid32,__PNR_setgid32,__PNR_setgid32,__PNR_setgid32,__PNR_setgid32,__PNR_setgid32,__PNR_setgid32,__PNR_setgid32,__PNR_setgid32,214,__PNR_setgid32 +setgroups,362,81,116,116,81,159,81,114,114,81,81,81,81,159,81,206 +setgroups32,363,206,__PNR_setgroups32,__PNR_setgroups32,206,__PNR_setgroups32,__PNR_setgroups32,__PNR_setgroups32,__PNR_setgroups32,__PNR_setgroups32,__PNR_setgroups32,__PNR_setgroups32,__PNR_setgroups32,__PNR_setgroups32,206,__PNR_setgroups32 +sethostname,364,74,170,170,74,161,74,165,165,74,74,74,74,161,74,74 +setitimer,365,104,38,38,104,103,104,36,36,104,104,104,104,103,104,104 +set_mempolicy,366,276,238,238,321,237,270,229,233,262,262,261,261,237,270,270 +set_mempolicy_home_node,367,450,450,450,450,450,450,450,450,450,450,450,450,450,450,450 +setns,368,346,308,308,375,268,344,303,308,328,328,350,350,268,339,339 +setpgid,369,57,109,109,57,154,57,107,107,57,57,57,57,154,57,57 +setpriority,370,97,141,141,97,140,97,138,138,97,97,97,97,140,97,97 +setregid,371,71,114,114,71,143,71,112,112,71,71,71,71,143,71,204 +setregid32,372,204,__PNR_setregid32,__PNR_setregid32,204,__PNR_setregid32,__PNR_setregid32,__PNR_setregid32,__PNR_setregid32,__PNR_setregid32,__PNR_setregid32,__PNR_setregid32,__PNR_setregid32,__PNR_setregid32,204,__PNR_setregid32 +setresgid,373,170,119,119,170,149,190,117,117,170,170,169,169,149,170,210 +setresgid32,374,210,__PNR_setresgid32,__PNR_setresgid32,210,__PNR_setresgid32,__PNR_setresgid32,__PNR_setresgid32,__PNR_setresgid32,__PNR_setresgid32,__PNR_setresgid32,__PNR_setresgid32,__PNR_setresgid32,__PNR_setresgid32,210,__PNR_setresgid32 +setresuid,375,164,117,117,164,147,185,115,115,164,164,164,164,147,164,208 +setresuid32,376,208,__PNR_setresuid32,__PNR_setresuid32,208,__PNR_setresuid32,__PNR_setresuid32,__PNR_setresuid32,__PNR_setresuid32,__PNR_setresuid32,__PNR_setresuid32,__PNR_setresuid32,__PNR_setresuid32,__PNR_setresuid32,208,__PNR_setresuid32 +setreuid,377,70,113,113,70,145,70,111,111,70,70,70,70,145,70,203 +setreuid32,378,203,__PNR_setreuid32,__PNR_setreuid32,203,__PNR_setreuid32,__PNR_setreuid32,__PNR_setreuid32,__PNR_setreuid32,__PNR_setreuid32,__PNR_setreuid32,__PNR_setreuid32,__PNR_setreuid32,__PNR_setreuid32,203,__PNR_setreuid32 +setrlimit,379,75,160,160,75,164,75,155,155,75,75,75,75,164,75,75 +set_robust_list,380,311,273,530,338,99,309,268,272,289,289,300,300,99,304,304 +setsid,381,66,112,112,66,157,66,110,110,66,66,66,66,157,66,66 +setsockopt,382,366,54,541,294,208,181,53,53,181,181,339,339,208,366,366 +set_thread_area,383,243,205,__PNR_set_thread_area,__PNR_set_thread_area,__PNR_set_thread_area,283,242,246,__PNR_set_thread_area,__PNR_set_thread_area,__PNR_set_thread_area,__PNR_set_thread_area,__PNR_set_thread_area,__PNR_set_thread_area,__PNR_set_thread_area +set_tid_address,384,258,218,218,256,96,252,212,213,237,237,232,232,96,252,252 +settimeofday,385,79,164,164,79,170,79,159,159,79,79,79,79,170,79,79 +set_tls,386,__PNR_set_tls,__PNR_set_tls,__PNR_set_tls,983045,__PNR_set_tls,__PNR_set_tls,__PNR_set_tls,__PNR_set_tls,__PNR_set_tls,__PNR_set_tls,__PNR_set_tls,__PNR_set_tls,__PNR_set_tls,__PNR_set_tls,__PNR_set_tls +setuid,387,23,105,105,23,146,23,103,103,23,23,23,23,146,23,213 +setuid32,388,213,__PNR_setuid32,__PNR_setuid32,213,__PNR_setuid32,__PNR_setuid32,__PNR_setuid32,__PNR_setuid32,__PNR_setuid32,__PNR_setuid32,__PNR_setuid32,__PNR_setuid32,__PNR_setuid32,213,__PNR_setuid32 +setxattr,389,226,188,188,226,5,224,180,180,238,238,209,209,5,224,224 +sgetmask,390,68,__PNR_sgetmask,__PNR_sgetmask,__PNR_sgetmask,__PNR_sgetmask,68,__PNR_sgetmask,__PNR_sgetmask,68,68,68,68,__PNR_sgetmask,__PNR_sgetmask,__PNR_sgetmask +shmat,391,397,30,30,305,196,397,29,29,192,192,397,397,196,397,397 +shmctl,392,396,31,31,308,195,396,30,30,195,195,396,396,195,396,396 +shmdt,393,398,67,67,306,197,398,65,65,193,193,398,398,197,398,398 +shmget,394,395,29,29,307,194,395,28,28,194,194,395,395,194,395,395 +shutdown,395,373,48,48,293,210,182,47,47,117,117,338,338,210,373,373 +sigaction,396,67,__PNR_sigaction,__PNR_sigaction,67,__PNR_sigaction,67,__PNR_sigaction,__PNR_sigaction,__PNR_sigaction,__PNR_sigaction,67,67,__PNR_sigaction,67,67 +sigaltstack,397,186,131,525,186,132,206,129,129,166,166,185,185,132,186,186 +signal,398,48,__PNR_signal,__PNR_signal,__PNR_signal,__PNR_signal,48,__PNR_signal,__PNR_signal,48,48,48,48,__PNR_signal,48,48 +signalfd,399,321,282,282,349,__PNR_signalfd,317,276,280,302,302,305,305,__PNR_signalfd,316,316 +signalfd4,400,327,289,289,355,74,324,283,287,309,309,313,313,74,322,322 +sigpending,401,73,__PNR_sigpending,__PNR_sigpending,73,__PNR_sigpending,73,__PNR_sigpending,__PNR_sigpending,73,73,73,73,__PNR_sigpending,73,73 +sigprocmask,402,126,__PNR_sigprocmask,__PNR_sigprocmask,126,__PNR_sigprocmask,126,__PNR_sigprocmask,__PNR_sigprocmask,126,126,126,126,__PNR_sigprocmask,126,126 +sigreturn,403,119,__PNR_sigreturn,__PNR_sigreturn,119,__PNR_sigreturn,119,__PNR_sigreturn,__PNR_sigreturn,__PNR_sigreturn,__PNR_sigreturn,119,119,__PNR_sigreturn,119,119 +sigsuspend,404,72,__PNR_sigsuspend,__PNR_sigsuspend,72,__PNR_sigsuspend,72,__PNR_sigsuspend,__PNR_sigsuspend,__PNR_sigsuspend,__PNR_sigsuspend,72,72,__PNR_sigsuspend,72,72 +socket,405,359,41,41,281,198,183,40,40,17,17,326,326,198,359,359 +socketcall,406,102,__PNR_socketcall,__PNR_socketcall,__PNR_socketcall,__PNR_socketcall,102,__PNR_socketcall,__PNR_socketcall,__PNR_socketcall,__PNR_socketcall,102,102,__PNR_socketcall,102,102 +socketpair,407,360,53,53,288,199,184,52,52,56,56,333,333,199,360,360 +splice,408,313,275,275,340,76,304,263,267,291,291,283,283,76,306,306 +spu_create,409,__PNR_spu_create,__PNR_spu_create,__PNR_spu_create,__PNR_spu_create,__PNR_spu_create,__PNR_spu_create,__PNR_spu_create,__PNR_spu_create,__PNR_spu_create,__PNR_spu_create,279,279,__PNR_spu_create,__PNR_spu_create,__PNR_spu_create +spu_run,410,__PNR_spu_run,__PNR_spu_run,__PNR_spu_run,__PNR_spu_run,__PNR_spu_run,__PNR_spu_run,__PNR_spu_run,__PNR_spu_run,__PNR_spu_run,__PNR_spu_run,278,278,__PNR_spu_run,__PNR_spu_run,__PNR_spu_run +ssetmask,411,69,__PNR_ssetmask,__PNR_ssetmask,__PNR_ssetmask,__PNR_ssetmask,69,__PNR_ssetmask,__PNR_ssetmask,69,69,69,69,__PNR_ssetmask,__PNR_ssetmask,__PNR_ssetmask +stat,412,106,4,4,106,__PNR_stat,106,4,4,18,18,106,106,__PNR_stat,106,106 +stat64,413,195,__PNR_stat64,__PNR_stat64,195,__PNR_stat64,213,__PNR_stat64,__PNR_stat64,101,101,195,__PNR_stat64,__PNR_stat64,195,__PNR_stat64 +statfs,414,99,137,137,99,43,99,134,134,99,99,99,99,43,99,99 +statfs64,415,268,__PNR_statfs64,__PNR_statfs64,266,__PNR_statfs64,255,__PNR_statfs64,217,298,298,252,252,__PNR_statfs64,265,265 +statx,416,383,332,332,397,291,366,326,330,349,349,383,383,291,379,379 +stime,417,25,__PNR_stime,__PNR_stime,__PNR_stime,__PNR_stime,25,__PNR_stime,__PNR_stime,25,25,25,25,__PNR_stime,25,__PNR_stime +stty,418,31,__PNR_stty,__PNR_stty,__PNR_stty,__PNR_stty,31,__PNR_stty,__PNR_stty,__PNR_stty,__PNR_stty,31,31,__PNR_stty,__PNR_stty,__PNR_stty +subpage_prot,419,__PNR_subpage_prot,__PNR_subpage_prot,__PNR_subpage_prot,__PNR_subpage_prot,__PNR_subpage_prot,__PNR_subpage_prot,__PNR_subpage_prot,__PNR_subpage_prot,__PNR_subpage_prot,__PNR_subpage_prot,310,310,__PNR_subpage_prot,__PNR_subpage_prot,__PNR_subpage_prot +swapcontext,420,__PNR_swapcontext,__PNR_swapcontext,__PNR_swapcontext,__PNR_swapcontext,__PNR_swapcontext,__PNR_swapcontext,__PNR_swapcontext,__PNR_swapcontext,__PNR_swapcontext,__PNR_swapcontext,249,249,__PNR_swapcontext,__PNR_swapcontext,__PNR_swapcontext +swapoff,421,115,168,168,115,225,115,163,163,115,115,115,115,225,115,115 +swapon,422,87,167,167,87,224,87,162,162,87,87,87,87,224,87,87 +switch_endian,423,__PNR_switch_endian,__PNR_switch_endian,__PNR_switch_endian,__PNR_switch_endian,__PNR_switch_endian,__PNR_switch_endian,__PNR_switch_endian,__PNR_switch_endian,__PNR_switch_endian,__PNR_switch_endian,363,363,__PNR_switch_endian,__PNR_switch_endian,__PNR_switch_endian +symlink,424,83,88,88,83,__PNR_symlink,83,86,86,83,83,83,83,__PNR_symlink,83,83 +symlinkat,425,304,266,266,331,36,297,256,260,284,284,295,295,36,297,297 +sync,426,36,162,162,36,81,36,157,157,36,36,36,36,81,36,36 +sync_file_range,427,314,277,277,__PNR_sync_file_range,84,305,264,268,292,292,__PNR_sync_file_range,__PNR_sync_file_range,84,307,307 +sync_file_range2,428,__PNR_sync_file_range2,__PNR_sync_file_range2,__PNR_sync_file_range2,__PNR_sync_file_range2,__PNR_sync_file_range2,__PNR_sync_file_range2,__PNR_sync_file_range2,__PNR_sync_file_range2,__PNR_sync_file_range2,__PNR_sync_file_range2,308,308,__PNR_sync_file_range2,__PNR_sync_file_range2,__PNR_sync_file_range2 +syncfs,429,344,306,306,373,267,342,301,306,327,327,348,348,267,338,338 +syscall,430,__PNR_syscall,__PNR_syscall,__PNR_syscall,__PNR_syscall,__PNR_syscall,0,__PNR_syscall,__PNR_syscall,__PNR_syscall,__PNR_syscall,__PNR_syscall,__PNR_syscall,__PNR_syscall,__PNR_syscall,__PNR_syscall +_sysctl,431,149,156,__PNR__sysctl,149,__PNR__sysctl,153,152,152,149,149,149,149,__PNR__sysctl,149,149 +sys_debug_setcontext,432,__PNR_sys_debug_setcontext,__PNR_sys_debug_setcontext,__PNR_sys_debug_setcontext,__PNR_sys_debug_setcontext,__PNR_sys_debug_setcontext,__PNR_sys_debug_setcontext,__PNR_sys_debug_setcontext,__PNR_sys_debug_setcontext,__PNR_sys_debug_setcontext,__PNR_sys_debug_setcontext,256,256,__PNR_sys_debug_setcontext,__PNR_sys_debug_setcontext,__PNR_sys_debug_setcontext +sysfs,433,135,139,139,135,__PNR_sysfs,135,136,136,135,135,135,135,__PNR_sysfs,135,135 +sysinfo,434,116,99,99,116,179,116,97,97,116,116,116,116,179,116,116 +syslog,435,103,103,103,103,116,103,101,101,103,103,103,103,116,103,103 +sysmips,436,__PNR_sysmips,__PNR_sysmips,__PNR_sysmips,__PNR_sysmips,__PNR_sysmips,149,199,199,__PNR_sysmips,__PNR_sysmips,__PNR_sysmips,__PNR_sysmips,__PNR_sysmips,__PNR_sysmips,__PNR_sysmips +tee,437,315,276,276,342,77,306,265,269,293,293,284,284,77,308,308 +tgkill,438,270,234,234,268,131,266,225,229,259,259,250,250,131,241,241 +time,439,13,201,201,__PNR_time,__PNR_time,13,__PNR_time,__PNR_time,13,13,13,13,__PNR_time,13,__PNR_time +timer_create,440,259,222,526,257,107,257,216,220,250,250,240,240,107,254,254 +timer_delete,441,263,226,226,261,111,261,220,224,254,254,244,244,111,258,258 +timerfd,442,__PNR_timerfd,__PNR_timerfd,__PNR_timerfd,__PNR_timerfd,__PNR_timerfd,318,277,281,__PNR_timerfd,__PNR_timerfd,__PNR_timerfd,__PNR_timerfd,__PNR_timerfd,317,317 +timerfd_create,443,322,283,283,350,85,321,280,284,306,306,306,306,85,319,319 +timerfd_gettime,444,326,287,287,354,87,322,281,285,308,308,312,312,87,321,321 +timerfd_gettime64,445,410,__PNR_timerfd_gettime64,__PNR_timerfd_gettime64,410,__PNR_timerfd_gettime64,410,__PNR_timerfd_gettime64,410,410,__PNR_timerfd_gettime64,410,__PNR_timerfd_gettime64,__PNR_timerfd_gettime64,410,__PNR_timerfd_gettime64 +timerfd_settime,446,325,286,286,353,86,323,282,286,307,307,311,311,86,320,320 +timerfd_settime64,447,411,__PNR_timerfd_settime64,__PNR_timerfd_settime64,411,__PNR_timerfd_settime64,411,__PNR_timerfd_settime64,411,411,__PNR_timerfd_settime64,411,__PNR_timerfd_settime64,__PNR_timerfd_settime64,411,__PNR_timerfd_settime64 +timer_getoverrun,448,262,225,225,260,109,260,219,223,253,253,243,243,109,257,257 +timer_gettime,449,261,224,224,259,108,259,218,222,252,252,242,242,108,256,256 +timer_gettime64,450,408,__PNR_timer_gettime64,__PNR_timer_gettime64,408,__PNR_timer_gettime64,408,__PNR_timer_gettime64,408,408,__PNR_timer_gettime64,408,__PNR_timer_gettime64,__PNR_timer_gettime64,408,__PNR_timer_gettime64 +timer_settime,451,260,223,223,258,110,258,217,221,251,251,241,241,110,255,255 +timer_settime64,452,409,__PNR_timer_settime64,__PNR_timer_settime64,409,__PNR_timer_settime64,409,__PNR_timer_settime64,409,409,__PNR_timer_settime64,409,__PNR_timer_settime64,__PNR_timer_settime64,409,__PNR_timer_settime64 +times,453,43,100,100,43,153,43,98,98,43,43,43,43,153,43,43 +tkill,454,238,200,200,238,130,236,192,192,208,208,208,208,130,237,237 +truncate,455,92,76,76,92,45,92,74,74,92,92,92,92,45,92,92 +truncate64,456,193,__PNR_truncate64,__PNR_truncate64,193,__PNR_truncate64,211,__PNR_truncate64,__PNR_truncate64,199,199,193,__PNR_truncate64,__PNR_truncate64,193,__PNR_truncate64 +tuxcall,457,__PNR_tuxcall,184,184,__PNR_tuxcall,__PNR_tuxcall,__PNR_tuxcall,__PNR_tuxcall,__PNR_tuxcall,__PNR_tuxcall,__PNR_tuxcall,225,225,__PNR_tuxcall,__PNR_tuxcall,__PNR_tuxcall +ugetrlimit,458,191,__PNR_ugetrlimit,__PNR_ugetrlimit,191,__PNR_ugetrlimit,__PNR_ugetrlimit,__PNR_ugetrlimit,__PNR_ugetrlimit,__PNR_ugetrlimit,__PNR_ugetrlimit,190,190,__PNR_ugetrlimit,191,__PNR_ugetrlimit +ulimit,459,58,__PNR_ulimit,__PNR_ulimit,__PNR_ulimit,__PNR_ulimit,58,__PNR_ulimit,__PNR_ulimit,__PNR_ulimit,__PNR_ulimit,58,58,__PNR_ulimit,__PNR_ulimit,__PNR_ulimit +umask,460,60,95,95,60,166,60,93,93,60,60,60,60,166,60,60 +umount,461,22,__PNR_umount,__PNR_umount,__PNR_umount,__PNR_umount,22,__PNR_umount,__PNR_umount,__PNR_umount,__PNR_umount,22,22,__PNR_umount,22,22 +umount2,462,52,166,166,52,39,52,161,161,52,52,52,52,39,52,52 +uname,463,122,63,63,122,160,122,61,61,59,59,122,122,160,122,122 +unlink,464,10,87,87,10,__PNR_unlink,10,85,85,10,10,10,10,__PNR_unlink,10,10 +unlinkat,465,301,263,263,328,35,294,253,257,281,281,292,292,35,294,294 +unshare,466,310,272,272,337,97,303,262,266,288,288,282,282,97,303,303 +uselib,467,86,134,__PNR_uselib,86,__PNR_uselib,86,__PNR_uselib,__PNR_uselib,86,86,86,86,__PNR_uselib,86,86 +userfaultfd,468,374,323,323,388,282,357,317,321,344,344,364,364,282,355,355 +usr26,469,__PNR_usr26,__PNR_usr26,__PNR_usr26,983043,__PNR_usr26,__PNR_usr26,__PNR_usr26,__PNR_usr26,__PNR_usr26,__PNR_usr26,__PNR_usr26,__PNR_usr26,__PNR_usr26,__PNR_usr26,__PNR_usr26 +usr32,470,__PNR_usr32,__PNR_usr32,__PNR_usr32,983044,__PNR_usr32,__PNR_usr32,__PNR_usr32,__PNR_usr32,__PNR_usr32,__PNR_usr32,__PNR_usr32,__PNR_usr32,__PNR_usr32,__PNR_usr32,__PNR_usr32 +ustat,471,62,136,136,62,__PNR_ustat,62,133,133,62,62,62,62,__PNR_ustat,62,62 +utime,472,30,132,132,__PNR_utime,__PNR_utime,30,130,130,30,30,30,30,__PNR_utime,30,30 +utimensat,473,320,280,280,348,88,316,275,279,301,301,304,304,88,315,315 +utimensat_time64,474,412,__PNR_utimensat_time64,__PNR_utimensat_time64,412,__PNR_utimensat_time64,412,__PNR_utimensat_time64,412,412,__PNR_utimensat_time64,412,__PNR_utimensat_time64,__PNR_utimensat_time64,412,__PNR_utimensat_time64 +utimes,475,271,235,235,269,__PNR_utimes,267,226,230,336,336,251,251,__PNR_utimes,313,313 +vfork,476,190,58,58,190,__PNR_vfork,__PNR_vfork,__PNR_vfork,__PNR_vfork,113,113,189,189,__PNR_vfork,190,190 +vhangup,477,111,153,153,111,58,111,150,150,111,111,111,111,58,111,111 +vm86,478,166,__PNR_vm86,__PNR_vm86,__PNR_vm86,__PNR_vm86,113,__PNR_vm86,__PNR_vm86,__PNR_vm86,__PNR_vm86,113,113,__PNR_vm86,__PNR_vm86,__PNR_vm86 +vm86old,479,113,__PNR_vm86old,__PNR_vm86old,__PNR_vm86old,__PNR_vm86old,__PNR_vm86old,__PNR_vm86old,__PNR_vm86old,__PNR_vm86old,__PNR_vm86old,__PNR_vm86old,__PNR_vm86old,__PNR_vm86old,__PNR_vm86old,__PNR_vm86old +vmsplice,480,316,278,532,343,75,307,266,270,294,294,285,285,75,309,309 +vserver,481,273,236,__PNR_vserver,313,__PNR_vserver,277,236,240,__PNR_vserver,__PNR_vserver,__PNR_vserver,__PNR_vserver,__PNR_vserver,__PNR_vserver,__PNR_vserver +wait4,482,114,61,61,114,260,114,59,59,114,114,114,114,260,114,114 +waitid,483,284,247,529,280,95,278,237,241,235,235,272,272,95,281,281 +waitpid,484,7,__PNR_waitpid,__PNR_waitpid,__PNR_waitpid,__PNR_waitpid,7,__PNR_waitpid,__PNR_waitpid,7,7,7,7,__PNR_waitpid,__PNR_waitpid,__PNR_waitpid +write,485,4,1,1,4,64,4,1,1,4,4,4,4,64,4,4 +writev,486,146,20,516,146,66,146,19,19,146,146,146,146,66,146,146 +%% + +static int syscall_get_offset_value(const struct arch_syscall_table *s, + int offset) +{ + return *(int *)((char *)s + offset); +} + +int syscall_resolve_name(const char *name, int offset) +{ + const struct arch_syscall_table *s; + + s = in_word_set(name, strlen(name)); + if (s == NULL) + return __NR_SCMP_ERROR; + + return syscall_get_offset_value(s, offset); +} + +const char *syscall_resolve_num(int num, int offset) +{ + unsigned int iter; + + for (iter = 0; iter < sizeof(wordlist)/sizeof(wordlist[0]); iter++) { + if (syscall_get_offset_value(&wordlist[iter], offset) == num) + return (stringpool + wordlist[iter].name); + } + + return NULL; +} + +const struct arch_syscall_def *syscall_iterate(unsigned int spot, int offset) +{ + unsigned int iter; + /* this is thread-unsafe, only use for testing */ + static struct arch_syscall_def arch_def; + + arch_def.name = NULL; + arch_def.num = __NR_SCMP_ERROR; + + for (iter = 0; iter < sizeof(wordlist)/sizeof(wordlist[0]); iter++) { + if (wordlist[iter].index == spot) { + arch_def.name = stringpool + wordlist[iter].name; + arch_def.num = syscall_get_offset_value(&wordlist[iter], + offset); + return &arch_def; + } + } + + return &arch_def; +} diff --git a/src/syscalls.perf.c b/src/syscalls.perf.c new file mode 100644 index 0000000..8681859 --- /dev/null +++ b/src/syscalls.perf.c @@ -0,0 +1,3640 @@ +/* ANSI-C code produced by gperf version 3.1 */ +/* Command-line: gperf -m 100 --null-strings --pic -tCEG -T -S1 syscalls.perf */ +/* Computed positions: -k'1-2,4-9,$' */ + +#if !((' ' == 32) && ('!' == 33) && ('"' == 34) && ('#' == 35) \ + && ('%' == 37) && ('&' == 38) && ('\'' == 39) && ('(' == 40) \ + && (')' == 41) && ('*' == 42) && ('+' == 43) && (',' == 44) \ + && ('-' == 45) && ('.' == 46) && ('/' == 47) && ('0' == 48) \ + && ('1' == 49) && ('2' == 50) && ('3' == 51) && ('4' == 52) \ + && ('5' == 53) && ('6' == 54) && ('7' == 55) && ('8' == 56) \ + && ('9' == 57) && (':' == 58) && (';' == 59) && ('<' == 60) \ + && ('=' == 61) && ('>' == 62) && ('?' == 63) && ('A' == 65) \ + && ('B' == 66) && ('C' == 67) && ('D' == 68) && ('E' == 69) \ + && ('F' == 70) && ('G' == 71) && ('H' == 72) && ('I' == 73) \ + && ('J' == 74) && ('K' == 75) && ('L' == 76) && ('M' == 77) \ + && ('N' == 78) && ('O' == 79) && ('P' == 80) && ('Q' == 81) \ + && ('R' == 82) && ('S' == 83) && ('T' == 84) && ('U' == 85) \ + && ('V' == 86) && ('W' == 87) && ('X' == 88) && ('Y' == 89) \ + && ('Z' == 90) && ('[' == 91) && ('\\' == 92) && (']' == 93) \ + && ('^' == 94) && ('_' == 95) && ('a' == 97) && ('b' == 98) \ + && ('c' == 99) && ('d' == 100) && ('e' == 101) && ('f' == 102) \ + && ('g' == 103) && ('h' == 104) && ('i' == 105) && ('j' == 106) \ + && ('k' == 107) && ('l' == 108) && ('m' == 109) && ('n' == 110) \ + && ('o' == 111) && ('p' == 112) && ('q' == 113) && ('r' == 114) \ + && ('s' == 115) && ('t' == 116) && ('u' == 117) && ('v' == 118) \ + && ('w' == 119) && ('x' == 120) && ('y' == 121) && ('z' == 122) \ + && ('{' == 123) && ('|' == 124) && ('}' == 125) && ('~' == 126)) +/* The character set is not based on ISO-646. */ +#error "gperf generated tables don't work with this execution character set. Please report a bug to <bug-gperf@gnu.org>." +#endif + +#line 1 "syscalls.perf" + +/** + * Copyright (c) 2012 Red Hat <pmoore@redhat.com> + * Copyright (c) 2020 Red Hat <gscrivan@redhat.com> + * Authors: Paul Moore <paul@paul-moore.com> + * Giuseppe Scrivano <gscrivan@redhat.com> + */ + +/* + * 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 <seccomp.h> +#include <string.h> +#include "syscalls.h" + +enum + { + TOTAL_KEYWORDS = 487, + MIN_WORD_LENGTH = 3, + MAX_WORD_LENGTH = 28, + MIN_HASH_VALUE = 24, + MAX_HASH_VALUE = 1874 + }; + +/* maximum key range = 1851, duplicates = 0 */ + +#ifdef __GNUC__ +__inline +#else +#ifdef __cplusplus +inline +#endif +#endif +static unsigned int +hash (register const char *str, register size_t len) +{ + static const unsigned short asso_values[] = + { + 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, + 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, + 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, + 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, + 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 5, + 356, 122, 463, 1875, 5, 9, 1875, 1875, 1875, 1875, + 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, + 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, + 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, + 1875, 1875, 1875, 1875, 1875, 7, 334, 124, 574, 12, + 10, 7, 7, 6, 194, 11, 355, 312, 91, 36, + 171, 36, 68, 159, 14, 5, 7, 317, 244, 473, + 218, 330, 8, 1875, 1875, 1875, 1875, 1875, 1875, 1875, + 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, + 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, + 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, + 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, + 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, + 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, + 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, + 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, + 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, + 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, + 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, + 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, + 1875, 1875, 1875, 1875, 1875, 1875, 1875 + }; + register unsigned int hval = len; + + switch (hval) + { + default: + hval += asso_values[(unsigned char)str[8]]; + /*FALLTHROUGH*/ + case 8: + hval += asso_values[(unsigned char)str[7]]; + /*FALLTHROUGH*/ + case 7: + hval += asso_values[(unsigned char)str[6]]; + /*FALLTHROUGH*/ + case 6: + hval += asso_values[(unsigned char)str[5]]; + /*FALLTHROUGH*/ + case 5: + hval += asso_values[(unsigned char)str[4]]; + /*FALLTHROUGH*/ + case 4: + hval += asso_values[(unsigned char)str[3]+1]; + /*FALLTHROUGH*/ + case 3: + case 2: + hval += asso_values[(unsigned char)str[1]]; + /*FALLTHROUGH*/ + case 1: + hval += asso_values[(unsigned char)str[0]]; + break; + } + return hval + asso_values[(unsigned char)str[len - 1]]; +} + +struct stringpool_t + { + char stringpool_str0[sizeof("tee")]; + char stringpool_str1[sizeof("send")]; + char stringpool_str2[sizeof("time")]; + char stringpool_str3[sizeof("rtas")]; + char stringpool_str4[sizeof("idle")]; + char stringpool_str5[sizeof("times")]; + char stringpool_str6[sizeof("read")]; + char stringpool_str7[sizeof("select")]; + char stringpool_str8[sizeof("setsid")]; + char stringpool_str9[sizeof("getsid")]; + char stringpool_str10[sizeof("setns")]; + char stringpool_str11[sizeof("getegid")]; + char stringpool_str12[sizeof("setfsgid")]; + char stringpool_str13[sizeof("setregid")]; + char stringpool_str14[sizeof("fchdir")]; + char stringpool_str15[sizeof("timerfd")]; + char stringpool_str16[sizeof("setresgid")]; + char stringpool_str17[sizeof("getresgid")]; + char stringpool_str18[sizeof("fsync")]; + char stringpool_str19[sizeof("sendmsg")]; + char stringpool_str20[sizeof("readdir")]; + char stringpool_str21[sizeof("timer_settime")]; + char stringpool_str22[sizeof("timer_gettime")]; + char stringpool_str23[sizeof("sched_setattr")]; + char stringpool_str24[sizeof("sched_getattr")]; + char stringpool_str25[sizeof("timerfd_settime")]; + char stringpool_str26[sizeof("timerfd_gettime")]; + char stringpool_str27[sizeof("sched_setscheduler")]; + char stringpool_str28[sizeof("sched_getscheduler")]; + char stringpool_str29[sizeof("ipc")]; + char stringpool_str30[sizeof("timerfd_create")]; + char stringpool_str31[sizeof("pipe")]; + char stringpool_str32[sizeof("timer_create")]; + char stringpool_str33[sizeof("prof")]; + char stringpool_str34[sizeof("sendto")]; + char stringpool_str35[sizeof("msync")]; + char stringpool_str36[sizeof("memfd_secret")]; + char stringpool_str37[sizeof("sched_setparam")]; + char stringpool_str38[sizeof("sched_getparam")]; + char stringpool_str39[sizeof("sendmmsg")]; + char stringpool_str40[sizeof("memfd_create")]; + char stringpool_str41[sizeof("rt_sigtimedwait")]; + char stringpool_str42[sizeof("connect")]; + char stringpool_str43[sizeof("mount")]; + char stringpool_str44[sizeof("mincore")]; + char stringpool_str45[sizeof("close")]; + char stringpool_str46[sizeof("ioprio_set")]; + char stringpool_str47[sizeof("ioprio_get")]; + char stringpool_str48[sizeof("delete_module")]; + char stringpool_str49[sizeof("pidfd_getfd")]; + char stringpool_str50[sizeof("reboot")]; + char stringpool_str51[sizeof("ioperm")]; + char stringpool_str52[sizeof("sendfile")]; + char stringpool_str53[sizeof("pselect6")]; + char stringpool_str54[sizeof("clone")]; + char stringpool_str55[sizeof("socket")]; + char stringpool_str56[sizeof("access")]; + char stringpool_str57[sizeof("mount_setattr")]; + char stringpool_str58[sizeof("capset")]; + char stringpool_str59[sizeof("timer_delete")]; + char stringpool_str60[sizeof("process_madvise")]; + char stringpool_str61[sizeof("process_mrelease")]; + char stringpool_str62[sizeof("iopl")]; + char stringpool_str63[sizeof("sched_rr_get_interval")]; + char stringpool_str64[sizeof("setrlimit")]; + char stringpool_str65[sizeof("getrlimit")]; + char stringpool_str66[sizeof("rseq")]; + char stringpool_str67[sizeof("open_tree")]; + char stringpool_str68[sizeof("nice")]; + char stringpool_str69[sizeof("copy_file_range")]; + char stringpool_str70[sizeof("stime")]; + char stringpool_str71[sizeof("ftime")]; + char stringpool_str72[sizeof("getpid")]; + char stringpool_str73[sizeof("setpgid")]; + char stringpool_str74[sizeof("getpgid")]; + char stringpool_str75[sizeof("semctl")]; + char stringpool_str76[sizeof("pause")]; + char stringpool_str77[sizeof("mprotect")]; + char stringpool_str78[sizeof("semop")]; + char stringpool_str79[sizeof("truncate")]; + char stringpool_str80[sizeof("getdents")]; + char stringpool_str81[sizeof("shmdt")]; + char stringpool_str82[sizeof("_sysctl")]; + char stringpool_str83[sizeof("accept")]; + char stringpool_str84[sizeof("getpmsg")]; + char stringpool_str85[sizeof("semget")]; + char stringpool_str86[sizeof("poll")]; + char stringpool_str87[sizeof("seccomp")]; + char stringpool_str88[sizeof("setgid")]; + char stringpool_str89[sizeof("getgid")]; + char stringpool_str90[sizeof("msgsnd")]; + char stringpool_str91[sizeof("msgctl")]; + char stringpool_str92[sizeof("membarrier")]; + char stringpool_str93[sizeof("fchmod")]; + char stringpool_str94[sizeof("timer_getoverrun")]; + char stringpool_str95[sizeof("sched_get_priority_min")]; + char stringpool_str96[sizeof("rt_sigreturn")]; + char stringpool_str97[sizeof("epoll_create1")]; + char stringpool_str98[sizeof("epoll_create")]; + char stringpool_str99[sizeof("msgget")]; + char stringpool_str100[sizeof("s390_pci_mmio_write")]; + char stringpool_str101[sizeof("pivot_root")]; + char stringpool_str102[sizeof("s390_pci_mmio_read")]; + char stringpool_str103[sizeof("getppid")]; + char stringpool_str104[sizeof("migrate_pages")]; + char stringpool_str105[sizeof("openat")]; + char stringpool_str106[sizeof("oldstat")]; + char stringpool_str107[sizeof("profil")]; + char stringpool_str108[sizeof("fsconfig")]; + char stringpool_str109[sizeof("oldfstat")]; + char stringpool_str110[sizeof("setuid")]; + char stringpool_str111[sizeof("getuid")]; + char stringpool_str112[sizeof("alarm")]; + char stringpool_str113[sizeof("vm86")]; + char stringpool_str114[sizeof("chmod")]; + char stringpool_str115[sizeof("sched_get_priority_max")]; + char stringpool_str116[sizeof("signalfd")]; + char stringpool_str117[sizeof("mmap")]; + char stringpool_str118[sizeof("faccessat")]; + char stringpool_str119[sizeof("move_pages")]; + char stringpool_str120[sizeof("rt_sigpending")]; + char stringpool_str121[sizeof("cachestat")]; + char stringpool_str122[sizeof("open")]; + char stringpool_str123[sizeof("oldlstat")]; + char stringpool_str124[sizeof("mpx")]; + char stringpool_str125[sizeof("eventfd")]; + char stringpool_str126[sizeof("chroot")]; + char stringpool_str127[sizeof("getpgrp")]; + char stringpool_str128[sizeof("linkat")]; + char stringpool_str129[sizeof("stat")]; + char stringpool_str130[sizeof("epoll_ctl_old")]; + char stringpool_str131[sizeof("pciconfig_write")]; + char stringpool_str132[sizeof("pciconfig_iobase")]; + char stringpool_str133[sizeof("pciconfig_read")]; + char stringpool_str134[sizeof("statfs")]; + char stringpool_str135[sizeof("stty")]; + char stringpool_str136[sizeof("gtty")]; + char stringpool_str137[sizeof("sysfs")]; + char stringpool_str138[sizeof("capget")]; + char stringpool_str139[sizeof("arch_prctl")]; + char stringpool_str140[sizeof("ppoll")]; + char stringpool_str141[sizeof("sync")]; + char stringpool_str142[sizeof("cachectl")]; + char stringpool_str143[sizeof("signal")]; + char stringpool_str144[sizeof("gettid")]; + char stringpool_str145[sizeof("syncfs")]; + char stringpool_str146[sizeof("fallocate")]; + char stringpool_str147[sizeof("rt_sigaction")]; + char stringpool_str148[sizeof("socketpair")]; + char stringpool_str149[sizeof("geteuid")]; + char stringpool_str150[sizeof("setfsuid")]; + char stringpool_str151[sizeof("setreuid")]; + char stringpool_str152[sizeof("fchmodat")]; + char stringpool_str153[sizeof("sethostname")]; + char stringpool_str154[sizeof("setresuid")]; + char stringpool_str155[sizeof("getresuid")]; + char stringpool_str156[sizeof("pidfd_send_signal")]; + char stringpool_str157[sizeof("pidfd_open")]; + char stringpool_str158[sizeof("rt_sigsuspend")]; + char stringpool_str159[sizeof("clone3")]; + char stringpool_str160[sizeof("dup")]; + char stringpool_str161[sizeof("shmctl")]; + char stringpool_str162[sizeof("sched_setaffinity")]; + char stringpool_str163[sizeof("sched_getaffinity")]; + char stringpool_str164[sizeof("sched_yield")]; + char stringpool_str165[sizeof("setdomainname")]; + char stringpool_str166[sizeof("epoll_ctl")]; + char stringpool_str167[sizeof("shmget")]; + char stringpool_str168[sizeof("setresgid32")]; + char stringpool_str169[sizeof("getresgid32")]; + char stringpool_str170[sizeof("syslog")]; + char stringpool_str171[sizeof("rmdir")]; + char stringpool_str172[sizeof("getrandom")]; + char stringpool_str173[sizeof("mknod")]; + char stringpool_str174[sizeof("vm86old")]; + char stringpool_str175[sizeof("pkey_free")]; + char stringpool_str176[sizeof("mq_getsetattr")]; + char stringpool_str177[sizeof("fork")]; + char stringpool_str178[sizeof("close_range")]; + char stringpool_str179[sizeof("kill")]; + char stringpool_str180[sizeof("usr26")]; + char stringpool_str181[sizeof("splice")]; + char stringpool_str182[sizeof("set_tls")]; + char stringpool_str183[sizeof("get_tls")]; + char stringpool_str184[sizeof("io_destroy")]; + char stringpool_str185[sizeof("acct")]; + char stringpool_str186[sizeof("setitimer")]; + char stringpool_str187[sizeof("getitimer")]; + char stringpool_str188[sizeof("newfstatat")]; + char stringpool_str189[sizeof("clock_getres")]; + char stringpool_str190[sizeof("clock_settime")]; + char stringpool_str191[sizeof("clock_gettime")]; + char stringpool_str192[sizeof("socketcall")]; + char stringpool_str193[sizeof("kexec_file_load")]; + char stringpool_str194[sizeof("mremap")]; + char stringpool_str195[sizeof("finit_module")]; + char stringpool_str196[sizeof("rt_sigprocmask")]; + char stringpool_str197[sizeof("sync_file_range")]; + char stringpool_str198[sizeof("flistxattr")]; + char stringpool_str199[sizeof("getrusage")]; + char stringpool_str200[sizeof("io_pgetevents")]; + char stringpool_str201[sizeof("execve")]; + char stringpool_str202[sizeof("setsockopt")]; + char stringpool_str203[sizeof("getsockopt")]; + char stringpool_str204[sizeof("readahead")]; + char stringpool_str205[sizeof("semtimedop")]; + char stringpool_str206[sizeof("link")]; + char stringpool_str207[sizeof("getpeername")]; + char stringpool_str208[sizeof("utime")]; + char stringpool_str209[sizeof("setxattr")]; + char stringpool_str210[sizeof("getxattr")]; + char stringpool_str211[sizeof("utimes")]; + char stringpool_str212[sizeof("readv")]; + char stringpool_str213[sizeof("getcwd")]; + char stringpool_str214[sizeof("fcntl")]; + char stringpool_str215[sizeof("keyctl")]; + char stringpool_str216[sizeof("set_tid_address")]; + char stringpool_str217[sizeof("fsopen")]; + char stringpool_str218[sizeof("io_uring_enter")]; + char stringpool_str219[sizeof("io_setup")]; + char stringpool_str220[sizeof("io_getevents")]; + char stringpool_str221[sizeof("io_uring_register")]; + char stringpool_str222[sizeof("lock")]; + char stringpool_str223[sizeof("_newselect")]; + char stringpool_str224[sizeof("setfsgid32")]; + char stringpool_str225[sizeof("setregid32")]; + char stringpool_str226[sizeof("vserver")]; + char stringpool_str227[sizeof("tkill")]; + char stringpool_str228[sizeof("timer_settime64")]; + char stringpool_str229[sizeof("timer_gettime64")]; + char stringpool_str230[sizeof("timerfd_settime64")]; + char stringpool_str231[sizeof("timerfd_gettime64")]; + char stringpool_str232[sizeof("ioctl")]; + char stringpool_str233[sizeof("msgrcv")]; + char stringpool_str234[sizeof("exit")]; + char stringpool_str235[sizeof("recvmsg")]; + char stringpool_str236[sizeof("kcmp")]; + char stringpool_str237[sizeof("set_mempolicy_home_node")]; + char stringpool_str238[sizeof("sigpending")]; + char stringpool_str239[sizeof("io_cancel")]; + char stringpool_str240[sizeof("sched_rr_get_interval_time64")]; + char stringpool_str241[sizeof("pkey_mprotect")]; + char stringpool_str242[sizeof("nfsservctl")]; + char stringpool_str243[sizeof("mknodat")]; + char stringpool_str244[sizeof("vmsplice")]; + char stringpool_str245[sizeof("llistxattr")]; + char stringpool_str246[sizeof("name_to_handle_at")]; + char stringpool_str247[sizeof("rt_tgsigqueueinfo")]; + char stringpool_str248[sizeof("rt_sigqueueinfo")]; + char stringpool_str249[sizeof("fanotify_init")]; + char stringpool_str250[sizeof("io_uring_setup")]; + char stringpool_str251[sizeof("rt_sigtimedwait_time64")]; + char stringpool_str252[sizeof("prctl")]; + char stringpool_str253[sizeof("spu_create")]; + char stringpool_str254[sizeof("fsmount")]; + char stringpool_str255[sizeof("recvmmsg")]; + char stringpool_str256[sizeof("chdir")]; + char stringpool_str257[sizeof("ftruncate")]; + char stringpool_str258[sizeof("setpriority")]; + char stringpool_str259[sizeof("getpriority")]; + char stringpool_str260[sizeof("restart_syscall")]; + char stringpool_str261[sizeof("sysmips")]; + char stringpool_str262[sizeof("mq_timedsend")]; + char stringpool_str263[sizeof("putpmsg")]; + char stringpool_str264[sizeof("fstat")]; + char stringpool_str265[sizeof("bind")]; + char stringpool_str266[sizeof("ulimit")]; + char stringpool_str267[sizeof("sigsuspend")]; + char stringpool_str268[sizeof("mq_timedreceive")]; + char stringpool_str269[sizeof("sendfile64")]; + char stringpool_str270[sizeof("kexec_load")]; + char stringpool_str271[sizeof("fstatfs")]; + char stringpool_str272[sizeof("nanosleep")]; + char stringpool_str273[sizeof("creat")]; + char stringpool_str274[sizeof("process_vm_readv")]; + char stringpool_str275[sizeof("process_vm_writev")]; + char stringpool_str276[sizeof("pselect6_time64")]; + char stringpool_str277[sizeof("s390_guarded_storage")]; + char stringpool_str278[sizeof("recvfrom")]; + char stringpool_str279[sizeof("execveat")]; + char stringpool_str280[sizeof("tgkill")]; + char stringpool_str281[sizeof("rename")]; + char stringpool_str282[sizeof("bpf")]; + char stringpool_str283[sizeof("lookup_dcookie")]; + char stringpool_str284[sizeof("faccessat2")]; + char stringpool_str285[sizeof("unshare")]; + char stringpool_str286[sizeof("setgroups")]; + char stringpool_str287[sizeof("getgroups")]; + char stringpool_str288[sizeof("move_mount")]; + char stringpool_str289[sizeof("madvise")]; + char stringpool_str290[sizeof("mbind")]; + char stringpool_str291[sizeof("uname")]; + char stringpool_str292[sizeof("s390_runtime_instr")]; + char stringpool_str293[sizeof("ptrace")]; + char stringpool_str294[sizeof("truncate64")]; + char stringpool_str295[sizeof("mq_open")]; + char stringpool_str296[sizeof("getdents64")]; + char stringpool_str297[sizeof("lstat")]; + char stringpool_str298[sizeof("getsockname")]; + char stringpool_str299[sizeof("s390_sthyi")]; + char stringpool_str300[sizeof("swapoff")]; + char stringpool_str301[sizeof("perf_event_open")]; + char stringpool_str302[sizeof("landlock_add_rule")]; + char stringpool_str303[sizeof("landlock_restrict_self")]; + char stringpool_str304[sizeof("landlock_create_ruleset")]; + char stringpool_str305[sizeof("subpage_prot")]; + char stringpool_str306[sizeof("create_module")]; + char stringpool_str307[sizeof("removexattr")]; + char stringpool_str308[sizeof("sigreturn")]; + char stringpool_str309[sizeof("sigprocmask")]; + char stringpool_str310[sizeof("fsetxattr")]; + char stringpool_str311[sizeof("fgetxattr")]; + char stringpool_str312[sizeof("olduname")]; + char stringpool_str313[sizeof("riscv_flush_icache")]; + char stringpool_str314[sizeof("getcpu")]; + char stringpool_str315[sizeof("lseek")]; + char stringpool_str316[sizeof("setresuid32")]; + char stringpool_str317[sizeof("getresuid32")]; + char stringpool_str318[sizeof("mkdir")]; + char stringpool_str319[sizeof("flock")]; + char stringpool_str320[sizeof("tuxcall")]; + char stringpool_str321[sizeof("recv")]; + char stringpool_str322[sizeof("syscall")]; + char stringpool_str323[sizeof("_llseek")]; + char stringpool_str324[sizeof("readlinkat")]; + char stringpool_str325[sizeof("futex_requeue")]; + char stringpool_str326[sizeof("pkey_alloc")]; + char stringpool_str327[sizeof("mlock")]; + char stringpool_str328[sizeof("settimeofday")]; + char stringpool_str329[sizeof("gettimeofday")]; + char stringpool_str330[sizeof("statx")]; + char stringpool_str331[sizeof("chown")]; + char stringpool_str332[sizeof("futex")]; + char stringpool_str333[sizeof("listen")]; + char stringpool_str334[sizeof("cacheflush")]; + char stringpool_str335[sizeof("renameat")]; + char stringpool_str336[sizeof("umount")]; + char stringpool_str337[sizeof("munmap")]; + char stringpool_str338[sizeof("shmat")]; + char stringpool_str339[sizeof("ppoll_time64")]; + char stringpool_str340[sizeof("remap_file_pages")]; + char stringpool_str341[sizeof("pipe2")]; + char stringpool_str342[sizeof("lsetxattr")]; + char stringpool_str343[sizeof("lgetxattr")]; + char stringpool_str344[sizeof("dup2")]; + char stringpool_str345[sizeof("listxattr")]; + char stringpool_str346[sizeof("ugetrlimit")]; + char stringpool_str347[sizeof("write")]; + char stringpool_str348[sizeof("utimensat")]; + char stringpool_str349[sizeof("set_thread_area")]; + char stringpool_str350[sizeof("get_thread_area")]; + char stringpool_str351[sizeof("epoll_wait")]; + char stringpool_str352[sizeof("sync_file_range2")]; + char stringpool_str353[sizeof("epoll_wait_old")]; + char stringpool_str354[sizeof("fremovexattr")]; + char stringpool_str355[sizeof("setfsuid32")]; + char stringpool_str356[sizeof("setreuid32")]; + char stringpool_str357[sizeof("mlockall")]; + char stringpool_str358[sizeof("personality")]; + char stringpool_str359[sizeof("mkdirat")]; + char stringpool_str360[sizeof("set_mempolicy")]; + char stringpool_str361[sizeof("get_mempolicy")]; + char stringpool_str362[sizeof("futimesat")]; + char stringpool_str363[sizeof("fchownat")]; + char stringpool_str364[sizeof("get_kernel_syms")]; + char stringpool_str365[sizeof("inotify_init1")]; + char stringpool_str366[sizeof("inotify_init")]; + char stringpool_str367[sizeof("vfork")]; + char stringpool_str368[sizeof("fanotify_mark")]; + char stringpool_str369[sizeof("swapcontext")]; + char stringpool_str370[sizeof("modify_ldt")]; + char stringpool_str371[sizeof("getegid32")]; + char stringpool_str372[sizeof("epoll_pwait")]; + char stringpool_str373[sizeof("userfaultfd")]; + char stringpool_str374[sizeof("brk")]; + char stringpool_str375[sizeof("fchown")]; + char stringpool_str376[sizeof("semtimedop_time64")]; + char stringpool_str377[sizeof("ustat")]; + char stringpool_str378[sizeof("dup3")]; + char stringpool_str379[sizeof("query_module")]; + char stringpool_str380[sizeof("init_module")]; + char stringpool_str381[sizeof("oldolduname")]; + char stringpool_str382[sizeof("clock_settime64")]; + char stringpool_str383[sizeof("clock_gettime64")]; + char stringpool_str384[sizeof("lremovexattr")]; + char stringpool_str385[sizeof("readlink")]; + char stringpool_str386[sizeof("clock_getres_time64")]; + char stringpool_str387[sizeof("vhangup")]; + char stringpool_str388[sizeof("clock_adjtime")]; + char stringpool_str389[sizeof("request_key")]; + char stringpool_str390[sizeof("sysinfo")]; + char stringpool_str391[sizeof("mmap2")]; + char stringpool_str392[sizeof("adjtimex")]; + char stringpool_str393[sizeof("waitid")]; + char stringpool_str394[sizeof("security")]; + char stringpool_str395[sizeof("io_pgetevents_time64")]; + char stringpool_str396[sizeof("mq_notify")]; + char stringpool_str397[sizeof("clock_nanosleep")]; + char stringpool_str398[sizeof("umask")]; + char stringpool_str399[sizeof("openat2")]; + char stringpool_str400[sizeof("lchown")]; + char stringpool_str401[sizeof("fdatasync")]; + char stringpool_str402[sizeof("exit_group")]; + char stringpool_str403[sizeof("sigaction")]; + char stringpool_str404[sizeof("fspick")]; + char stringpool_str405[sizeof("symlinkat")]; + char stringpool_str406[sizeof("setgroups32")]; + char stringpool_str407[sizeof("getgroups32")]; + char stringpool_str408[sizeof("io_submit")]; + char stringpool_str409[sizeof("waitpid")]; + char stringpool_str410[sizeof("swapon")]; + char stringpool_str411[sizeof("arm_sync_file_range")]; + char stringpool_str412[sizeof("eventfd2")]; + char stringpool_str413[sizeof("afs_syscall")]; + char stringpool_str414[sizeof("ftruncate64")]; + char stringpool_str415[sizeof("quotactl_fd")]; + char stringpool_str416[sizeof("recvmmsg_time64")]; + char stringpool_str417[sizeof("mq_timedsend_time64")]; + char stringpool_str418[sizeof("munlockall")]; + char stringpool_str419[sizeof("munlock")]; + char stringpool_str420[sizeof("setgid32")]; + char stringpool_str421[sizeof("getgid32")]; + char stringpool_str422[sizeof("mq_timedreceive_time64")]; + char stringpool_str423[sizeof("inotify_rm_watch")]; + char stringpool_str424[sizeof("futex_time64")]; + char stringpool_str425[sizeof("spu_run")]; + char stringpool_str426[sizeof("fchmodat2")]; + char stringpool_str427[sizeof("multiplexer")]; + char stringpool_str428[sizeof("setuid32")]; + char stringpool_str429[sizeof("getuid32")]; + char stringpool_str430[sizeof("ssetmask")]; + char stringpool_str431[sizeof("sgetmask")]; + char stringpool_str432[sizeof("quotactl")]; + char stringpool_str433[sizeof("sigaltstack")]; + char stringpool_str434[sizeof("accept4")]; + char stringpool_str435[sizeof("preadv")]; + char stringpool_str436[sizeof("mlock2")]; + char stringpool_str437[sizeof("futex_wait")]; + char stringpool_str438[sizeof("symlink")]; + char stringpool_str439[sizeof("inotify_add_watch")]; + char stringpool_str440[sizeof("map_shadow_stack")]; + char stringpool_str441[sizeof("geteuid32")]; + char stringpool_str442[sizeof("signalfd4")]; + char stringpool_str443[sizeof("epoll_pwait2")]; + char stringpool_str444[sizeof("stat64")]; + char stringpool_str445[sizeof("open_by_handle_at")]; + char stringpool_str446[sizeof("statfs64")]; + char stringpool_str447[sizeof("utimensat_time64")]; + char stringpool_str448[sizeof("writev")]; + char stringpool_str449[sizeof("set_robust_list")]; + char stringpool_str450[sizeof("get_robust_list")]; + char stringpool_str451[sizeof("bdflush")]; + char stringpool_str452[sizeof("arm_fadvise64_64")]; + char stringpool_str453[sizeof("fcntl64")]; + char stringpool_str454[sizeof("switch_endian")]; + char stringpool_str455[sizeof("clock_nanosleep_time64")]; + char stringpool_str456[sizeof("shutdown")]; + char stringpool_str457[sizeof("clock_adjtime64")]; + char stringpool_str458[sizeof("pwritev")]; + char stringpool_str459[sizeof("futex_waitv")]; + char stringpool_str460[sizeof("prlimit64")]; + char stringpool_str461[sizeof("chown32")]; + char stringpool_str462[sizeof("add_key")]; + char stringpool_str463[sizeof("unlinkat")]; + char stringpool_str464[sizeof("futex_wake")]; + char stringpool_str465[sizeof("renameat2")]; + char stringpool_str466[sizeof("umount2")]; + char stringpool_str467[sizeof("usr32")]; + char stringpool_str468[sizeof("mq_unlink")]; + char stringpool_str469[sizeof("uselib")]; + char stringpool_str470[sizeof("fstat64")]; + char stringpool_str471[sizeof("fstatfs64")]; + char stringpool_str472[sizeof("fadvise64")]; + char stringpool_str473[sizeof("fadvise64_64")]; + char stringpool_str474[sizeof("fchown32")]; + char stringpool_str475[sizeof("pread64")]; + char stringpool_str476[sizeof("sys_debug_setcontext")]; + char stringpool_str477[sizeof("lstat64")]; + char stringpool_str478[sizeof("preadv2")]; + char stringpool_str479[sizeof("unlink")]; + char stringpool_str480[sizeof("lchown32")]; + char stringpool_str481[sizeof("fstatat64")]; + char stringpool_str482[sizeof("breakpoint")]; + char stringpool_str483[sizeof("break")]; + char stringpool_str484[sizeof("wait4")]; + char stringpool_str485[sizeof("pwrite64")]; + char stringpool_str486[sizeof("pwritev2")]; + }; +static const struct stringpool_t stringpool_contents = + { + "tee", + "send", + "time", + "rtas", + "idle", + "times", + "read", + "select", + "setsid", + "getsid", + "setns", + "getegid", + "setfsgid", + "setregid", + "fchdir", + "timerfd", + "setresgid", + "getresgid", + "fsync", + "sendmsg", + "readdir", + "timer_settime", + "timer_gettime", + "sched_setattr", + "sched_getattr", + "timerfd_settime", + "timerfd_gettime", + "sched_setscheduler", + "sched_getscheduler", + "ipc", + "timerfd_create", + "pipe", + "timer_create", + "prof", + "sendto", + "msync", + "memfd_secret", + "sched_setparam", + "sched_getparam", + "sendmmsg", + "memfd_create", + "rt_sigtimedwait", + "connect", + "mount", + "mincore", + "close", + "ioprio_set", + "ioprio_get", + "delete_module", + "pidfd_getfd", + "reboot", + "ioperm", + "sendfile", + "pselect6", + "clone", + "socket", + "access", + "mount_setattr", + "capset", + "timer_delete", + "process_madvise", + "process_mrelease", + "iopl", + "sched_rr_get_interval", + "setrlimit", + "getrlimit", + "rseq", + "open_tree", + "nice", + "copy_file_range", + "stime", + "ftime", + "getpid", + "setpgid", + "getpgid", + "semctl", + "pause", + "mprotect", + "semop", + "truncate", + "getdents", + "shmdt", + "_sysctl", + "accept", + "getpmsg", + "semget", + "poll", + "seccomp", + "setgid", + "getgid", + "msgsnd", + "msgctl", + "membarrier", + "fchmod", + "timer_getoverrun", + "sched_get_priority_min", + "rt_sigreturn", + "epoll_create1", + "epoll_create", + "msgget", + "s390_pci_mmio_write", + "pivot_root", + "s390_pci_mmio_read", + "getppid", + "migrate_pages", + "openat", + "oldstat", + "profil", + "fsconfig", + "oldfstat", + "setuid", + "getuid", + "alarm", + "vm86", + "chmod", + "sched_get_priority_max", + "signalfd", + "mmap", + "faccessat", + "move_pages", + "rt_sigpending", + "cachestat", + "open", + "oldlstat", + "mpx", + "eventfd", + "chroot", + "getpgrp", + "linkat", + "stat", + "epoll_ctl_old", + "pciconfig_write", + "pciconfig_iobase", + "pciconfig_read", + "statfs", + "stty", + "gtty", + "sysfs", + "capget", + "arch_prctl", + "ppoll", + "sync", + "cachectl", + "signal", + "gettid", + "syncfs", + "fallocate", + "rt_sigaction", + "socketpair", + "geteuid", + "setfsuid", + "setreuid", + "fchmodat", + "sethostname", + "setresuid", + "getresuid", + "pidfd_send_signal", + "pidfd_open", + "rt_sigsuspend", + "clone3", + "dup", + "shmctl", + "sched_setaffinity", + "sched_getaffinity", + "sched_yield", + "setdomainname", + "epoll_ctl", + "shmget", + "setresgid32", + "getresgid32", + "syslog", + "rmdir", + "getrandom", + "mknod", + "vm86old", + "pkey_free", + "mq_getsetattr", + "fork", + "close_range", + "kill", + "usr26", + "splice", + "set_tls", + "get_tls", + "io_destroy", + "acct", + "setitimer", + "getitimer", + "newfstatat", + "clock_getres", + "clock_settime", + "clock_gettime", + "socketcall", + "kexec_file_load", + "mremap", + "finit_module", + "rt_sigprocmask", + "sync_file_range", + "flistxattr", + "getrusage", + "io_pgetevents", + "execve", + "setsockopt", + "getsockopt", + "readahead", + "semtimedop", + "link", + "getpeername", + "utime", + "setxattr", + "getxattr", + "utimes", + "readv", + "getcwd", + "fcntl", + "keyctl", + "set_tid_address", + "fsopen", + "io_uring_enter", + "io_setup", + "io_getevents", + "io_uring_register", + "lock", + "_newselect", + "setfsgid32", + "setregid32", + "vserver", + "tkill", + "timer_settime64", + "timer_gettime64", + "timerfd_settime64", + "timerfd_gettime64", + "ioctl", + "msgrcv", + "exit", + "recvmsg", + "kcmp", + "set_mempolicy_home_node", + "sigpending", + "io_cancel", + "sched_rr_get_interval_time64", + "pkey_mprotect", + "nfsservctl", + "mknodat", + "vmsplice", + "llistxattr", + "name_to_handle_at", + "rt_tgsigqueueinfo", + "rt_sigqueueinfo", + "fanotify_init", + "io_uring_setup", + "rt_sigtimedwait_time64", + "prctl", + "spu_create", + "fsmount", + "recvmmsg", + "chdir", + "ftruncate", + "setpriority", + "getpriority", + "restart_syscall", + "sysmips", + "mq_timedsend", + "putpmsg", + "fstat", + "bind", + "ulimit", + "sigsuspend", + "mq_timedreceive", + "sendfile64", + "kexec_load", + "fstatfs", + "nanosleep", + "creat", + "process_vm_readv", + "process_vm_writev", + "pselect6_time64", + "s390_guarded_storage", + "recvfrom", + "execveat", + "tgkill", + "rename", + "bpf", + "lookup_dcookie", + "faccessat2", + "unshare", + "setgroups", + "getgroups", + "move_mount", + "madvise", + "mbind", + "uname", + "s390_runtime_instr", + "ptrace", + "truncate64", + "mq_open", + "getdents64", + "lstat", + "getsockname", + "s390_sthyi", + "swapoff", + "perf_event_open", + "landlock_add_rule", + "landlock_restrict_self", + "landlock_create_ruleset", + "subpage_prot", + "create_module", + "removexattr", + "sigreturn", + "sigprocmask", + "fsetxattr", + "fgetxattr", + "olduname", + "riscv_flush_icache", + "getcpu", + "lseek", + "setresuid32", + "getresuid32", + "mkdir", + "flock", + "tuxcall", + "recv", + "syscall", + "_llseek", + "readlinkat", + "futex_requeue", + "pkey_alloc", + "mlock", + "settimeofday", + "gettimeofday", + "statx", + "chown", + "futex", + "listen", + "cacheflush", + "renameat", + "umount", + "munmap", + "shmat", + "ppoll_time64", + "remap_file_pages", + "pipe2", + "lsetxattr", + "lgetxattr", + "dup2", + "listxattr", + "ugetrlimit", + "write", + "utimensat", + "set_thread_area", + "get_thread_area", + "epoll_wait", + "sync_file_range2", + "epoll_wait_old", + "fremovexattr", + "setfsuid32", + "setreuid32", + "mlockall", + "personality", + "mkdirat", + "set_mempolicy", + "get_mempolicy", + "futimesat", + "fchownat", + "get_kernel_syms", + "inotify_init1", + "inotify_init", + "vfork", + "fanotify_mark", + "swapcontext", + "modify_ldt", + "getegid32", + "epoll_pwait", + "userfaultfd", + "brk", + "fchown", + "semtimedop_time64", + "ustat", + "dup3", + "query_module", + "init_module", + "oldolduname", + "clock_settime64", + "clock_gettime64", + "lremovexattr", + "readlink", + "clock_getres_time64", + "vhangup", + "clock_adjtime", + "request_key", + "sysinfo", + "mmap2", + "adjtimex", + "waitid", + "security", + "io_pgetevents_time64", + "mq_notify", + "clock_nanosleep", + "umask", + "openat2", + "lchown", + "fdatasync", + "exit_group", + "sigaction", + "fspick", + "symlinkat", + "setgroups32", + "getgroups32", + "io_submit", + "waitpid", + "swapon", + "arm_sync_file_range", + "eventfd2", + "afs_syscall", + "ftruncate64", + "quotactl_fd", + "recvmmsg_time64", + "mq_timedsend_time64", + "munlockall", + "munlock", + "setgid32", + "getgid32", + "mq_timedreceive_time64", + "inotify_rm_watch", + "futex_time64", + "spu_run", + "fchmodat2", + "multiplexer", + "setuid32", + "getuid32", + "ssetmask", + "sgetmask", + "quotactl", + "sigaltstack", + "accept4", + "preadv", + "mlock2", + "futex_wait", + "symlink", + "inotify_add_watch", + "map_shadow_stack", + "geteuid32", + "signalfd4", + "epoll_pwait2", + "stat64", + "open_by_handle_at", + "statfs64", + "utimensat_time64", + "writev", + "set_robust_list", + "get_robust_list", + "bdflush", + "arm_fadvise64_64", + "fcntl64", + "switch_endian", + "clock_nanosleep_time64", + "shutdown", + "clock_adjtime64", + "pwritev", + "futex_waitv", + "prlimit64", + "chown32", + "add_key", + "unlinkat", + "futex_wake", + "renameat2", + "umount2", + "usr32", + "mq_unlink", + "uselib", + "fstat64", + "fstatfs64", + "fadvise64", + "fadvise64_64", + "fchown32", + "pread64", + "sys_debug_setcontext", + "lstat64", + "preadv2", + "unlink", + "lchown32", + "fstatat64", + "breakpoint", + "break", + "wait4", + "pwrite64", + "pwritev2" + }; +#define stringpool ((const char *) &stringpool_contents) + +static const struct arch_syscall_table wordlist[] = + { +#line 468 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str0,437,315,276,276,342,77,306,265,269,293,293,284,284,77,308,308}, +#line 380 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str1,349,__PNR_send,__PNR_send,__PNR_send,289,__PNR_send,178,__PNR_send,__PNR_send,58,58,334,334,__PNR_send,__PNR_send,__PNR_send}, +#line 470 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str2,439,13,201,201,__PNR_time,__PNR_time,13,__PNR_time,__PNR_time,13,13,13,13,__PNR_time,13,__PNR_time}, +#line 344 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str3,313,__PNR_rtas,__PNR_rtas,__PNR_rtas,__PNR_rtas,__PNR_rtas,__PNR_rtas,__PNR_rtas,__PNR_rtas,__PNR_rtas,__PNR_rtas,255,255,__PNR_rtas,__PNR_rtas,__PNR_rtas}, +#line 179 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str4,148,112,__PNR_idle,__PNR_idle,__PNR_idle,__PNR_idle,112,__PNR_idle,__PNR_idle,__PNR_idle,__PNR_idle,112,112,__PNR_idle,112,112}, +#line 484 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str5,453,43,100,100,43,153,43,98,98,43,43,43,43,153,43,43}, +#line 322 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str6,291,3,0,0,3,63,3,0,0,3,3,3,3,63,3,3}, +#line 374 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str7,343,82,23,23,__PNR_select,__PNR_select,__PNR_select,__PNR_select,__PNR_select,__PNR_select,__PNR_select,82,82,__PNR_select,__PNR_select,142}, +#line 412 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str8,381,66,112,112,66,157,66,110,110,66,66,66,66,157,66,66}, +#line 168 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str9,137,147,124,124,147,156,151,122,122,147,147,147,147,156,147,147}, +#line 399 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str10,368,346,308,308,375,268,344,303,308,328,328,350,350,268,339,339}, +#line 142 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str11,111,50,108,108,50,177,50,106,106,50,50,50,50,177,50,202}, +#line 387 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str12,356,139,123,123,139,152,139,121,121,139,139,139,139,152,139,216}, +#line 402 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str13,371,71,114,114,71,143,71,112,112,71,71,71,71,143,71,204}, +#line 101 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str14,70,133,81,81,133,50,133,79,79,133,133,133,133,50,133,133}, +#line 473 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str15,442,__PNR_timerfd,__PNR_timerfd,__PNR_timerfd,__PNR_timerfd,__PNR_timerfd,318,277,281,__PNR_timerfd,__PNR_timerfd,__PNR_timerfd,__PNR_timerfd,__PNR_timerfd,317,317}, +#line 404 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str16,373,170,119,119,170,149,190,117,117,170,170,169,169,149,170,210}, +#line 161 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str17,130,171,120,120,171,150,191,118,118,171,171,170,170,150,171,211}, +#line 127 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str18,96,118,74,74,118,82,118,72,72,118,118,118,118,82,118,118}, +#line 384 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str19,353,370,46,518,296,211,179,45,45,183,183,341,341,211,370,370}, +#line 324 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str20,293,89,__PNR_readdir,__PNR_readdir,__PNR_readdir,__PNR_readdir,89,__PNR_readdir,__PNR_readdir,__PNR_readdir,__PNR_readdir,89,89,__PNR_readdir,89,89}, +#line 482 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str21,451,260,223,223,258,110,258,217,221,251,251,241,241,110,255,255}, +#line 480 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str22,449,261,224,224,259,108,259,218,222,252,252,242,242,108,256,256}, +#line 368 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str23,337,351,314,314,380,274,349,309,313,334,334,355,355,274,345,345}, +#line 360 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str24,329,352,315,315,381,275,350,310,314,335,335,356,356,275,346,346}, +#line 477 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str25,446,325,286,286,353,86,323,282,286,307,307,311,311,86,320,320}, +#line 475 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str26,444,326,287,287,354,87,322,281,285,308,308,312,312,87,321,321}, +#line 370 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str27,339,156,144,144,156,119,160,141,141,156,156,156,156,119,156,156}, +#line 364 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str28,333,157,145,145,157,120,161,142,142,157,157,157,157,120,157,157}, +#line 200 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str29,169,117,__PNR_ipc,__PNR_ipc,__PNR_ipc,__PNR_ipc,117,__PNR_ipc,__PNR_ipc,__PNR_ipc,__PNR_ipc,117,117,__PNR_ipc,117,117}, +#line 474 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str30,443,322,283,283,350,85,321,280,284,306,306,306,306,85,319,319}, +#line 292 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str31,261,42,22,22,42,__PNR_pipe,42,21,21,42,42,42,42,__PNR_pipe,42,42}, +#line 471 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str32,440,259,222,526,257,107,257,216,220,250,250,240,240,107,254,254}, +#line 310 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str33,279,44,__PNR_prof,__PNR_prof,__PNR_prof,__PNR_prof,44,__PNR_prof,__PNR_prof,__PNR_prof,__PNR_prof,44,44,__PNR_prof,__PNR_prof,__PNR_prof}, +#line 385 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str34,354,369,44,44,290,206,180,43,43,82,82,335,335,206,369,369}, +#line 262 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str35,231,144,26,26,144,227,144,25,25,144,144,144,144,227,144,144}, +#line 230 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str36,199,447,447,447,__PNR_memfd_secret,447,__PNR_memfd_secret,__PNR_memfd_secret,__PNR_memfd_secret,__PNR_memfd_secret,__PNR_memfd_secret,__PNR_memfd_secret,__PNR_memfd_secret,447,447,447}, +#line 369 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str37,338,154,142,142,154,118,158,139,139,154,154,154,154,118,154,154}, +#line 361 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str38,330,155,143,143,155,121,159,140,140,155,155,155,155,121,155,155}, +#line 383 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str39,352,345,307,538,374,269,343,302,307,329,329,349,349,269,358,358}, +#line 229 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str40,198,356,319,319,385,279,354,314,318,340,340,360,360,279,350,350}, +#line 351 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str41,320,177,128,523,177,137,197,126,126,177,177,176,176,137,177,177}, +#line 72 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str42,41,362,42,42,283,203,170,41,41,31,31,328,328,203,362,362}, +#line 243 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str43,212,21,165,165,21,40,21,160,160,21,21,21,21,40,21,21}, +#line 232 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str44,201,218,27,27,219,232,217,26,26,72,72,206,206,232,218,218}, +#line 70 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str45,39,6,3,3,6,57,6,3,3,6,6,6,6,57,6,6}, +#line 194 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str46,163,289,251,251,314,30,314,273,277,267,267,273,273,30,282,282}, +#line 193 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str47,162,290,252,252,315,31,315,274,278,268,268,274,274,31,283,283}, +#line 76 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str48,45,129,176,176,129,106,129,169,169,129,129,129,129,106,129,129}, +#line 289 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str49,258,438,438,438,438,438,438,438,438,438,438,438,438,438,438,438}, +#line 328 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str50,297,88,169,169,88,142,88,164,164,88,88,88,88,142,88,88}, +#line 189 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str51,158,101,173,173,__PNR_ioperm,__PNR_ioperm,101,__PNR_ioperm,__PNR_ioperm,__PNR_ioperm,__PNR_ioperm,101,101,__PNR_ioperm,101,__PNR_ioperm}, +#line 381 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str52,350,187,40,40,187,71,207,39,39,122,122,186,186,71,187,187}, +#line 312 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str53,281,308,270,270,335,72,301,260,264,273,273,280,280,72,301,301}, +#line 68 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str54,37,120,56,56,120,220,120,55,55,120,120,120,120,220,120,120}, +#line 436 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str55,405,359,41,41,281,198,183,40,40,17,17,326,326,198,359,359}, +#line 33 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str56,2,33,21,21,33,__PNR_access,33,20,20,33,33,33,33,__PNR_access,33,33}, +#line 244 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str57,213,442,442,442,442,442,442,442,442,442,442,442,442,442,442,442}, +#line 52 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str58,21,185,126,126,185,91,205,124,124,107,107,184,184,91,185,185}, +#line 472 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str59,441,263,226,226,261,111,261,220,224,254,254,244,244,111,258,258}, +#line 306 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str60,275,440,440,440,440,440,440,440,440,440,440,440,440,440,440,440}, +#line 307 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str61,276,448,448,448,448,448,448,448,448,448,448,448,448,448,448,448}, +#line 192 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str62,161,110,172,172,__PNR_iopl,__PNR_iopl,110,__PNR_iopl,__PNR_iopl,__PNR_iopl,__PNR_iopl,110,110,__PNR_iopl,__PNR_iopl,__PNR_iopl}, +#line 365 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str63,334,161,148,148,161,127,165,145,145,161,161,161,161,127,161,161}, +#line 410 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str64,379,75,160,160,75,164,75,155,155,75,75,75,75,164,75,75}, +#line 165 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str65,134,76,97,97,__PNR_getrlimit,163,76,95,95,76,76,76,76,163,76,191}, +#line 343 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str66,312,386,334,334,398,293,367,327,331,354,354,387,387,293,383,383}, +#line 282 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str67,251,428,428,428,428,428,428,428,428,428,428,428,428,428,428,428}, +#line 272 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str68,241,34,__PNR_nice,__PNR_nice,34,__PNR_nice,34,__PNR_nice,__PNR_nice,34,34,34,34,__PNR_nice,34,34}, +#line 73 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str69,42,377,326,326,391,285,360,320,324,346,346,379,379,285,375,375}, +#line 448 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str70,417,25,__PNR_stime,__PNR_stime,__PNR_stime,__PNR_stime,25,__PNR_stime,__PNR_stime,25,25,25,25,__PNR_stime,25,__PNR_stime}, +#line 128 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str71,97,35,__PNR_ftime,__PNR_ftime,__PNR_ftime,__PNR_ftime,35,__PNR_ftime,__PNR_ftime,__PNR_ftime,__PNR_ftime,35,35,__PNR_ftime,__PNR_ftime,__PNR_ftime}, +#line 156 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str72,125,20,39,39,20,172,20,38,38,20,20,20,20,172,20,20}, +#line 400 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str73,369,57,109,109,57,154,57,107,107,57,57,57,57,154,57,57}, +#line 154 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str74,123,132,121,121,132,155,132,119,119,132,132,132,132,155,132,132}, +#line 375 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str75,344,394,66,66,300,191,394,64,64,187,187,394,394,191,394,394}, +#line 283 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str76,252,29,34,34,29,__PNR_pause,29,33,33,29,29,29,29,__PNR_pause,29,29}, +#line 247 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str77,216,125,10,10,125,226,125,10,10,125,125,125,125,226,125,125}, +#line 377 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str78,346,__PNR_semop,65,65,298,193,__PNR_semop,63,63,185,185,__PNR_semop,__PNR_semop,193,__PNR_semop,__PNR_semop}, +#line 486 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str79,455,92,76,76,92,45,92,74,74,92,92,92,92,45,92,92}, +#line 140 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str80,109,141,78,78,141,__PNR_getdents,141,76,76,141,141,141,141,__PNR_getdents,141,141}, +#line 424 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str81,393,398,67,67,306,197,398,65,65,193,193,398,398,197,398,398}, +#line 462 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str82,431,149,156,__PNR__sysctl,149,__PNR__sysctl,153,152,152,149,149,149,149,__PNR__sysctl,149,149}, +#line 31 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str83,0,__PNR_accept,43,43,285,202,168,42,42,35,35,330,330,202,__PNR_accept,__PNR_accept}, +#line 157 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str84,126,188,181,181,__PNR_getpmsg,__PNR_getpmsg,208,174,174,__PNR_getpmsg,__PNR_getpmsg,187,187,__PNR_getpmsg,188,188}, +#line 376 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str85,345,393,64,64,299,190,393,62,62,186,186,393,393,190,393,393}, +#line 298 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str86,267,168,7,7,168,__PNR_poll,188,7,7,168,168,167,167,__PNR_poll,168,168}, +#line 372 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str87,341,354,317,317,383,277,352,312,316,338,338,358,358,277,348,348}, +#line 391 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str88,360,46,106,106,46,144,46,104,104,46,46,46,46,144,46,214}, +#line 146 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str89,115,47,104,104,47,176,47,102,102,47,47,47,47,176,47,200}, +#line 261 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str90,230,400,69,69,301,189,400,67,67,188,188,400,400,189,400,400}, +#line 258 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str91,227,402,71,71,304,187,402,69,69,191,191,402,402,187,402,402}, +#line 228 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str92,197,375,324,324,389,283,358,318,322,343,343,365,365,283,356,356}, +#line 102 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str93,71,94,91,91,94,52,94,89,89,94,94,94,94,52,94,94}, +#line 479 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str94,448,262,225,225,260,109,260,219,223,253,253,243,243,109,257,257}, +#line 363 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str95,332,160,147,147,160,126,164,144,144,160,160,160,160,126,160,160}, +#line 349 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str96,318,173,15,513,173,139,193,211,211,173,173,172,172,139,173,173}, +#line 81 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str97,50,329,291,291,357,20,326,285,289,311,311,315,315,20,327,327}, +#line 80 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str98,49,254,213,213,250,__PNR_epoll_create,248,207,207,224,224,236,236,__PNR_epoll_create,249,249}, +#line 259 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str99,228,399,68,68,303,186,399,66,66,190,190,399,399,186,399,399}, +#line 356 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str100,325,__PNR_s390_pci_mmio_write,__PNR_s390_pci_mmio_write,__PNR_s390_pci_mmio_write,__PNR_s390_pci_mmio_write,__PNR_s390_pci_mmio_write,__PNR_s390_pci_mmio_write,__PNR_s390_pci_mmio_write,__PNR_s390_pci_mmio_write,__PNR_s390_pci_mmio_write,__PNR_s390_pci_mmio_write,__PNR_s390_pci_mmio_write,__PNR_s390_pci_mmio_write,__PNR_s390_pci_mmio_write,352,352}, +#line 294 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str101,263,217,155,155,218,41,216,151,151,67,67,203,203,41,217,217}, +#line 355 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str102,324,__PNR_s390_pci_mmio_read,__PNR_s390_pci_mmio_read,__PNR_s390_pci_mmio_read,__PNR_s390_pci_mmio_read,__PNR_s390_pci_mmio_read,__PNR_s390_pci_mmio_read,__PNR_s390_pci_mmio_read,__PNR_s390_pci_mmio_read,__PNR_s390_pci_mmio_read,__PNR_s390_pci_mmio_read,__PNR_s390_pci_mmio_read,__PNR_s390_pci_mmio_read,__PNR_s390_pci_mmio_read,353,353}, +#line 158 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str103,127,64,110,110,64,173,64,108,108,64,64,64,64,173,64,64}, +#line 231 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str104,200,294,256,256,400,238,287,246,250,272,272,258,258,238,287,287}, +#line 279 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str105,248,295,257,257,322,56,288,247,251,275,275,286,286,56,288,288}, +#line 276 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str106,245,18,__PNR_oldstat,__PNR_oldstat,__PNR_oldstat,__PNR_oldstat,__PNR_oldstat,__PNR_oldstat,__PNR_oldstat,__PNR_oldstat,__PNR_oldstat,18,18,__PNR_oldstat,__PNR_oldstat,__PNR_oldstat}, +#line 311 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str107,280,98,__PNR_profil,__PNR_profil,__PNR_profil,__PNR_profil,98,__PNR_profil,__PNR_profil,__PNR_profil,__PNR_profil,98,98,__PNR_profil,__PNR_profil,__PNR_profil}, +#line 117 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str108,86,431,431,431,431,431,431,431,431,431,431,431,431,431,431,431}, +#line 273 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str109,242,28,__PNR_oldfstat,__PNR_oldfstat,__PNR_oldfstat,__PNR_oldfstat,__PNR_oldfstat,__PNR_oldfstat,__PNR_oldfstat,__PNR_oldfstat,__PNR_oldfstat,28,28,__PNR_oldfstat,__PNR_oldfstat,__PNR_oldfstat}, +#line 418 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str110,387,23,105,105,23,146,23,103,103,23,23,23,23,146,23,213}, +#line 175 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str111,144,24,102,102,24,174,24,100,100,24,24,24,24,174,24,199}, +#line 38 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str112,7,27,37,37,__PNR_alarm,__PNR_alarm,27,37,37,27,27,27,27,__PNR_alarm,27,27}, +#line 509 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str113,478,166,__PNR_vm86,__PNR_vm86,__PNR_vm86,__PNR_vm86,113,__PNR_vm86,__PNR_vm86,__PNR_vm86,__PNR_vm86,113,113,__PNR_vm86,__PNR_vm86,__PNR_vm86}, +#line 54 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str114,23,15,90,90,15,__PNR_chmod,15,88,88,15,15,15,15,__PNR_chmod,15,15}, +#line 362 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str115,331,159,146,146,159,125,163,143,143,159,159,159,159,125,159,159}, +#line 430 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str116,399,321,282,282,349,__PNR_signalfd,317,276,280,302,302,305,305,__PNR_signalfd,316,316}, +#line 240 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str117,209,90,9,9,__PNR_mmap,222,90,9,9,90,90,90,90,222,90,90}, +#line 94 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str118,63,307,269,269,334,48,300,259,263,287,287,298,298,48,300,300}, +#line 246 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str119,215,317,279,533,344,239,308,267,271,295,295,301,301,239,310,310}, +#line 346 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str120,315,176,127,522,176,136,196,125,125,176,176,175,175,136,176,176}, +#line 50 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str121,19,451,451,451,451,451,451,451,451,451,451,451,451,451,451,451}, +#line 278 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str122,247,5,2,2,5,__PNR_open,5,2,2,5,5,5,5,__PNR_open,5,5}, +#line 274 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str123,243,84,__PNR_oldlstat,__PNR_oldlstat,__PNR_oldlstat,__PNR_oldlstat,__PNR_oldlstat,__PNR_oldlstat,__PNR_oldlstat,__PNR_oldlstat,__PNR_oldlstat,84,84,__PNR_oldlstat,__PNR_oldlstat,__PNR_oldlstat}, +#line 248 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str124,217,56,__PNR_mpx,__PNR_mpx,__PNR_mpx,__PNR_mpx,56,__PNR_mpx,__PNR_mpx,__PNR_mpx,__PNR_mpx,56,56,__PNR_mpx,__PNR_mpx,__PNR_mpx}, +#line 88 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str125,57,323,284,284,351,__PNR_eventfd,319,278,282,304,304,307,307,__PNR_eventfd,318,318}, +#line 57 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str126,26,61,161,161,61,51,61,156,156,61,61,61,61,51,61,61}, +#line 155 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str127,124,65,111,111,65,__PNR_getpgrp,65,109,109,65,65,65,65,__PNR_getpgrp,65,65}, +#line 213 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str128,182,303,265,265,330,37,296,255,259,283,283,294,294,37,296,296}, +#line 443 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str129,412,106,4,4,106,__PNR_stat,106,4,4,18,18,106,106,__PNR_stat,106,106}, +#line 83 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str130,52,__PNR_epoll_ctl_old,214,__PNR_epoll_ctl_old,__PNR_epoll_ctl_old,__PNR_epoll_ctl_old,__PNR_epoll_ctl_old,__PNR_epoll_ctl_old,__PNR_epoll_ctl_old,__PNR_epoll_ctl_old,__PNR_epoll_ctl_old,__PNR_epoll_ctl_old,__PNR_epoll_ctl_old,__PNR_epoll_ctl_old,__PNR_epoll_ctl_old,__PNR_epoll_ctl_old}, +#line 286 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str131,255,__PNR_pciconfig_write,__PNR_pciconfig_write,__PNR_pciconfig_write,273,__PNR_pciconfig_write,__PNR_pciconfig_write,__PNR_pciconfig_write,__PNR_pciconfig_write,__PNR_pciconfig_write,__PNR_pciconfig_write,199,199,__PNR_pciconfig_write,__PNR_pciconfig_write,__PNR_pciconfig_write}, +#line 284 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str132,253,__PNR_pciconfig_iobase,__PNR_pciconfig_iobase,__PNR_pciconfig_iobase,271,__PNR_pciconfig_iobase,__PNR_pciconfig_iobase,__PNR_pciconfig_iobase,__PNR_pciconfig_iobase,__PNR_pciconfig_iobase,__PNR_pciconfig_iobase,200,200,__PNR_pciconfig_iobase,__PNR_pciconfig_iobase,__PNR_pciconfig_iobase}, +#line 285 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str133,254,__PNR_pciconfig_read,__PNR_pciconfig_read,__PNR_pciconfig_read,272,__PNR_pciconfig_read,__PNR_pciconfig_read,__PNR_pciconfig_read,__PNR_pciconfig_read,__PNR_pciconfig_read,__PNR_pciconfig_read,198,198,__PNR_pciconfig_read,__PNR_pciconfig_read,__PNR_pciconfig_read}, +#line 445 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str134,414,99,137,137,99,43,99,134,134,99,99,99,99,43,99,99}, +#line 449 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str135,418,31,__PNR_stty,__PNR_stty,__PNR_stty,__PNR_stty,31,__PNR_stty,__PNR_stty,__PNR_stty,__PNR_stty,31,31,__PNR_stty,__PNR_stty,__PNR_stty}, +#line 178 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str136,147,32,__PNR_gtty,__PNR_gtty,__PNR_gtty,__PNR_gtty,32,__PNR_gtty,__PNR_gtty,__PNR_gtty,__PNR_gtty,32,32,__PNR_gtty,__PNR_gtty,__PNR_gtty}, +#line 464 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str137,433,135,139,139,135,__PNR_sysfs,135,136,136,135,135,135,135,__PNR_sysfs,135,135}, +#line 51 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str138,20,184,125,125,184,90,204,123,123,106,106,183,183,90,184,184}, +#line 39 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str139,8,384,158,158,__PNR_arch_prctl,__PNR_arch_prctl,__PNR_arch_prctl,__PNR_arch_prctl,__PNR_arch_prctl,__PNR_arch_prctl,__PNR_arch_prctl,__PNR_arch_prctl,__PNR_arch_prctl,__PNR_arch_prctl,__PNR_arch_prctl,__PNR_arch_prctl}, +#line 299 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str140,268,309,271,271,336,73,302,261,265,274,274,281,281,73,302,302}, +#line 457 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str141,426,36,162,162,36,81,36,157,157,36,36,36,36,81,36,36}, +#line 48 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str142,17,__PNR_cachectl,__PNR_cachectl,__PNR_cachectl,__PNR_cachectl,__PNR_cachectl,148,198,198,__PNR_cachectl,__PNR_cachectl,__PNR_cachectl,__PNR_cachectl,__PNR_cachectl,__PNR_cachectl,__PNR_cachectl}, +#line 429 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str143,398,48,__PNR_signal,__PNR_signal,__PNR_signal,__PNR_signal,48,__PNR_signal,__PNR_signal,48,48,48,48,__PNR_signal,48,48}, +#line 172 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str144,141,224,186,186,224,178,222,178,178,206,206,207,207,178,236,236}, +#line 460 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str145,429,344,306,306,373,267,342,301,306,327,327,348,348,267,338,338}, +#line 98 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str146,67,324,285,285,352,47,320,279,283,305,305,309,309,47,314,314}, +#line 345 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str147,314,174,13,512,174,134,194,13,13,174,174,173,173,134,174,174}, +#line 438 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str148,407,360,53,53,288,199,184,52,52,56,56,333,333,199,360,360}, +#line 144 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str149,113,49,107,107,49,175,49,105,105,49,49,49,49,175,49,201}, +#line 389 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str150,358,138,122,122,138,151,138,120,120,138,138,138,138,151,138,215}, +#line 408 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str151,377,70,113,113,70,145,70,111,111,70,70,70,70,145,70,203}, +#line 103 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str152,72,306,268,268,333,53,299,258,262,286,286,297,297,53,299,299}, +#line 395 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str153,364,74,170,170,74,161,74,165,165,74,74,74,74,161,74,74}, +#line 406 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str154,375,164,117,117,164,147,185,115,115,164,164,164,164,147,164,208}, +#line 163 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str155,132,165,118,118,165,148,186,116,116,165,165,165,165,148,165,209}, +#line 291 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str156,260,424,424,424,424,424,424,424,424,424,424,424,424,424,424,424}, +#line 290 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str157,259,434,434,434,434,434,434,434,434,434,434,434,434,434,434,434}, +#line 350 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str158,319,179,130,130,179,133,199,128,128,179,179,178,178,133,179,179}, +#line 69 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str159,38,435,435,435,435,435,435,435,435,435,435,435,435,435,435,435}, +#line 77 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str160,46,41,32,32,41,23,41,31,31,41,41,41,41,23,41,41}, +#line 423 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str161,392,396,31,31,308,195,396,30,30,195,195,396,396,195,396,396}, +#line 367 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str162,336,241,203,203,241,122,239,195,195,211,211,222,222,122,239,239}, +#line 359 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str163,328,242,204,204,242,123,240,196,196,212,212,223,223,123,240,240}, +#line 371 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str164,340,158,24,24,158,124,162,23,23,158,158,158,158,124,158,158}, +#line 386 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str165,355,121,171,171,121,162,121,166,166,121,121,121,121,162,121,121}, +#line 82 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str166,51,255,233,233,251,21,249,208,208,225,225,237,237,21,250,250}, +#line 425 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str167,394,395,29,29,307,194,395,28,28,194,194,395,395,194,395,395}, +#line 405 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str168,374,210,__PNR_setresgid32,__PNR_setresgid32,210,__PNR_setresgid32,__PNR_setresgid32,__PNR_setresgid32,__PNR_setresgid32,__PNR_setresgid32,__PNR_setresgid32,__PNR_setresgid32,__PNR_setresgid32,__PNR_setresgid32,210,__PNR_setresgid32}, +#line 162 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str169,131,211,__PNR_getresgid32,__PNR_getresgid32,211,__PNR_getresgid32,__PNR_getresgid32,__PNR_getresgid32,__PNR_getresgid32,__PNR_getresgid32,__PNR_getresgid32,__PNR_getresgid32,__PNR_getresgid32,__PNR_getresgid32,211,__PNR_getresgid32}, +#line 466 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str170,435,103,103,103,103,116,103,101,101,103,103,103,103,116,103,103}, +#line 342 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str171,311,40,84,84,40,__PNR_rmdir,40,82,82,40,40,40,40,__PNR_rmdir,40,40}, +#line 160 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str172,129,355,318,318,384,278,353,313,317,339,339,359,359,278,349,349}, +#line 235 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str173,204,14,133,133,14,__PNR_mknod,14,131,131,14,14,14,14,__PNR_mknod,14,14}, +#line 510 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str174,479,113,__PNR_vm86old,__PNR_vm86old,__PNR_vm86old,__PNR_vm86old,__PNR_vm86old,__PNR_vm86old,__PNR_vm86old,__PNR_vm86old,__PNR_vm86old,__PNR_vm86old,__PNR_vm86old,__PNR_vm86old,__PNR_vm86old,__PNR_vm86old}, +#line 296 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str175,265,382,331,331,396,290,365,325,329,353,353,385,385,290,386,386}, +#line 249 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str176,218,282,245,245,279,185,276,235,239,234,234,267,267,185,276,276}, +#line 115 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str177,84,2,57,57,2,__PNR_fork,2,56,56,2,2,2,2,__PNR_fork,2,2}, +#line 71 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str178,40,436,436,436,436,436,436,436,436,436,436,436,436,436,436,436}, +#line 205 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str179,174,37,62,62,37,129,37,60,60,37,37,37,37,129,37,37}, +#line 500 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str180,469,__PNR_usr26,__PNR_usr26,__PNR_usr26,983043,__PNR_usr26,__PNR_usr26,__PNR_usr26,__PNR_usr26,__PNR_usr26,__PNR_usr26,__PNR_usr26,__PNR_usr26,__PNR_usr26,__PNR_usr26,__PNR_usr26}, +#line 439 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str181,408,313,275,275,340,76,304,263,267,291,291,283,283,76,306,306}, +#line 417 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str182,386,__PNR_set_tls,__PNR_set_tls,__PNR_set_tls,983045,__PNR_set_tls,__PNR_set_tls,__PNR_set_tls,__PNR_set_tls,__PNR_set_tls,__PNR_set_tls,__PNR_set_tls,__PNR_set_tls,__PNR_set_tls,__PNR_set_tls,__PNR_set_tls}, +#line 174 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str183,143,__PNR_get_tls,__PNR_get_tls,__PNR_get_tls,983046,__PNR_get_tls,__PNR_get_tls,__PNR_get_tls,__PNR_get_tls,__PNR_get_tls,__PNR_get_tls,__PNR_get_tls,__PNR_get_tls,__PNR_get_tls,__PNR_get_tls,__PNR_get_tls}, +#line 187 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str184,156,246,207,207,244,1,242,201,201,216,216,228,228,1,244,244}, +#line 34 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str185,3,51,163,163,51,89,51,158,158,51,51,51,51,89,51,51}, +#line 396 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str186,365,104,38,38,104,103,104,36,36,104,104,104,104,103,104,104}, +#line 150 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str187,119,105,36,36,105,102,105,35,35,105,105,105,105,102,105,105}, +#line 269 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str188,238,__PNR_newfstatat,262,262,__PNR_newfstatat,79,__PNR_newfstatat,252,256,__PNR_newfstatat,__PNR_newfstatat,__PNR_newfstatat,291,79,__PNR_newfstatat,293}, +#line 60 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str189,29,266,229,229,264,114,264,223,227,257,257,247,247,114,261,261}, +#line 66 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str190,35,264,227,227,262,112,262,221,225,255,255,245,245,112,259,259}, +#line 62 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str191,31,265,228,228,263,113,263,222,226,256,256,246,246,113,260,260}, +#line 437 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str192,406,102,__PNR_socketcall,__PNR_socketcall,__PNR_socketcall,__PNR_socketcall,102,__PNR_socketcall,__PNR_socketcall,__PNR_socketcall,__PNR_socketcall,102,102,__PNR_socketcall,102,102}, +#line 202 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str193,171,__PNR_kexec_file_load,320,320,401,294,__PNR_kexec_file_load,__PNR_kexec_file_load,__PNR_kexec_file_load,355,355,382,382,294,381,381}, +#line 257 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str194,226,163,25,25,163,216,167,24,24,163,163,163,163,216,163,163}, +#line 112 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str195,81,350,313,313,379,273,348,307,312,333,333,353,353,273,344,344}, +#line 347 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str196,316,175,14,14,175,135,195,14,14,175,175,174,174,135,175,175}, +#line 458 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str197,427,314,277,277,__PNR_sync_file_range,84,305,264,268,292,292,__PNR_sync_file_range,__PNR_sync_file_range,84,307,307}, +#line 113 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str198,82,234,196,196,234,13,232,188,188,246,246,217,217,13,232,232}, +#line 167 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str199,136,77,98,98,77,165,77,96,96,77,77,77,77,165,77,77}, +#line 190 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str200,159,385,333,333,399,292,368,328,332,350,350,388,388,292,382,382}, +#line 90 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str201,59,11,59,520,11,221,11,57,57,11,11,11,11,221,11,11}, +#line 413 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str202,382,366,54,541,294,208,181,53,53,181,181,339,339,208,366,366}, +#line 170 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str203,139,365,55,542,295,209,173,54,54,182,182,340,340,209,365,365}, +#line 323 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str204,292,225,187,187,225,213,223,179,179,207,207,191,191,213,222,222}, +#line 378 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str205,347,__PNR_semtimedop,220,220,312,192,__PNR_semtimedop,214,215,228,228,__PNR_semtimedop,392,192,__PNR_semtimedop,392}, +#line 212 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str206,181,9,86,86,9,__PNR_link,9,84,84,9,9,9,9,__PNR_link,9,9}, +#line 153 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str207,122,368,52,52,287,205,171,51,51,53,53,332,332,205,368,368}, +#line 503 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str208,472,30,132,132,__PNR_utime,__PNR_utime,30,130,130,30,30,30,30,__PNR_utime,30,30}, +#line 420 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str209,389,226,188,188,226,5,224,180,180,238,238,209,209,5,224,224}, +#line 177 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str210,146,229,191,191,229,8,227,183,183,241,241,212,212,8,227,227}, +#line 506 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str211,475,271,235,235,269,__PNR_utimes,267,226,230,336,336,251,251,__PNR_utimes,313,313}, +#line 327 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str212,296,145,19,515,145,65,145,18,18,145,145,145,145,65,145,145}, +#line 139 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str213,108,183,79,79,183,17,203,77,77,110,110,182,182,17,183,183}, +#line 108 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str214,77,55,72,72,55,25,55,70,70,55,55,55,55,25,55,55}, +#line 204 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str215,173,288,250,250,311,219,282,241,245,266,266,271,271,219,280,280}, +#line 415 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str216,384,258,218,218,256,96,252,212,213,237,237,232,232,96,252,252}, +#line 120 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str217,89,430,430,430,430,430,430,430,430,430,430,430,430,430,430,430}, +#line 197 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str218,166,426,426,426,426,426,426,426,426,426,426,426,426,426,426,426}, +#line 195 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str219,164,245,206,543,243,0,241,200,200,215,215,227,227,0,243,243}, +#line 188 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str220,157,247,208,208,245,4,243,202,202,217,217,229,229,4,245,245}, +#line 198 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str221,167,427,427,427,427,427,427,427,427,427,427,427,427,427,427,427}, +#line 218 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str222,187,53,__PNR_lock,__PNR_lock,__PNR_lock,__PNR_lock,53,__PNR_lock,__PNR_lock,__PNR_lock,__PNR_lock,53,53,__PNR_lock,__PNR_lock,__PNR_lock}, +#line 270 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str223,239,142,__PNR__newselect,__PNR__newselect,142,__PNR__newselect,142,22,22,142,142,142,142,__PNR__newselect,142,__PNR__newselect}, +#line 388 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str224,357,216,__PNR_setfsgid32,__PNR_setfsgid32,216,__PNR_setfsgid32,__PNR_setfsgid32,__PNR_setfsgid32,__PNR_setfsgid32,__PNR_setfsgid32,__PNR_setfsgid32,__PNR_setfsgid32,__PNR_setfsgid32,__PNR_setfsgid32,216,__PNR_setfsgid32}, +#line 403 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str225,372,204,__PNR_setregid32,__PNR_setregid32,204,__PNR_setregid32,__PNR_setregid32,__PNR_setregid32,__PNR_setregid32,__PNR_setregid32,__PNR_setregid32,__PNR_setregid32,__PNR_setregid32,__PNR_setregid32,204,__PNR_setregid32}, +#line 512 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str226,481,273,236,__PNR_vserver,313,__PNR_vserver,277,236,240,__PNR_vserver,__PNR_vserver,__PNR_vserver,__PNR_vserver,__PNR_vserver,__PNR_vserver,__PNR_vserver}, +#line 485 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str227,454,238,200,200,238,130,236,192,192,208,208,208,208,130,237,237}, +#line 483 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str228,452,409,__PNR_timer_settime64,__PNR_timer_settime64,409,__PNR_timer_settime64,409,__PNR_timer_settime64,409,409,__PNR_timer_settime64,409,__PNR_timer_settime64,__PNR_timer_settime64,409,__PNR_timer_settime64}, +#line 481 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str229,450,408,__PNR_timer_gettime64,__PNR_timer_gettime64,408,__PNR_timer_gettime64,408,__PNR_timer_gettime64,408,408,__PNR_timer_gettime64,408,__PNR_timer_gettime64,__PNR_timer_gettime64,408,__PNR_timer_gettime64}, +#line 478 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str230,447,411,__PNR_timerfd_settime64,__PNR_timerfd_settime64,411,__PNR_timerfd_settime64,411,__PNR_timerfd_settime64,411,411,__PNR_timerfd_settime64,411,__PNR_timerfd_settime64,__PNR_timerfd_settime64,411,__PNR_timerfd_settime64}, +#line 476 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str231,445,410,__PNR_timerfd_gettime64,__PNR_timerfd_gettime64,410,__PNR_timerfd_gettime64,410,__PNR_timerfd_gettime64,410,410,__PNR_timerfd_gettime64,410,__PNR_timerfd_gettime64,__PNR_timerfd_gettime64,410,__PNR_timerfd_gettime64}, +#line 186 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str232,155,54,16,514,54,29,54,15,15,54,54,54,54,29,54,54}, +#line 260 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str233,229,401,70,70,302,188,401,68,68,189,189,401,401,188,401,401}, +#line 92 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str234,61,1,60,60,1,93,1,58,58,1,1,1,1,93,1,1}, +#line 333 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str235,302,372,47,519,297,212,177,46,46,184,184,342,342,212,372,372}, +#line 201 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str236,170,349,312,312,378,272,347,306,311,332,332,354,354,272,343,343}, +#line 398 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str237,367,450,450,450,450,450,450,450,450,450,450,450,450,450,450,450}, +#line 432 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str238,401,73,__PNR_sigpending,__PNR_sigpending,73,__PNR_sigpending,73,__PNR_sigpending,__PNR_sigpending,73,73,73,73,__PNR_sigpending,73,73}, +#line 185 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str239,154,249,210,210,247,3,245,204,204,219,219,231,231,3,247,247}, +#line 366 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str240,335,423,__PNR_sched_rr_get_interval_time64,__PNR_sched_rr_get_interval_time64,423,__PNR_sched_rr_get_interval_time64,423,__PNR_sched_rr_get_interval_time64,423,423,__PNR_sched_rr_get_interval_time64,423,__PNR_sched_rr_get_interval_time64,__PNR_sched_rr_get_interval_time64,423,__PNR_sched_rr_get_interval_time64}, +#line 297 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str241,266,380,329,329,394,288,363,323,327,351,351,386,386,288,384,384}, +#line 271 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str242,240,169,180,__PNR_nfsservctl,169,42,189,173,173,__PNR_nfsservctl,__PNR_nfsservctl,168,168,42,169,169}, +#line 236 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str243,205,297,259,259,324,33,290,249,253,277,277,288,288,33,290,290}, +#line 511 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str244,480,316,278,532,343,75,307,266,270,294,294,285,285,75,309,309}, +#line 216 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str245,185,233,195,195,233,12,231,187,187,245,245,216,216,12,231,231}, +#line 267 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str246,236,341,303,303,370,264,339,298,303,325,325,345,345,264,335,335}, +#line 353 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str247,322,335,297,536,363,240,332,291,295,317,317,322,322,240,330,330}, +#line 348 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str248,317,178,129,524,178,138,198,127,127,178,178,177,177,138,178,178}, +#line 99 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str249,68,338,300,300,367,262,336,295,300,322,322,323,323,262,332,332}, +#line 199 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str250,168,425,425,425,425,425,425,425,425,425,425,425,425,425,425,425}, +#line 352 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str251,321,421,__PNR_rt_sigtimedwait_time64,__PNR_rt_sigtimedwait_time64,421,__PNR_rt_sigtimedwait_time64,421,__PNR_rt_sigtimedwait_time64,421,421,__PNR_rt_sigtimedwait_time64,421,__PNR_rt_sigtimedwait_time64,__PNR_rt_sigtimedwait_time64,421,__PNR_rt_sigtimedwait_time64}, +#line 301 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str252,270,172,157,157,172,167,192,153,153,172,172,171,171,167,172,172}, +#line 440 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str253,409,__PNR_spu_create,__PNR_spu_create,__PNR_spu_create,__PNR_spu_create,__PNR_spu_create,__PNR_spu_create,__PNR_spu_create,__PNR_spu_create,__PNR_spu_create,__PNR_spu_create,279,279,__PNR_spu_create,__PNR_spu_create,__PNR_spu_create}, +#line 119 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str254,88,432,432,432,432,432,432,432,432,432,432,432,432,432,432,432}, +#line 331 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str255,300,337,299,537,365,243,335,294,298,319,319,343,343,243,357,357}, +#line 53 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str256,22,12,80,80,12,49,12,78,78,12,12,12,12,49,12,12}, +#line 129 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str257,98,93,77,77,93,46,93,75,75,93,93,93,93,46,93,93}, +#line 401 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str258,370,97,141,141,97,140,97,138,138,97,97,97,97,140,97,97}, +#line 159 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str259,128,96,140,140,96,141,96,137,137,96,96,96,96,141,96,96}, +#line 340 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str260,309,0,219,219,0,128,253,213,214,0,0,0,0,128,7,7}, +#line 467 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str261,436,__PNR_sysmips,__PNR_sysmips,__PNR_sysmips,__PNR_sysmips,__PNR_sysmips,149,199,199,__PNR_sysmips,__PNR_sysmips,__PNR_sysmips,__PNR_sysmips,__PNR_sysmips,__PNR_sysmips,__PNR_sysmips}, +#line 254 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str262,223,279,242,242,276,182,273,232,236,231,231,264,264,182,273,273}, +#line 315 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str263,284,189,182,182,__PNR_putpmsg,__PNR_putpmsg,209,175,175,__PNR_putpmsg,__PNR_putpmsg,188,188,__PNR_putpmsg,189,189}, +#line 122 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str264,91,108,5,5,108,80,108,5,5,28,28,108,108,80,108,108}, +#line 43 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str265,12,361,49,49,282,200,169,48,48,22,22,327,327,200,361,361}, +#line 490 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str266,459,58,__PNR_ulimit,__PNR_ulimit,__PNR_ulimit,__PNR_ulimit,58,__PNR_ulimit,__PNR_ulimit,__PNR_ulimit,__PNR_ulimit,58,58,__PNR_ulimit,__PNR_ulimit,__PNR_ulimit}, +#line 435 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str267,404,72,__PNR_sigsuspend,__PNR_sigsuspend,72,__PNR_sigsuspend,72,__PNR_sigsuspend,__PNR_sigsuspend,__PNR_sigsuspend,__PNR_sigsuspend,72,72,__PNR_sigsuspend,72,72}, +#line 252 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str268,221,280,243,243,277,183,274,233,237,232,232,265,265,183,274,274}, +#line 382 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str269,351,239,__PNR_sendfile64,__PNR_sendfile64,239,__PNR_sendfile64,237,__PNR_sendfile64,219,209,209,226,__PNR_sendfile64,__PNR_sendfile64,223,__PNR_sendfile64}, +#line 203 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str270,172,283,246,528,347,104,311,270,274,300,300,268,268,104,277,277}, +#line 125 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str271,94,100,138,138,100,44,100,135,135,100,100,100,100,44,100,100}, +#line 268 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str272,237,162,35,35,162,101,166,34,34,162,162,162,162,101,162,162}, +#line 74 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str273,43,8,85,85,8,__PNR_creat,8,83,83,8,8,8,8,__PNR_creat,8,8}, +#line 308 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str274,277,347,310,539,376,270,345,304,309,330,330,351,351,270,340,340}, +#line 309 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str275,278,348,311,540,377,271,346,305,310,331,331,352,352,271,341,341}, +#line 313 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str276,282,413,__PNR_pselect6_time64,__PNR_pselect6_time64,413,__PNR_pselect6_time64,413,__PNR_pselect6_time64,413,413,__PNR_pselect6_time64,413,__PNR_pselect6_time64,__PNR_pselect6_time64,413,__PNR_pselect6_time64}, +#line 354 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str277,323,__PNR_s390_guarded_storage,__PNR_s390_guarded_storage,__PNR_s390_guarded_storage,__PNR_s390_guarded_storage,__PNR_s390_guarded_storage,__PNR_s390_guarded_storage,__PNR_s390_guarded_storage,__PNR_s390_guarded_storage,__PNR_s390_guarded_storage,__PNR_s390_guarded_storage,__PNR_s390_guarded_storage,__PNR_s390_guarded_storage,__PNR_s390_guarded_storage,378,378}, +#line 330 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str278,299,371,45,517,292,207,176,44,44,123,123,337,337,207,371,371}, +#line 91 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str279,60,358,322,545,387,281,356,316,320,342,342,362,362,281,354,354}, +#line 469 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str280,438,270,234,234,268,131,266,225,229,259,259,250,250,131,241,241}, +#line 336 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str281,305,38,82,82,38,__PNR_rename,38,80,80,38,38,38,38,__PNR_rename,38,38}, +#line 44 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str282,13,357,321,321,386,280,355,315,319,341,341,361,361,280,351,351}, +#line 219 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str283,188,253,212,212,249,18,247,206,206,223,223,235,235,18,110,110}, +#line 95 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str284,64,439,439,439,439,439,439,439,439,439,439,439,439,439,439,439}, +#line 497 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str285,466,310,272,272,337,97,303,262,266,288,288,282,282,97,303,303}, +#line 393 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str286,362,81,116,116,81,159,81,114,114,81,81,81,81,159,81,206}, +#line 148 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str287,117,80,115,115,80,158,80,113,113,80,80,80,80,158,80,205}, +#line 245 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str288,214,429,429,429,429,429,429,429,429,429,429,429,429,429,429,429}, +#line 225 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str289,194,219,28,28,220,233,218,27,27,119,119,205,205,233,219,219}, +#line 227 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str290,196,274,237,237,319,235,268,227,231,260,260,259,259,235,268,268}, +#line 494 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str291,463,122,63,63,122,160,122,61,61,59,59,122,122,160,122,122}, +#line 357 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str292,326,__PNR_s390_runtime_instr,__PNR_s390_runtime_instr,__PNR_s390_runtime_instr,__PNR_s390_runtime_instr,__PNR_s390_runtime_instr,__PNR_s390_runtime_instr,__PNR_s390_runtime_instr,__PNR_s390_runtime_instr,__PNR_s390_runtime_instr,__PNR_s390_runtime_instr,__PNR_s390_runtime_instr,__PNR_s390_runtime_instr,__PNR_s390_runtime_instr,342,342}, +#line 314 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str293,283,26,101,521,26,117,26,99,99,26,26,26,26,117,26,26}, +#line 487 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str294,456,193,__PNR_truncate64,__PNR_truncate64,193,__PNR_truncate64,211,__PNR_truncate64,__PNR_truncate64,199,199,193,__PNR_truncate64,__PNR_truncate64,193,__PNR_truncate64}, +#line 251 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str295,220,277,240,240,274,180,271,230,234,229,229,262,262,180,271,271}, +#line 141 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str296,110,220,217,217,217,61,219,308,299,201,201,202,202,61,220,220}, +#line 223 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str297,192,107,6,6,107,__PNR_lstat,107,6,6,84,84,107,107,__PNR_lstat,107,107}, +#line 169 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str298,138,367,51,51,286,204,172,50,50,44,44,331,331,204,367,367}, +#line 358 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str299,327,__PNR_s390_sthyi,__PNR_s390_sthyi,__PNR_s390_sthyi,__PNR_s390_sthyi,__PNR_s390_sthyi,__PNR_s390_sthyi,__PNR_s390_sthyi,__PNR_s390_sthyi,__PNR_s390_sthyi,__PNR_s390_sthyi,__PNR_s390_sthyi,__PNR_s390_sthyi,__PNR_s390_sthyi,380,380}, +#line 452 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str300,421,115,168,168,115,225,115,163,163,115,115,115,115,225,115,115}, +#line 287 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str301,256,336,298,298,364,241,333,292,296,318,318,319,319,241,331,331}, +#line 206 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str302,175,445,445,445,445,445,445,445,445,445,445,445,445,445,445,445}, +#line 208 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str303,177,446,446,446,446,446,446,446,446,446,446,446,446,446,446,446}, +#line 207 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str304,176,444,444,444,444,444,444,444,444,444,444,444,444,444,444,444}, +#line 450 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str305,419,__PNR_subpage_prot,__PNR_subpage_prot,__PNR_subpage_prot,__PNR_subpage_prot,__PNR_subpage_prot,__PNR_subpage_prot,__PNR_subpage_prot,__PNR_subpage_prot,__PNR_subpage_prot,__PNR_subpage_prot,310,310,__PNR_subpage_prot,__PNR_subpage_prot,__PNR_subpage_prot}, +#line 75 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str306,44,127,174,__PNR_create_module,__PNR_create_module,__PNR_create_module,127,167,167,__PNR_create_module,__PNR_create_module,127,127,__PNR_create_module,127,127}, +#line 335 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str307,304,235,197,197,235,14,233,189,189,247,247,218,218,14,233,233}, +#line 434 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str308,403,119,__PNR_sigreturn,__PNR_sigreturn,119,__PNR_sigreturn,119,__PNR_sigreturn,__PNR_sigreturn,__PNR_sigreturn,__PNR_sigreturn,119,119,__PNR_sigreturn,119,119}, +#line 433 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str309,402,126,__PNR_sigprocmask,__PNR_sigprocmask,126,__PNR_sigprocmask,126,__PNR_sigprocmask,__PNR_sigprocmask,126,126,126,126,__PNR_sigprocmask,126,126}, +#line 118 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str310,87,228,190,190,228,7,226,182,182,240,240,211,211,7,226,226}, +#line 111 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str311,80,231,193,193,231,10,229,185,185,243,243,214,214,10,229,229}, +#line 277 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str312,246,109,__PNR_olduname,__PNR_olduname,__PNR_olduname,__PNR_olduname,__PNR_olduname,__PNR_olduname,__PNR_olduname,__PNR_olduname,__PNR_olduname,109,109,__PNR_olduname,__PNR_olduname,__PNR_olduname}, +#line 341 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str313,310,__PNR_riscv_flush_icache,__PNR_riscv_flush_icache,__PNR_riscv_flush_icache,__PNR_riscv_flush_icache,__PNR_riscv_flush_icache,__PNR_riscv_flush_icache,__PNR_riscv_flush_icache,__PNR_riscv_flush_icache,__PNR_riscv_flush_icache,__PNR_riscv_flush_icache,__PNR_riscv_flush_icache,__PNR_riscv_flush_icache,259,__PNR_riscv_flush_icache,__PNR_riscv_flush_icache}, +#line 138 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str314,107,318,309,309,345,168,312,271,275,296,296,302,302,168,311,311}, +#line 221 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str315,190,19,8,8,19,62,19,8,8,19,19,19,19,62,19,19}, +#line 407 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str316,376,208,__PNR_setresuid32,__PNR_setresuid32,208,__PNR_setresuid32,__PNR_setresuid32,__PNR_setresuid32,__PNR_setresuid32,__PNR_setresuid32,__PNR_setresuid32,__PNR_setresuid32,__PNR_setresuid32,__PNR_setresuid32,208,__PNR_setresuid32}, +#line 164 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str317,133,209,__PNR_getresuid32,__PNR_getresuid32,209,__PNR_getresuid32,__PNR_getresuid32,__PNR_getresuid32,__PNR_getresuid32,__PNR_getresuid32,__PNR_getresuid32,__PNR_getresuid32,__PNR_getresuid32,__PNR_getresuid32,209,__PNR_getresuid32}, +#line 233 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str318,202,39,83,83,39,__PNR_mkdir,39,81,81,39,39,39,39,__PNR_mkdir,39,39}, +#line 114 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str319,83,143,73,73,143,32,143,71,71,143,143,143,143,32,143,143}, +#line 488 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str320,457,__PNR_tuxcall,184,184,__PNR_tuxcall,__PNR_tuxcall,__PNR_tuxcall,__PNR_tuxcall,__PNR_tuxcall,__PNR_tuxcall,__PNR_tuxcall,225,225,__PNR_tuxcall,__PNR_tuxcall,__PNR_tuxcall}, +#line 329 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str321,298,__PNR_recv,__PNR_recv,__PNR_recv,291,__PNR_recv,175,__PNR_recv,__PNR_recv,98,98,336,336,__PNR_recv,__PNR_recv,__PNR_recv}, +#line 461 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str322,430,__PNR_syscall,__PNR_syscall,__PNR_syscall,__PNR_syscall,__PNR_syscall,0,__PNR_syscall,__PNR_syscall,__PNR_syscall,__PNR_syscall,__PNR_syscall,__PNR_syscall,__PNR_syscall,__PNR_syscall,__PNR_syscall}, +#line 217 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str323,186,140,__PNR__llseek,__PNR__llseek,140,__PNR__llseek,140,__PNR__llseek,__PNR__llseek,140,140,140,140,__PNR__llseek,140,__PNR__llseek}, +#line 326 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str324,295,305,267,267,332,78,298,257,261,285,285,296,296,78,298,298}, +#line 132 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str325,101,456,456,456,456,456,456,456,456,456,456,456,456,456,456,456}, +#line 295 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str326,264,381,330,330,395,289,364,324,328,352,352,384,384,289,385,385}, +#line 237 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str327,206,150,149,149,150,228,154,146,146,150,150,150,150,228,150,150}, +#line 416 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str328,385,79,164,164,79,170,79,159,159,79,79,79,79,170,79,79}, +#line 173 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str329,142,78,96,96,78,169,78,94,94,78,78,78,78,169,78,78}, +#line 447 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str330,416,383,332,332,397,291,366,326,330,349,349,383,383,291,379,379}, +#line 55 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str331,24,182,92,92,182,__PNR_chown,202,90,90,180,180,181,181,__PNR_chown,182,212}, +#line 131 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str332,100,240,202,202,240,98,238,194,194,210,210,221,221,98,238,238}, +#line 214 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str333,183,363,50,50,284,201,174,49,49,32,32,329,329,201,363,363}, +#line 49 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str334,18,__PNR_cacheflush,__PNR_cacheflush,__PNR_cacheflush,983042,__PNR_cacheflush,147,197,197,356,356,__PNR_cacheflush,__PNR_cacheflush,__PNR_cacheflush,__PNR_cacheflush,__PNR_cacheflush}, +#line 337 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str335,306,302,264,264,329,38,295,254,258,282,282,293,293,__PNR_renameat,295,295}, +#line 492 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str336,461,22,__PNR_umount,__PNR_umount,__PNR_umount,__PNR_umount,22,__PNR_umount,__PNR_umount,__PNR_umount,__PNR_umount,22,22,__PNR_umount,22,22}, +#line 266 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str337,235,91,11,11,91,215,91,11,11,91,91,91,91,215,91,91}, +#line 422 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str338,391,397,30,30,305,196,397,29,29,192,192,397,397,196,397,397}, +#line 300 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str339,269,414,__PNR_ppoll_time64,__PNR_ppoll_time64,414,__PNR_ppoll_time64,414,__PNR_ppoll_time64,414,414,__PNR_ppoll_time64,414,__PNR_ppoll_time64,__PNR_ppoll_time64,414,__PNR_ppoll_time64}, +#line 334 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str340,303,257,216,216,253,234,251,210,210,227,227,239,239,234,267,267}, +#line 293 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str341,262,331,293,293,359,59,328,287,291,313,313,317,317,59,325,325}, +#line 222 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str342,191,227,189,189,227,6,225,181,181,239,239,210,210,6,225,225}, +#line 211 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str343,180,230,192,192,230,9,228,184,184,242,242,213,213,9,228,228}, +#line 78 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str344,47,63,33,33,63,__PNR_dup2,63,32,32,63,63,63,63,__PNR_dup2,63,63}, +#line 215 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str345,184,232,194,194,232,11,230,186,186,244,244,215,215,11,230,230}, +#line 489 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str346,458,191,__PNR_ugetrlimit,__PNR_ugetrlimit,191,__PNR_ugetrlimit,__PNR_ugetrlimit,__PNR_ugetrlimit,__PNR_ugetrlimit,__PNR_ugetrlimit,__PNR_ugetrlimit,190,190,__PNR_ugetrlimit,191,__PNR_ugetrlimit}, +#line 516 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str347,485,4,1,1,4,64,4,1,1,4,4,4,4,64,4,4}, +#line 504 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str348,473,320,280,280,348,88,316,275,279,301,301,304,304,88,315,315}, +#line 414 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str349,383,243,205,__PNR_set_thread_area,__PNR_set_thread_area,__PNR_set_thread_area,283,242,246,__PNR_set_thread_area,__PNR_set_thread_area,__PNR_set_thread_area,__PNR_set_thread_area,__PNR_set_thread_area,__PNR_set_thread_area,__PNR_set_thread_area}, +#line 171 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str350,140,244,211,__PNR_get_thread_area,__PNR_get_thread_area,__PNR_get_thread_area,__PNR_get_thread_area,__PNR_get_thread_area,__PNR_get_thread_area,__PNR_get_thread_area,__PNR_get_thread_area,__PNR_get_thread_area,__PNR_get_thread_area,__PNR_get_thread_area,__PNR_get_thread_area,__PNR_get_thread_area}, +#line 86 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str351,55,256,232,232,252,__PNR_epoll_wait,250,209,209,226,226,238,238,__PNR_epoll_wait,251,251}, +#line 459 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str352,428,__PNR_sync_file_range2,__PNR_sync_file_range2,__PNR_sync_file_range2,__PNR_sync_file_range2,__PNR_sync_file_range2,__PNR_sync_file_range2,__PNR_sync_file_range2,__PNR_sync_file_range2,__PNR_sync_file_range2,__PNR_sync_file_range2,308,308,__PNR_sync_file_range2,__PNR_sync_file_range2,__PNR_sync_file_range2}, +#line 87 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str353,56,__PNR_epoll_wait_old,215,__PNR_epoll_wait_old,__PNR_epoll_wait_old,__PNR_epoll_wait_old,__PNR_epoll_wait_old,__PNR_epoll_wait_old,__PNR_epoll_wait_old,__PNR_epoll_wait_old,__PNR_epoll_wait_old,__PNR_epoll_wait_old,__PNR_epoll_wait_old,__PNR_epoll_wait_old,__PNR_epoll_wait_old,__PNR_epoll_wait_old}, +#line 116 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str354,85,237,199,199,237,16,235,191,191,249,249,220,220,16,235,235}, +#line 390 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str355,359,215,__PNR_setfsuid32,__PNR_setfsuid32,215,__PNR_setfsuid32,__PNR_setfsuid32,__PNR_setfsuid32,__PNR_setfsuid32,__PNR_setfsuid32,__PNR_setfsuid32,__PNR_setfsuid32,__PNR_setfsuid32,__PNR_setfsuid32,215,__PNR_setfsuid32}, +#line 409 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str356,378,203,__PNR_setreuid32,__PNR_setreuid32,203,__PNR_setreuid32,__PNR_setreuid32,__PNR_setreuid32,__PNR_setreuid32,__PNR_setreuid32,__PNR_setreuid32,__PNR_setreuid32,__PNR_setreuid32,__PNR_setreuid32,203,__PNR_setreuid32}, +#line 239 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str357,208,152,151,151,152,230,156,148,148,152,152,152,152,230,152,152}, +#line 288 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str358,257,136,135,135,136,92,136,132,132,136,136,136,136,92,136,136}, +#line 234 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str359,203,296,258,258,323,34,289,248,252,276,276,287,287,34,289,289}, +#line 397 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str360,366,276,238,238,321,237,270,229,233,262,262,261,261,237,270,270}, +#line 152 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str361,121,275,239,239,320,236,269,228,232,261,261,260,260,236,269,269}, +#line 137 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str362,106,299,261,261,326,__PNR_futimesat,292,251,255,279,279,290,290,__PNR_futimesat,292,292}, +#line 107 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str363,76,298,260,260,325,54,291,250,254,278,278,289,289,54,291,291}, +#line 151 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str364,120,130,177,__PNR_get_kernel_syms,__PNR_get_kernel_syms,__PNR_get_kernel_syms,130,170,170,__PNR_get_kernel_syms,__PNR_get_kernel_syms,130,130,__PNR_get_kernel_syms,130,130}, +#line 183 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str365,152,332,294,294,360,26,329,288,292,314,314,318,318,26,324,324}, +#line 182 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str366,151,291,253,253,316,__PNR_inotify_init,284,243,247,269,269,275,275,__PNR_inotify_init,284,284}, +#line 507 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str367,476,190,58,58,190,__PNR_vfork,__PNR_vfork,__PNR_vfork,__PNR_vfork,113,113,189,189,__PNR_vfork,190,190}, +#line 100 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str368,69,339,301,301,368,263,337,296,301,323,323,324,324,263,333,333}, +#line 451 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str369,420,__PNR_swapcontext,__PNR_swapcontext,__PNR_swapcontext,__PNR_swapcontext,__PNR_swapcontext,__PNR_swapcontext,__PNR_swapcontext,__PNR_swapcontext,__PNR_swapcontext,__PNR_swapcontext,249,249,__PNR_swapcontext,__PNR_swapcontext,__PNR_swapcontext}, +#line 242 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str370,211,123,154,154,__PNR_modify_ldt,__PNR_modify_ldt,123,__PNR_modify_ldt,__PNR_modify_ldt,__PNR_modify_ldt,__PNR_modify_ldt,123,123,__PNR_modify_ldt,__PNR_modify_ldt,__PNR_modify_ldt}, +#line 143 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str371,112,202,__PNR_getegid32,__PNR_getegid32,202,__PNR_getegid32,__PNR_getegid32,__PNR_getegid32,__PNR_getegid32,__PNR_getegid32,__PNR_getegid32,__PNR_getegid32,__PNR_getegid32,__PNR_getegid32,202,__PNR_getegid32}, +#line 84 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str372,53,319,281,281,346,22,313,272,276,297,297,303,303,22,312,312}, +#line 499 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str373,468,374,323,323,388,282,357,317,321,344,344,364,364,282,355,355}, +#line 47 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str374,16,45,12,12,45,214,45,12,12,45,45,45,45,214,45,45}, +#line 105 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str375,74,95,93,93,95,55,95,91,91,95,95,95,95,55,95,207}, +#line 379 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str376,348,420,__PNR_semtimedop_time64,__PNR_semtimedop_time64,420,__PNR_semtimedop_time64,420,__PNR_semtimedop_time64,420,420,__PNR_semtimedop_time64,420,__PNR_semtimedop_time64,__PNR_semtimedop_time64,420,__PNR_semtimedop_time64}, +#line 502 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str377,471,62,136,136,62,__PNR_ustat,62,133,133,62,62,62,62,__PNR_ustat,62,62}, +#line 79 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str378,48,330,292,292,358,24,327,286,290,312,312,316,316,24,326,326}, +#line 319 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str379,288,167,178,__PNR_query_module,__PNR_query_module,__PNR_query_module,187,171,171,__PNR_query_module,__PNR_query_module,166,166,__PNR_query_module,167,167}, +#line 180 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str380,149,128,175,175,128,105,128,168,168,128,128,128,128,105,128,128}, +#line 275 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str381,244,59,__PNR_oldolduname,__PNR_oldolduname,__PNR_oldolduname,__PNR_oldolduname,__PNR_oldolduname,__PNR_oldolduname,__PNR_oldolduname,__PNR_oldolduname,__PNR_oldolduname,59,59,__PNR_oldolduname,__PNR_oldolduname,__PNR_oldolduname}, +#line 67 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str382,36,404,__PNR_clock_settime64,__PNR_clock_settime64,404,__PNR_clock_settime64,404,__PNR_clock_settime64,404,404,__PNR_clock_settime64,404,__PNR_clock_settime64,__PNR_clock_settime64,404,__PNR_clock_settime64}, +#line 63 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str383,32,403,__PNR_clock_gettime64,__PNR_clock_gettime64,403,__PNR_clock_gettime64,403,__PNR_clock_gettime64,403,403,__PNR_clock_gettime64,403,__PNR_clock_gettime64,__PNR_clock_gettime64,403,__PNR_clock_gettime64}, +#line 220 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str384,189,236,198,198,236,15,234,190,190,248,248,219,219,15,234,234}, +#line 325 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str385,294,85,89,89,85,__PNR_readlink,85,87,87,85,85,85,85,__PNR_readlink,85,85}, +#line 61 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str386,30,406,__PNR_clock_getres_time64,__PNR_clock_getres_time64,406,__PNR_clock_getres_time64,406,__PNR_clock_getres_time64,406,406,__PNR_clock_getres_time64,406,__PNR_clock_getres_time64,__PNR_clock_getres_time64,406,__PNR_clock_getres_time64}, +#line 508 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str387,477,111,153,153,111,58,111,150,150,111,111,111,111,58,111,111}, +#line 58 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str388,27,343,305,305,372,266,341,300,305,324,324,347,347,266,337,337}, +#line 339 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str389,308,287,249,249,310,218,281,240,244,265,265,270,270,218,279,279}, +#line 465 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str390,434,116,99,99,116,179,116,97,97,116,116,116,116,179,116,116}, +#line 241 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str391,210,192,__PNR_mmap2,__PNR_mmap2,192,__PNR_mmap2,210,__PNR_mmap2,__PNR_mmap2,89,89,192,__PNR_mmap2,__PNR_mmap2,192,__PNR_mmap2}, +#line 36 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str392,5,124,159,159,124,171,124,154,154,124,124,124,124,171,124,124}, +#line 514 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str393,483,284,247,529,280,95,278,237,241,235,235,272,272,95,281,281}, +#line 373 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str394,342,__PNR_security,185,185,__PNR_security,__PNR_security,__PNR_security,__PNR_security,__PNR_security,__PNR_security,__PNR_security,__PNR_security,__PNR_security,__PNR_security,__PNR_security,__PNR_security}, +#line 191 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str395,160,416,__PNR_io_pgetevents_time64,__PNR_io_pgetevents_time64,416,__PNR_io_pgetevents_time64,416,__PNR_io_pgetevents_time64,416,416,__PNR_io_pgetevents_time64,416,__PNR_io_pgetevents_time64,__PNR_io_pgetevents_time64,416,__PNR_io_pgetevents_time64}, +#line 250 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str396,219,281,244,527,278,184,275,234,238,233,233,266,266,184,275,275}, +#line 64 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str397,33,267,230,230,265,115,265,224,228,258,258,248,248,115,262,262}, +#line 491 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str398,460,60,95,95,60,166,60,93,93,60,60,60,60,166,60,60}, +#line 280 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str399,249,437,437,437,437,437,437,437,437,437,437,437,437,437,437,437}, +#line 209 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str400,178,16,94,94,16,__PNR_lchown,16,92,92,16,16,16,16,__PNR_lchown,16,198}, +#line 110 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str401,79,148,75,75,148,83,152,73,73,148,148,148,148,83,148,148}, +#line 93 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str402,62,252,231,231,248,94,246,205,205,222,222,234,234,94,248,248}, +#line 427 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str403,396,67,__PNR_sigaction,__PNR_sigaction,67,__PNR_sigaction,67,__PNR_sigaction,__PNR_sigaction,__PNR_sigaction,__PNR_sigaction,67,67,__PNR_sigaction,67,67}, +#line 121 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str404,90,433,433,433,433,433,433,433,433,433,433,433,433,433,433,433}, +#line 456 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str405,425,304,266,266,331,36,297,256,260,284,284,295,295,36,297,297}, +#line 394 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str406,363,206,__PNR_setgroups32,__PNR_setgroups32,206,__PNR_setgroups32,__PNR_setgroups32,__PNR_setgroups32,__PNR_setgroups32,__PNR_setgroups32,__PNR_setgroups32,__PNR_setgroups32,__PNR_setgroups32,__PNR_setgroups32,206,__PNR_setgroups32}, +#line 149 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str407,118,205,__PNR_getgroups32,__PNR_getgroups32,205,__PNR_getgroups32,__PNR_getgroups32,__PNR_getgroups32,__PNR_getgroups32,__PNR_getgroups32,__PNR_getgroups32,__PNR_getgroups32,__PNR_getgroups32,__PNR_getgroups32,205,__PNR_getgroups32}, +#line 196 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str408,165,248,209,544,246,2,244,203,203,218,218,230,230,2,246,246}, +#line 515 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str409,484,7,__PNR_waitpid,__PNR_waitpid,__PNR_waitpid,__PNR_waitpid,7,__PNR_waitpid,__PNR_waitpid,7,7,7,7,__PNR_waitpid,__PNR_waitpid,__PNR_waitpid}, +#line 453 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str410,422,87,167,167,87,224,87,162,162,87,87,87,87,224,87,87}, +#line 41 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str411,10,__PNR_arm_sync_file_range,__PNR_arm_sync_file_range,__PNR_arm_sync_file_range,341,__PNR_arm_sync_file_range,__PNR_arm_sync_file_range,__PNR_arm_sync_file_range,__PNR_arm_sync_file_range,__PNR_arm_sync_file_range,__PNR_arm_sync_file_range,__PNR_arm_sync_file_range,__PNR_arm_sync_file_range,__PNR_arm_sync_file_range,__PNR_arm_sync_file_range,__PNR_arm_sync_file_range}, +#line 89 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str412,58,328,290,290,356,19,325,284,288,310,310,314,314,19,323,323}, +#line 37 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str413,6,137,183,183,__PNR_afs_syscall,__PNR_afs_syscall,137,176,176,__PNR_afs_syscall,__PNR_afs_syscall,137,137,__PNR_afs_syscall,137,137}, +#line 130 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str414,99,194,__PNR_ftruncate64,__PNR_ftruncate64,194,__PNR_ftruncate64,212,__PNR_ftruncate64,__PNR_ftruncate64,200,200,194,__PNR_ftruncate64,__PNR_ftruncate64,194,__PNR_ftruncate64}, +#line 321 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str415,290,443,443,443,443,443,443,443,443,443,443,443,443,443,443,443}, +#line 332 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str416,301,417,__PNR_recvmmsg_time64,__PNR_recvmmsg_time64,417,__PNR_recvmmsg_time64,417,__PNR_recvmmsg_time64,417,417,__PNR_recvmmsg_time64,417,__PNR_recvmmsg_time64,__PNR_recvmmsg_time64,417,__PNR_recvmmsg_time64}, +#line 255 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str417,224,418,__PNR_mq_timedsend_time64,__PNR_mq_timedsend_time64,418,__PNR_mq_timedsend_time64,418,__PNR_mq_timedsend_time64,418,418,__PNR_mq_timedsend_time64,418,__PNR_mq_timedsend_time64,__PNR_mq_timedsend_time64,418,__PNR_mq_timedsend_time64}, +#line 265 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str418,234,153,152,152,153,231,157,149,149,153,153,153,153,231,153,153}, +#line 264 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str419,233,151,150,150,151,229,155,147,147,151,151,151,151,229,151,151}, +#line 392 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str420,361,214,__PNR_setgid32,__PNR_setgid32,214,__PNR_setgid32,__PNR_setgid32,__PNR_setgid32,__PNR_setgid32,__PNR_setgid32,__PNR_setgid32,__PNR_setgid32,__PNR_setgid32,__PNR_setgid32,214,__PNR_setgid32}, +#line 147 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str421,116,200,__PNR_getgid32,__PNR_getgid32,200,__PNR_getgid32,__PNR_getgid32,__PNR_getgid32,__PNR_getgid32,__PNR_getgid32,__PNR_getgid32,__PNR_getgid32,__PNR_getgid32,__PNR_getgid32,200,__PNR_getgid32}, +#line 253 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str422,222,419,__PNR_mq_timedreceive_time64,__PNR_mq_timedreceive_time64,419,__PNR_mq_timedreceive_time64,419,__PNR_mq_timedreceive_time64,419,419,__PNR_mq_timedreceive_time64,419,__PNR_mq_timedreceive_time64,__PNR_mq_timedreceive_time64,419,__PNR_mq_timedreceive_time64}, +#line 184 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str423,153,293,255,255,318,28,286,245,249,271,271,277,277,28,286,286}, +#line 133 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str424,102,422,__PNR_futex_time64,__PNR_futex_time64,422,__PNR_futex_time64,422,__PNR_futex_time64,422,422,__PNR_futex_time64,422,__PNR_futex_time64,__PNR_futex_time64,422,__PNR_futex_time64}, +#line 441 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str425,410,__PNR_spu_run,__PNR_spu_run,__PNR_spu_run,__PNR_spu_run,__PNR_spu_run,__PNR_spu_run,__PNR_spu_run,__PNR_spu_run,__PNR_spu_run,__PNR_spu_run,278,278,__PNR_spu_run,__PNR_spu_run,__PNR_spu_run}, +#line 104 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str426,73,452,452,452,452,452,452,452,452,452,452,452,452,452,452,452}, +#line 263 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str427,232,__PNR_multiplexer,__PNR_multiplexer,__PNR_multiplexer,__PNR_multiplexer,__PNR_multiplexer,__PNR_multiplexer,__PNR_multiplexer,__PNR_multiplexer,__PNR_multiplexer,__PNR_multiplexer,201,201,__PNR_multiplexer,__PNR_multiplexer,__PNR_multiplexer}, +#line 419 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str428,388,213,__PNR_setuid32,__PNR_setuid32,213,__PNR_setuid32,__PNR_setuid32,__PNR_setuid32,__PNR_setuid32,__PNR_setuid32,__PNR_setuid32,__PNR_setuid32,__PNR_setuid32,__PNR_setuid32,213,__PNR_setuid32}, +#line 176 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str429,145,199,__PNR_getuid32,__PNR_getuid32,199,__PNR_getuid32,__PNR_getuid32,__PNR_getuid32,__PNR_getuid32,__PNR_getuid32,__PNR_getuid32,__PNR_getuid32,__PNR_getuid32,__PNR_getuid32,199,__PNR_getuid32}, +#line 442 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str430,411,69,__PNR_ssetmask,__PNR_ssetmask,__PNR_ssetmask,__PNR_ssetmask,69,__PNR_ssetmask,__PNR_ssetmask,69,69,69,69,__PNR_ssetmask,__PNR_ssetmask,__PNR_ssetmask}, +#line 421 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str431,390,68,__PNR_sgetmask,__PNR_sgetmask,__PNR_sgetmask,__PNR_sgetmask,68,__PNR_sgetmask,__PNR_sgetmask,68,68,68,68,__PNR_sgetmask,__PNR_sgetmask,__PNR_sgetmask}, +#line 320 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str432,289,131,179,179,131,60,131,172,172,131,131,131,131,60,131,131}, +#line 428 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str433,397,186,131,525,186,132,206,129,129,166,166,185,185,132,186,186}, +#line 32 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str434,1,364,288,288,366,242,334,293,297,320,320,344,344,242,364,364}, +#line 303 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str435,272,333,295,534,361,69,330,289,293,315,315,320,320,69,328,328}, +#line 238 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str436,207,376,325,325,390,284,359,319,323,345,345,378,378,284,374,374}, +#line 134 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str437,103,455,455,455,455,455,455,455,455,455,455,455,455,455,455,455}, +#line 455 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str438,424,83,88,88,83,__PNR_symlink,83,86,86,83,83,83,83,__PNR_symlink,83,83}, +#line 181 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str439,150,292,254,254,317,27,285,244,248,270,270,276,276,27,285,285}, +#line 226 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str440,195,453,453,__PNR_map_shadow_stack,453,453,453,453,453,453,453,453,453,453,453,453}, +#line 145 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str441,114,201,__PNR_geteuid32,__PNR_geteuid32,201,__PNR_geteuid32,__PNR_geteuid32,__PNR_geteuid32,__PNR_geteuid32,__PNR_geteuid32,__PNR_geteuid32,__PNR_geteuid32,__PNR_geteuid32,__PNR_geteuid32,201,__PNR_geteuid32}, +#line 431 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str442,400,327,289,289,355,74,324,283,287,309,309,313,313,74,322,322}, +#line 85 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str443,54,441,441,441,441,441,441,441,441,441,441,441,441,441,441,441}, +#line 444 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str444,413,195,__PNR_stat64,__PNR_stat64,195,__PNR_stat64,213,__PNR_stat64,__PNR_stat64,101,101,195,__PNR_stat64,__PNR_stat64,195,__PNR_stat64}, +#line 281 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str445,250,342,304,304,371,265,340,299,304,326,326,346,346,265,336,336}, +#line 446 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str446,415,268,__PNR_statfs64,__PNR_statfs64,266,__PNR_statfs64,255,__PNR_statfs64,217,298,298,252,252,__PNR_statfs64,265,265}, +#line 505 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str447,474,412,__PNR_utimensat_time64,__PNR_utimensat_time64,412,__PNR_utimensat_time64,412,__PNR_utimensat_time64,412,412,__PNR_utimensat_time64,412,__PNR_utimensat_time64,__PNR_utimensat_time64,412,__PNR_utimensat_time64}, +#line 517 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str448,486,146,20,516,146,66,146,19,19,146,146,146,146,66,146,146}, +#line 411 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str449,380,311,273,530,338,99,309,268,272,289,289,300,300,99,304,304}, +#line 166 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str450,135,312,274,531,339,100,310,269,273,290,290,299,299,100,305,305}, +#line 42 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str451,11,134,__PNR_bdflush,__PNR_bdflush,134,__PNR_bdflush,134,__PNR_bdflush,__PNR_bdflush,134,134,134,134,__PNR_bdflush,134,134}, +#line 40 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str452,9,__PNR_arm_fadvise64_64,__PNR_arm_fadvise64_64,__PNR_arm_fadvise64_64,270,__PNR_arm_fadvise64_64,__PNR_arm_fadvise64_64,__PNR_arm_fadvise64_64,__PNR_arm_fadvise64_64,__PNR_arm_fadvise64_64,__PNR_arm_fadvise64_64,__PNR_arm_fadvise64_64,__PNR_arm_fadvise64_64,__PNR_arm_fadvise64_64,__PNR_arm_fadvise64_64,__PNR_arm_fadvise64_64}, +#line 109 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str453,78,221,__PNR_fcntl64,__PNR_fcntl64,221,__PNR_fcntl64,220,__PNR_fcntl64,212,202,202,204,__PNR_fcntl64,__PNR_fcntl64,221,__PNR_fcntl64}, +#line 454 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str454,423,__PNR_switch_endian,__PNR_switch_endian,__PNR_switch_endian,__PNR_switch_endian,__PNR_switch_endian,__PNR_switch_endian,__PNR_switch_endian,__PNR_switch_endian,__PNR_switch_endian,__PNR_switch_endian,363,363,__PNR_switch_endian,__PNR_switch_endian,__PNR_switch_endian}, +#line 65 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str455,34,407,__PNR_clock_nanosleep_time64,__PNR_clock_nanosleep_time64,407,__PNR_clock_nanosleep_time64,407,__PNR_clock_nanosleep_time64,407,407,__PNR_clock_nanosleep_time64,407,__PNR_clock_nanosleep_time64,__PNR_clock_nanosleep_time64,407,__PNR_clock_nanosleep_time64}, +#line 426 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str456,395,373,48,48,293,210,182,47,47,117,117,338,338,210,373,373}, +#line 59 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str457,28,405,__PNR_clock_adjtime64,__PNR_clock_adjtime64,405,__PNR_clock_adjtime64,405,__PNR_clock_adjtime64,405,405,__PNR_clock_adjtime64,405,__PNR_clock_adjtime64,__PNR_clock_adjtime64,405,__PNR_clock_adjtime64}, +#line 317 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str458,286,334,296,535,362,70,331,290,294,316,316,321,321,70,329,329}, +#line 135 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str459,104,449,449,449,449,449,449,449,449,449,449,449,449,449,449,449}, +#line 305 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str460,274,340,302,302,369,261,338,297,302,321,321,325,325,261,334,334}, +#line 56 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str461,25,212,__PNR_chown32,__PNR_chown32,212,__PNR_chown32,__PNR_chown32,__PNR_chown32,__PNR_chown32,__PNR_chown32,__PNR_chown32,__PNR_chown32,__PNR_chown32,__PNR_chown32,212,__PNR_chown32}, +#line 35 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str462,4,286,248,248,309,217,280,239,243,264,264,269,269,217,278,278}, +#line 496 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str463,465,301,263,263,328,35,294,253,257,281,281,292,292,35,294,294}, +#line 136 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str464,105,454,454,454,454,454,454,454,454,454,454,454,454,454,454,454}, +#line 338 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str465,307,353,316,316,382,276,351,311,315,337,337,357,357,276,347,347}, +#line 493 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str466,462,52,166,166,52,39,52,161,161,52,52,52,52,39,52,52}, +#line 501 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str467,470,__PNR_usr32,__PNR_usr32,__PNR_usr32,983044,__PNR_usr32,__PNR_usr32,__PNR_usr32,__PNR_usr32,__PNR_usr32,__PNR_usr32,__PNR_usr32,__PNR_usr32,__PNR_usr32,__PNR_usr32,__PNR_usr32}, +#line 256 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str468,225,278,241,241,275,181,272,231,235,230,230,263,263,181,272,272}, +#line 498 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str469,467,86,134,__PNR_uselib,86,__PNR_uselib,86,__PNR_uselib,__PNR_uselib,86,86,86,86,__PNR_uselib,86,86}, +#line 123 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str470,92,197,__PNR_fstat64,__PNR_fstat64,197,__PNR_fstat64,215,__PNR_fstat64,__PNR_fstat64,112,112,197,__PNR_fstat64,__PNR_fstat64,197,__PNR_fstat64}, +#line 126 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str471,95,269,__PNR_fstatfs64,__PNR_fstatfs64,267,__PNR_fstatfs64,256,__PNR_fstatfs64,218,299,299,253,253,__PNR_fstatfs64,266,266}, +#line 96 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str472,65,250,221,221,__PNR_fadvise64,223,254,215,216,__PNR_fadvise64,__PNR_fadvise64,233,233,223,253,253}, +#line 97 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str473,66,272,__PNR_fadvise64_64,__PNR_fadvise64_64,__PNR_fadvise64_64,__PNR_fadvise64_64,__PNR_fadvise64_64,__PNR_fadvise64_64,__PNR_fadvise64_64,236,236,254,__PNR_fadvise64_64,__PNR_fadvise64_64,264,__PNR_fadvise64_64}, +#line 106 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str474,75,207,__PNR_fchown32,__PNR_fchown32,207,__PNR_fchown32,__PNR_fchown32,__PNR_fchown32,__PNR_fchown32,__PNR_fchown32,__PNR_fchown32,__PNR_fchown32,__PNR_fchown32,__PNR_fchown32,207,__PNR_fchown32}, +#line 302 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str475,271,180,17,17,180,67,200,16,16,108,108,179,179,67,180,180}, +#line 463 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str476,432,__PNR_sys_debug_setcontext,__PNR_sys_debug_setcontext,__PNR_sys_debug_setcontext,__PNR_sys_debug_setcontext,__PNR_sys_debug_setcontext,__PNR_sys_debug_setcontext,__PNR_sys_debug_setcontext,__PNR_sys_debug_setcontext,__PNR_sys_debug_setcontext,__PNR_sys_debug_setcontext,256,256,__PNR_sys_debug_setcontext,__PNR_sys_debug_setcontext,__PNR_sys_debug_setcontext}, +#line 224 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str477,193,196,__PNR_lstat64,__PNR_lstat64,196,__PNR_lstat64,214,__PNR_lstat64,__PNR_lstat64,198,198,196,__PNR_lstat64,__PNR_lstat64,196,__PNR_lstat64}, +#line 304 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str478,273,378,327,546,392,286,361,321,325,347,347,380,380,286,376,376}, +#line 495 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str479,464,10,87,87,10,__PNR_unlink,10,85,85,10,10,10,10,__PNR_unlink,10,10}, +#line 210 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str480,179,198,__PNR_lchown32,__PNR_lchown32,198,__PNR_lchown32,__PNR_lchown32,__PNR_lchown32,__PNR_lchown32,__PNR_lchown32,__PNR_lchown32,__PNR_lchown32,__PNR_lchown32,__PNR_lchown32,198,__PNR_lchown32}, +#line 124 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str481,93,300,__PNR_fstatat64,__PNR_fstatat64,327,__PNR_fstatat64,293,__PNR_fstatat64,__PNR_fstatat64,280,280,291,__PNR_fstatat64,__PNR_fstatat64,293,__PNR_fstatat64}, +#line 46 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str482,15,__PNR_breakpoint,__PNR_breakpoint,__PNR_breakpoint,983041,__PNR_breakpoint,__PNR_breakpoint,__PNR_breakpoint,__PNR_breakpoint,__PNR_breakpoint,__PNR_breakpoint,__PNR_breakpoint,__PNR_breakpoint,__PNR_breakpoint,__PNR_breakpoint,__PNR_breakpoint}, +#line 45 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str483,14,17,__PNR_break,__PNR_break,__PNR_break,__PNR_break,17,__PNR_break,__PNR_break,__PNR_break,__PNR_break,17,17,__PNR_break,__PNR_break,__PNR_break}, +#line 513 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str484,482,114,61,61,114,260,114,59,59,114,114,114,114,260,114,114}, +#line 316 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str485,285,181,18,18,181,68,201,17,17,109,109,180,180,68,181,181}, +#line 318 "syscalls.perf" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str486,287,379,328,547,393,287,362,322,326,348,348,381,381,287,377,377} + }; + +const struct arch_syscall_table * +in_word_set (register const char *str, register size_t len) +{ + if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH) + { + register unsigned int key = hash (str, len); + + if (key <= MAX_HASH_VALUE && key >= MIN_HASH_VALUE) + { + register const struct arch_syscall_table *resword; + + switch (key - 24) + { + case 0: + resword = &wordlist[0]; + goto compare; + case 9: + resword = &wordlist[1]; + goto compare; + case 12: + resword = &wordlist[2]; + goto compare; + case 13: + resword = &wordlist[3]; + goto compare; + case 15: + resword = &wordlist[4]; + goto compare; + case 16: + resword = &wordlist[5]; + goto compare; + case 18: + resword = &wordlist[6]; + goto compare; + case 27: + resword = &wordlist[7]; + goto compare; + case 32: + resword = &wordlist[8]; + goto compare; + case 33: + resword = &wordlist[9]; + goto compare; + case 39: + resword = &wordlist[10]; + goto compare; + case 40: + resword = &wordlist[11]; + goto compare; + case 44: + resword = &wordlist[12]; + goto compare; + case 45: + resword = &wordlist[13]; + goto compare; + case 47: + resword = &wordlist[14]; + goto compare; + case 49: + resword = &wordlist[15]; + goto compare; + case 51: + resword = &wordlist[16]; + goto compare; + case 52: + resword = &wordlist[17]; + goto compare; + case 53: + resword = &wordlist[18]; + goto compare; + case 55: + resword = &wordlist[19]; + goto compare; + case 60: + resword = &wordlist[20]; + goto compare; + case 61: + resword = &wordlist[21]; + goto compare; + case 62: + resword = &wordlist[22]; + goto compare; + case 63: + resword = &wordlist[23]; + goto compare; + case 64: + resword = &wordlist[24]; + goto compare; + case 66: + resword = &wordlist[25]; + goto compare; + case 67: + resword = &wordlist[26]; + goto compare; + case 68: + resword = &wordlist[27]; + goto compare; + case 69: + resword = &wordlist[28]; + goto compare; + case 70: + resword = &wordlist[29]; + goto compare; + case 72: + resword = &wordlist[30]; + goto compare; + case 73: + resword = &wordlist[31]; + goto compare; + case 74: + resword = &wordlist[32]; + goto compare; + case 75: + resword = &wordlist[33]; + goto compare; + case 80: + resword = &wordlist[34]; + goto compare; + case 82: + resword = &wordlist[35]; + goto compare; + case 85: + resword = &wordlist[36]; + goto compare; + case 86: + resword = &wordlist[37]; + goto compare; + case 87: + resword = &wordlist[38]; + goto compare; + case 92: + resword = &wordlist[39]; + goto compare; + case 94: + resword = &wordlist[40]; + goto compare; + case 97: + resword = &wordlist[41]; + goto compare; + case 100: + resword = &wordlist[42]; + goto compare; + case 103: + resword = &wordlist[43]; + goto compare; + case 104: + resword = &wordlist[44]; + goto compare; + case 105: + resword = &wordlist[45]; + goto compare; + case 111: + resword = &wordlist[46]; + goto compare; + case 112: + resword = &wordlist[47]; + goto compare; + case 113: + resword = &wordlist[48]; + goto compare; + case 119: + resword = &wordlist[49]; + goto compare; + case 121: + resword = &wordlist[50]; + goto compare; + case 122: + resword = &wordlist[51]; + goto compare; + case 126: + resword = &wordlist[52]; + goto compare; + case 129: + resword = &wordlist[53]; + goto compare; + case 134: + resword = &wordlist[54]; + goto compare; + case 135: + resword = &wordlist[55]; + goto compare; + case 140: + resword = &wordlist[56]; + goto compare; + case 144: + resword = &wordlist[57]; + goto compare; + case 146: + resword = &wordlist[58]; + goto compare; + case 149: + resword = &wordlist[59]; + goto compare; + case 150: + resword = &wordlist[60]; + goto compare; + case 151: + resword = &wordlist[61]; + goto compare; + case 154: + resword = &wordlist[62]; + goto compare; + case 164: + resword = &wordlist[63]; + goto compare; + case 165: + resword = &wordlist[64]; + goto compare; + case 166: + resword = &wordlist[65]; + goto compare; + case 172: + resword = &wordlist[66]; + goto compare; + case 174: + resword = &wordlist[67]; + goto compare; + case 176: + resword = &wordlist[68]; + goto compare; + case 177: + resword = &wordlist[69]; + goto compare; + case 178: + resword = &wordlist[70]; + goto compare; + case 180: + resword = &wordlist[71]; + goto compare; + case 185: + resword = &wordlist[72]; + goto compare; + case 191: + resword = &wordlist[73]; + goto compare; + case 192: + resword = &wordlist[74]; + goto compare; + case 193: + resword = &wordlist[75]; + goto compare; + case 194: + resword = &wordlist[76]; + goto compare; + case 196: + resword = &wordlist[77]; + goto compare; + case 197: + resword = &wordlist[78]; + goto compare; + case 198: + resword = &wordlist[79]; + goto compare; + case 199: + resword = &wordlist[80]; + goto compare; + case 201: + resword = &wordlist[81]; + goto compare; + case 203: + resword = &wordlist[82]; + goto compare; + case 207: + resword = &wordlist[83]; + goto compare; + case 208: + resword = &wordlist[84]; + goto compare; + case 209: + resword = &wordlist[85]; + goto compare; + case 211: + resword = &wordlist[86]; + goto compare; + case 213: + resword = &wordlist[87]; + goto compare; + case 219: + resword = &wordlist[88]; + goto compare; + case 220: + resword = &wordlist[89]; + goto compare; + case 221: + resword = &wordlist[90]; + goto compare; + case 222: + resword = &wordlist[91]; + goto compare; + case 225: + resword = &wordlist[92]; + goto compare; + case 228: + resword = &wordlist[93]; + goto compare; + case 229: + resword = &wordlist[94]; + goto compare; + case 230: + resword = &wordlist[95]; + goto compare; + case 232: + resword = &wordlist[96]; + goto compare; + case 236: + resword = &wordlist[97]; + goto compare; + case 237: + resword = &wordlist[98]; + goto compare; + case 238: + resword = &wordlist[99]; + goto compare; + case 239: + resword = &wordlist[100]; + goto compare; + case 240: + resword = &wordlist[101]; + goto compare; + case 241: + resword = &wordlist[102]; + goto compare; + case 254: + resword = &wordlist[103]; + goto compare; + case 259: + resword = &wordlist[104]; + goto compare; + case 260: + resword = &wordlist[105]; + goto compare; + case 262: + resword = &wordlist[106]; + goto compare; + case 263: + resword = &wordlist[107]; + goto compare; + case 265: + resword = &wordlist[108]; + goto compare; + case 267: + resword = &wordlist[109]; + goto compare; + case 269: + resword = &wordlist[110]; + goto compare; + case 270: + resword = &wordlist[111]; + goto compare; + case 273: + resword = &wordlist[112]; + goto compare; + case 274: + resword = &wordlist[113]; + goto compare; + case 275: + resword = &wordlist[114]; + goto compare; + case 277: + resword = &wordlist[115]; + goto compare; + case 278: + resword = &wordlist[116]; + goto compare; + case 279: + resword = &wordlist[117]; + goto compare; + case 281: + resword = &wordlist[118]; + goto compare; + case 282: + resword = &wordlist[119]; + goto compare; + case 286: + resword = &wordlist[120]; + goto compare; + case 289: + resword = &wordlist[121]; + goto compare; + case 291: + resword = &wordlist[122]; + goto compare; + case 297: + resword = &wordlist[123]; + goto compare; + case 301: + resword = &wordlist[124]; + goto compare; + case 304: + resword = &wordlist[125]; + goto compare; + case 306: + resword = &wordlist[126]; + goto compare; + case 311: + resword = &wordlist[127]; + goto compare; + case 313: + resword = &wordlist[128]; + goto compare; + case 316: + resword = &wordlist[129]; + goto compare; + case 318: + resword = &wordlist[130]; + goto compare; + case 319: + resword = &wordlist[131]; + goto compare; + case 320: + resword = &wordlist[132]; + goto compare; + case 321: + resword = &wordlist[133]; + goto compare; + case 328: + resword = &wordlist[134]; + goto compare; + case 330: + resword = &wordlist[135]; + goto compare; + case 331: + resword = &wordlist[136]; + goto compare; + case 332: + resword = &wordlist[137]; + goto compare; + case 333: + resword = &wordlist[138]; + goto compare; + case 334: + resword = &wordlist[139]; + goto compare; + case 335: + resword = &wordlist[140]; + goto compare; + case 337: + resword = &wordlist[141]; + goto compare; + case 339: + resword = &wordlist[142]; + goto compare; + case 340: + resword = &wordlist[143]; + goto compare; + case 343: + resword = &wordlist[144]; + goto compare; + case 344: + resword = &wordlist[145]; + goto compare; + case 345: + resword = &wordlist[146]; + goto compare; + case 347: + resword = &wordlist[147]; + goto compare; + case 349: + resword = &wordlist[148]; + goto compare; + case 351: + resword = &wordlist[149]; + goto compare; + case 355: + resword = &wordlist[150]; + goto compare; + case 356: + resword = &wordlist[151]; + goto compare; + case 358: + resword = &wordlist[152]; + goto compare; + case 360: + resword = &wordlist[153]; + goto compare; + case 362: + resword = &wordlist[154]; + goto compare; + case 363: + resword = &wordlist[155]; + goto compare; + case 369: + resword = &wordlist[156]; + goto compare; + case 370: + resword = &wordlist[157]; + goto compare; + case 371: + resword = &wordlist[158]; + goto compare; + case 372: + resword = &wordlist[159]; + goto compare; + case 374: + resword = &wordlist[160]; + goto compare; + case 380: + resword = &wordlist[161]; + goto compare; + case 383: + resword = &wordlist[162]; + goto compare; + case 384: + resword = &wordlist[163]; + goto compare; + case 386: + resword = &wordlist[164]; + goto compare; + case 393: + resword = &wordlist[165]; + goto compare; + case 395: + resword = &wordlist[166]; + goto compare; + case 396: + resword = &wordlist[167]; + goto compare; + case 399: + resword = &wordlist[168]; + goto compare; + case 400: + resword = &wordlist[169]; + goto compare; + case 401: + resword = &wordlist[170]; + goto compare; + case 414: + resword = &wordlist[171]; + goto compare; + case 416: + resword = &wordlist[172]; + goto compare; + case 417: + resword = &wordlist[173]; + goto compare; + case 419: + resword = &wordlist[174]; + goto compare; + case 422: + resword = &wordlist[175]; + goto compare; + case 425: + resword = &wordlist[176]; + goto compare; + case 426: + resword = &wordlist[177]; + goto compare; + case 427: + resword = &wordlist[178]; + goto compare; + case 430: + resword = &wordlist[179]; + goto compare; + case 435: + resword = &wordlist[180]; + goto compare; + case 436: + resword = &wordlist[181]; + goto compare; + case 437: + resword = &wordlist[182]; + goto compare; + case 438: + resword = &wordlist[183]; + goto compare; + case 439: + resword = &wordlist[184]; + goto compare; + case 440: + resword = &wordlist[185]; + goto compare; + case 441: + resword = &wordlist[186]; + goto compare; + case 442: + resword = &wordlist[187]; + goto compare; + case 444: + resword = &wordlist[188]; + goto compare; + case 445: + resword = &wordlist[189]; + goto compare; + case 447: + resword = &wordlist[190]; + goto compare; + case 448: + resword = &wordlist[191]; + goto compare; + case 450: + resword = &wordlist[192]; + goto compare; + case 455: + resword = &wordlist[193]; + goto compare; + case 463: + resword = &wordlist[194]; + goto compare; + case 464: + resword = &wordlist[195]; + goto compare; + case 465: + resword = &wordlist[196]; + goto compare; + case 466: + resword = &wordlist[197]; + goto compare; + case 468: + resword = &wordlist[198]; + goto compare; + case 469: + resword = &wordlist[199]; + goto compare; + case 471: + resword = &wordlist[200]; + goto compare; + case 475: + resword = &wordlist[201]; + goto compare; + case 476: + resword = &wordlist[202]; + goto compare; + case 477: + resword = &wordlist[203]; + goto compare; + case 482: + resword = &wordlist[204]; + goto compare; + case 483: + resword = &wordlist[205]; + goto compare; + case 485: + resword = &wordlist[206]; + goto compare; + case 489: + resword = &wordlist[207]; + goto compare; + case 490: + resword = &wordlist[208]; + goto compare; + case 492: + resword = &wordlist[209]; + goto compare; + case 493: + resword = &wordlist[210]; + goto compare; + case 494: + resword = &wordlist[211]; + goto compare; + case 497: + resword = &wordlist[212]; + goto compare; + case 498: + resword = &wordlist[213]; + goto compare; + case 499: + resword = &wordlist[214]; + goto compare; + case 500: + resword = &wordlist[215]; + goto compare; + case 501: + resword = &wordlist[216]; + goto compare; + case 502: + resword = &wordlist[217]; + goto compare; + case 504: + resword = &wordlist[218]; + goto compare; + case 505: + resword = &wordlist[219]; + goto compare; + case 506: + resword = &wordlist[220]; + goto compare; + case 507: + resword = &wordlist[221]; + goto compare; + case 510: + resword = &wordlist[222]; + goto compare; + case 511: + resword = &wordlist[223]; + goto compare; + case 514: + resword = &wordlist[224]; + goto compare; + case 515: + resword = &wordlist[225]; + goto compare; + case 516: + resword = &wordlist[226]; + goto compare; + case 518: + resword = &wordlist[227]; + goto compare; + case 519: + resword = &wordlist[228]; + goto compare; + case 520: + resword = &wordlist[229]; + goto compare; + case 524: + resword = &wordlist[230]; + goto compare; + case 525: + resword = &wordlist[231]; + goto compare; + case 527: + resword = &wordlist[232]; + goto compare; + case 528: + resword = &wordlist[233]; + goto compare; + case 529: + resword = &wordlist[234]; + goto compare; + case 530: + resword = &wordlist[235]; + goto compare; + case 531: + resword = &wordlist[236]; + goto compare; + case 535: + resword = &wordlist[237]; + goto compare; + case 537: + resword = &wordlist[238]; + goto compare; + case 538: + resword = &wordlist[239]; + goto compare; + case 543: + resword = &wordlist[240]; + goto compare; + case 545: + resword = &wordlist[241]; + goto compare; + case 546: + resword = &wordlist[242]; + goto compare; + case 547: + resword = &wordlist[243]; + goto compare; + case 551: + resword = &wordlist[244]; + goto compare; + case 552: + resword = &wordlist[245]; + goto compare; + case 553: + resword = &wordlist[246]; + goto compare; + case 554: + resword = &wordlist[247]; + goto compare; + case 555: + resword = &wordlist[248]; + goto compare; + case 557: + resword = &wordlist[249]; + goto compare; + case 558: + resword = &wordlist[250]; + goto compare; + case 560: + resword = &wordlist[251]; + goto compare; + case 562: + resword = &wordlist[252]; + goto compare; + case 564: + resword = &wordlist[253]; + goto compare; + case 565: + resword = &wordlist[254]; + goto compare; + case 567: + resword = &wordlist[255]; + goto compare; + case 570: + resword = &wordlist[256]; + goto compare; + case 571: + resword = &wordlist[257]; + goto compare; + case 574: + resword = &wordlist[258]; + goto compare; + case 575: + resword = &wordlist[259]; + goto compare; + case 577: + resword = &wordlist[260]; + goto compare; + case 578: + resword = &wordlist[261]; + goto compare; + case 579: + resword = &wordlist[262]; + goto compare; + case 580: + resword = &wordlist[263]; + goto compare; + case 581: + resword = &wordlist[264]; + goto compare; + case 582: + resword = &wordlist[265]; + goto compare; + case 586: + resword = &wordlist[266]; + goto compare; + case 587: + resword = &wordlist[267]; + goto compare; + case 588: + resword = &wordlist[268]; + goto compare; + case 589: + resword = &wordlist[269]; + goto compare; + case 592: + resword = &wordlist[270]; + goto compare; + case 593: + resword = &wordlist[271]; + goto compare; + case 594: + resword = &wordlist[272]; + goto compare; + case 595: + resword = &wordlist[273]; + goto compare; + case 596: + resword = &wordlist[274]; + goto compare; + case 597: + resword = &wordlist[275]; + goto compare; + case 601: + resword = &wordlist[276]; + goto compare; + case 603: + resword = &wordlist[277]; + goto compare; + case 607: + resword = &wordlist[278]; + goto compare; + case 608: + resword = &wordlist[279]; + goto compare; + case 623: + resword = &wordlist[280]; + goto compare; + case 627: + resword = &wordlist[281]; + goto compare; + case 628: + resword = &wordlist[282]; + goto compare; + case 629: + resword = &wordlist[283]; + goto compare; + case 631: + resword = &wordlist[284]; + goto compare; + case 634: + resword = &wordlist[285]; + goto compare; + case 636: + resword = &wordlist[286]; + goto compare; + case 637: + resword = &wordlist[287]; + goto compare; + case 639: + resword = &wordlist[288]; + goto compare; + case 646: + resword = &wordlist[289]; + goto compare; + case 647: + resword = &wordlist[290]; + goto compare; + case 654: + resword = &wordlist[291]; + goto compare; + case 656: + resword = &wordlist[292]; + goto compare; + case 657: + resword = &wordlist[293]; + goto compare; + case 661: + resword = &wordlist[294]; + goto compare; + case 663: + resword = &wordlist[295]; + goto compare; + case 664: + resword = &wordlist[296]; + goto compare; + case 665: + resword = &wordlist[297]; + goto compare; + case 669: + resword = &wordlist[298]; + goto compare; + case 672: + resword = &wordlist[299]; + goto compare; + case 677: + resword = &wordlist[300]; + goto compare; + case 679: + resword = &wordlist[301]; + goto compare; + case 680: + resword = &wordlist[302]; + goto compare; + case 685: + resword = &wordlist[303]; + goto compare; + case 686: + resword = &wordlist[304]; + goto compare; + case 688: + resword = &wordlist[305]; + goto compare; + case 689: + resword = &wordlist[306]; + goto compare; + case 690: + resword = &wordlist[307]; + goto compare; + case 693: + resword = &wordlist[308]; + goto compare; + case 696: + resword = &wordlist[309]; + goto compare; + case 698: + resword = &wordlist[310]; + goto compare; + case 699: + resword = &wordlist[311]; + goto compare; + case 700: + resword = &wordlist[312]; + goto compare; + case 702: + resword = &wordlist[313]; + goto compare; + case 707: + resword = &wordlist[314]; + goto compare; + case 708: + resword = &wordlist[315]; + goto compare; + case 710: + resword = &wordlist[316]; + goto compare; + case 711: + resword = &wordlist[317]; + goto compare; + case 712: + resword = &wordlist[318]; + goto compare; + case 713: + resword = &wordlist[319]; + goto compare; + case 714: + resword = &wordlist[320]; + goto compare; + case 718: + resword = &wordlist[321]; + goto compare; + case 725: + resword = &wordlist[322]; + goto compare; + case 726: + resword = &wordlist[323]; + goto compare; + case 730: + resword = &wordlist[324]; + goto compare; + case 732: + resword = &wordlist[325]; + goto compare; + case 735: + resword = &wordlist[326]; + goto compare; + case 742: + resword = &wordlist[327]; + goto compare; + case 744: + resword = &wordlist[328]; + goto compare; + case 745: + resword = &wordlist[329]; + goto compare; + case 746: + resword = &wordlist[330]; + goto compare; + case 747: + resword = &wordlist[331]; + goto compare; + case 748: + resword = &wordlist[332]; + goto compare; + case 750: + resword = &wordlist[333]; + goto compare; + case 754: + resword = &wordlist[334]; + goto compare; + case 760: + resword = &wordlist[335]; + goto compare; + case 764: + resword = &wordlist[336]; + goto compare; + case 766: + resword = &wordlist[337]; + goto compare; + case 768: + resword = &wordlist[338]; + goto compare; + case 775: + resword = &wordlist[339]; + goto compare; + case 776: + resword = &wordlist[340]; + goto compare; + case 779: + resword = &wordlist[341]; + goto compare; + case 782: + resword = &wordlist[342]; + goto compare; + case 783: + resword = &wordlist[343]; + goto compare; + case 785: + resword = &wordlist[344]; + goto compare; + case 788: + resword = &wordlist[345]; + goto compare; + case 796: + resword = &wordlist[346]; + goto compare; + case 799: + resword = &wordlist[347]; + goto compare; + case 801: + resword = &wordlist[348]; + goto compare; + case 807: + resword = &wordlist[349]; + goto compare; + case 808: + resword = &wordlist[350]; + goto compare; + case 810: + resword = &wordlist[351]; + goto compare; + case 816: + resword = &wordlist[352]; + goto compare; + case 817: + resword = &wordlist[353]; + goto compare; + case 823: + resword = &wordlist[354]; + goto compare; + case 825: + resword = &wordlist[355]; + goto compare; + case 826: + resword = &wordlist[356]; + goto compare; + case 830: + resword = &wordlist[357]; + goto compare; + case 832: + resword = &wordlist[358]; + goto compare; + case 838: + resword = &wordlist[359]; + goto compare; + case 848: + resword = &wordlist[360]; + goto compare; + case 849: + resword = &wordlist[361]; + goto compare; + case 850: + resword = &wordlist[362]; + goto compare; + case 853: + resword = &wordlist[363]; + goto compare; + case 854: + resword = &wordlist[364]; + goto compare; + case 859: + resword = &wordlist[365]; + goto compare; + case 860: + resword = &wordlist[366]; + goto compare; + case 861: + resword = &wordlist[367]; + goto compare; + case 862: + resword = &wordlist[368]; + goto compare; + case 864: + resword = &wordlist[369]; + goto compare; + case 865: + resword = &wordlist[370]; + goto compare; + case 866: + resword = &wordlist[371]; + goto compare; + case 868: + resword = &wordlist[372]; + goto compare; + case 870: + resword = &wordlist[373]; + goto compare; + case 879: + resword = &wordlist[374]; + goto compare; + case 884: + resword = &wordlist[375]; + goto compare; + case 885: + resword = &wordlist[376]; + goto compare; + case 891: + resword = &wordlist[377]; + goto compare; + case 892: + resword = &wordlist[378]; + goto compare; + case 895: + resword = &wordlist[379]; + goto compare; + case 899: + resword = &wordlist[380]; + goto compare; + case 902: + resword = &wordlist[381]; + goto compare; + case 905: + resword = &wordlist[382]; + goto compare; + case 906: + resword = &wordlist[383]; + goto compare; + case 907: + resword = &wordlist[384]; + goto compare; + case 909: + resword = &wordlist[385]; + goto compare; + case 910: + resword = &wordlist[386]; + goto compare; + case 916: + resword = &wordlist[387]; + goto compare; + case 917: + resword = &wordlist[388]; + goto compare; + case 920: + resword = &wordlist[389]; + goto compare; + case 923: + resword = &wordlist[390]; + goto compare; + case 924: + resword = &wordlist[391]; + goto compare; + case 925: + resword = &wordlist[392]; + goto compare; + case 927: + resword = &wordlist[393]; + goto compare; + case 932: + resword = &wordlist[394]; + goto compare; + case 936: + resword = &wordlist[395]; + goto compare; + case 937: + resword = &wordlist[396]; + goto compare; + case 957: + resword = &wordlist[397]; + goto compare; + case 965: + resword = &wordlist[398]; + goto compare; + case 966: + resword = &wordlist[399]; + goto compare; + case 968: + resword = &wordlist[400]; + goto compare; + case 973: + resword = &wordlist[401]; + goto compare; + case 976: + resword = &wordlist[402]; + goto compare; + case 983: + resword = &wordlist[403]; + goto compare; + case 985: + resword = &wordlist[404]; + goto compare; + case 988: + resword = &wordlist[405]; + goto compare; + case 989: + resword = &wordlist[406]; + goto compare; + case 990: + resword = &wordlist[407]; + goto compare; + case 991: + resword = &wordlist[408]; + goto compare; + case 996: + resword = &wordlist[409]; + goto compare; + case 997: + resword = &wordlist[410]; + goto compare; + case 999: + resword = &wordlist[411]; + goto compare; + case 1007: + resword = &wordlist[412]; + goto compare; + case 1019: + resword = &wordlist[413]; + goto compare; + case 1029: + resword = &wordlist[414]; + goto compare; + case 1031: + resword = &wordlist[415]; + goto compare; + case 1038: + resword = &wordlist[416]; + goto compare; + case 1039: + resword = &wordlist[417]; + goto compare; + case 1041: + resword = &wordlist[418]; + goto compare; + case 1044: + resword = &wordlist[419]; + goto compare; + case 1045: + resword = &wordlist[420]; + goto compare; + case 1046: + resword = &wordlist[421]; + goto compare; + case 1051: + resword = &wordlist[422]; + goto compare; + case 1054: + resword = &wordlist[423]; + goto compare; + case 1061: + resword = &wordlist[424]; + goto compare; + case 1063: + resword = &wordlist[425]; + goto compare; + case 1064: + resword = &wordlist[426]; + goto compare; + case 1066: + resword = &wordlist[427]; + goto compare; + case 1095: + resword = &wordlist[428]; + goto compare; + case 1096: + resword = &wordlist[429]; + goto compare; + case 1100: + resword = &wordlist[430]; + goto compare; + case 1101: + resword = &wordlist[431]; + goto compare; + case 1102: + resword = &wordlist[432]; + goto compare; + case 1123: + resword = &wordlist[433]; + goto compare; + case 1127: + resword = &wordlist[434]; + goto compare; + case 1136: + resword = &wordlist[435]; + goto compare; + case 1143: + resword = &wordlist[436]; + goto compare; + case 1157: + resword = &wordlist[437]; + goto compare; + case 1160: + resword = &wordlist[438]; + goto compare; + case 1165: + resword = &wordlist[439]; + goto compare; + case 1167: + resword = &wordlist[440]; + goto compare; + case 1177: + resword = &wordlist[441]; + goto compare; + case 1195: + resword = &wordlist[442]; + goto compare; + case 1218: + resword = &wordlist[443]; + goto compare; + case 1242: + resword = &wordlist[444]; + goto compare; + case 1252: + resword = &wordlist[445]; + goto compare; + case 1256: + resword = &wordlist[446]; + goto compare; + case 1264: + resword = &wordlist[447]; + goto compare; + case 1281: + resword = &wordlist[448]; + goto compare; + case 1290: + resword = &wordlist[449]; + goto compare; + case 1291: + resword = &wordlist[450]; + goto compare; + case 1313: + resword = &wordlist[451]; + goto compare; + case 1323: + resword = &wordlist[452]; + goto compare; + case 1341: + resword = &wordlist[453]; + goto compare; + case 1346: + resword = &wordlist[454]; + goto compare; + case 1359: + resword = &wordlist[455]; + goto compare; + case 1361: + resword = &wordlist[456]; + goto compare; + case 1375: + resword = &wordlist[457]; + goto compare; + case 1381: + resword = &wordlist[458]; + goto compare; + case 1395: + resword = &wordlist[459]; + goto compare; + case 1407: + resword = &wordlist[460]; + goto compare; + case 1412: + resword = &wordlist[461]; + goto compare; + case 1430: + resword = &wordlist[462]; + goto compare; + case 1448: + resword = &wordlist[463]; + goto compare; + case 1458: + resword = &wordlist[464]; + goto compare; + case 1466: + resword = &wordlist[465]; + goto compare; + case 1470: + resword = &wordlist[466]; + goto compare; + case 1478: + resword = &wordlist[467]; + goto compare; + case 1492: + resword = &wordlist[468]; + goto compare; + case 1499: + resword = &wordlist[469]; + goto compare; + case 1507: + resword = &wordlist[470]; + goto compare; + case 1521: + resword = &wordlist[471]; + goto compare; + case 1543: + resword = &wordlist[472]; + goto compare; + case 1546: + resword = &wordlist[473]; + goto compare; + case 1549: + resword = &wordlist[474]; + goto compare; + case 1580: + resword = &wordlist[475]; + goto compare; + case 1586: + resword = &wordlist[476]; + goto compare; + case 1591: + resword = &wordlist[477]; + goto compare; + case 1605: + resword = &wordlist[478]; + goto compare; + case 1620: + resword = &wordlist[479]; + goto compare; + case 1633: + resword = &wordlist[480]; + goto compare; + case 1640: + resword = &wordlist[481]; + goto compare; + case 1753: + resword = &wordlist[482]; + goto compare; + case 1767: + resword = &wordlist[483]; + goto compare; + case 1821: + resword = &wordlist[484]; + goto compare; + case 1825: + resword = &wordlist[485]; + goto compare; + case 1850: + resword = &wordlist[486]; + goto compare; + } + return 0; + compare: + { + register const char *s = resword->name + stringpool; + + if (*str == *s && !strcmp (str + 1, s + 1)) + return resword; + } + } + } + return 0; +} +#line 518 "syscalls.perf" + + +static int syscall_get_offset_value(const struct arch_syscall_table *s, + int offset) +{ + return *(int *)((char *)s + offset); +} + +int syscall_resolve_name(const char *name, int offset) +{ + const struct arch_syscall_table *s; + + s = in_word_set(name, strlen(name)); + if (s == NULL) + return __NR_SCMP_ERROR; + + return syscall_get_offset_value(s, offset); +} + +const char *syscall_resolve_num(int num, int offset) +{ + unsigned int iter; + + for (iter = 0; iter < sizeof(wordlist)/sizeof(wordlist[0]); iter++) { + if (syscall_get_offset_value(&wordlist[iter], offset) == num) + return (stringpool + wordlist[iter].name); + } + + return NULL; +} + +const struct arch_syscall_def *syscall_iterate(unsigned int spot, int offset) +{ + unsigned int iter; + /* this is thread-unsafe, only use for testing */ + static struct arch_syscall_def arch_def; + + arch_def.name = NULL; + arch_def.num = __NR_SCMP_ERROR; + + for (iter = 0; iter < sizeof(wordlist)/sizeof(wordlist[0]); iter++) { + if (wordlist[iter].index == spot) { + arch_def.name = stringpool + wordlist[iter].name; + arch_def.num = syscall_get_offset_value(&wordlist[iter], + offset); + return &arch_def; + } + } + + return &arch_def; +} diff --git a/src/syscalls.perf.template b/src/syscalls.perf.template new file mode 100644 index 0000000..f1fd3db --- /dev/null +++ b/src/syscalls.perf.template @@ -0,0 +1,82 @@ +%{ +/** + * Copyright (c) 2012 Red Hat <pmoore@redhat.com> + * Copyright (c) 2020 Red Hat <gscrivan@redhat.com> + * Authors: Paul Moore <paul@paul-moore.com> + * Giuseppe Scrivano <gscrivan@redhat.com> + */ + +/* + * 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 <seccomp.h> +#include <string.h> +#include "syscalls.h" + +%} +struct arch_syscall_table; + +%% +@@SYSCALLS_TABLE@@ +%% + +static int syscall_get_offset_value(const struct arch_syscall_table *s, + int offset) +{ + return *(int *)((char *)s + offset); +} + +int syscall_resolve_name(const char *name, int offset) +{ + const struct arch_syscall_table *s; + + s = in_word_set(name, strlen(name)); + if (s == NULL) + return __NR_SCMP_ERROR; + + return syscall_get_offset_value(s, offset); +} + +const char *syscall_resolve_num(int num, int offset) +{ + unsigned int iter; + + for (iter = 0; iter < sizeof(wordlist)/sizeof(wordlist[0]); iter++) { + if (syscall_get_offset_value(&wordlist[iter], offset) == num) + return (stringpool + wordlist[iter].name); + } + + return NULL; +} + +const struct arch_syscall_def *syscall_iterate(unsigned int spot, int offset) +{ + unsigned int iter; + /* this is thread-unsafe, only use for testing */ + static struct arch_syscall_def arch_def; + + arch_def.name = NULL; + arch_def.num = __NR_SCMP_ERROR; + + for (iter = 0; iter < sizeof(wordlist)/sizeof(wordlist[0]); iter++) { + if (wordlist[iter].index == spot) { + arch_def.name = stringpool + wordlist[iter].name; + arch_def.num = syscall_get_offset_value(&wordlist[iter], + offset); + return &arch_def; + } + } + + return &arch_def; +} diff --git a/src/system.c b/src/system.c new file mode 100644 index 0000000..ae445bf --- /dev/null +++ b/src/system.c @@ -0,0 +1,554 @@ +/** + * Seccomp System Interfaces + * + * Copyright (c) 2014 Red Hat <pmoore@redhat.com> + * Author: Paul Moore <paul@paul-moore.com> + */ + +/* + * 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 <sys/prctl.h> + +#define _GNU_SOURCE +#include <unistd.h> + +#include "system.h" + +#include <seccomp.h> + +#include "arch.h" +#include "db.h" +#include "gen_bpf.h" +#include "helper.h" + +/* NOTE: the seccomp syscall allowlist is currently disabled for testing + * purposes, but unless we can verify all of the supported ABIs before + * our next release we may have to enable the allowlist */ +#define SYSCALL_ALLOWLIST_ENABLE 0 + +/* task global state */ +struct task_state { + /* seccomp(2) syscall */ + int nr_seccomp; + + /* userspace notification fd */ + int notify_fd; + + /* runtime support flags */ + int sup_syscall; + int sup_flag_tsync; + int sup_flag_log; + int sup_action_log; + int sup_kill_process; + int sup_flag_spec_allow; + int sup_flag_new_listener; + int sup_user_notif; + int sup_flag_tsync_esrch; +}; +static struct task_state state = { + .nr_seccomp = -1, + + .notify_fd = -1, + + .sup_syscall = -1, + .sup_flag_tsync = -1, + .sup_flag_log = -1, + .sup_action_log = -1, + .sup_kill_process = -1, + .sup_flag_spec_allow = -1, + .sup_flag_new_listener = -1, + .sup_user_notif = -1, + .sup_flag_tsync_esrch = -1, +}; + +/** + * Reset the task state + * + * This function fully resets the library's global "system task state". + * + */ +void sys_reset_state(void) +{ + state.nr_seccomp = -1; + + if (state.notify_fd > 0) + close(state.notify_fd); + state.notify_fd = -1; + + state.sup_syscall = -1; + state.sup_flag_tsync = -1; + state.sup_flag_log = -1; + state.sup_action_log = -1; + state.sup_kill_process = -1; + state.sup_flag_spec_allow = -1; + state.sup_flag_new_listener = -1; + state.sup_user_notif = -1; + state.sup_flag_tsync_esrch = -1; +} + +/** + * Check to see if the seccomp() syscall is supported + * + * This function attempts to see if the system supports the seccomp() syscall. + * Unfortunately, there are a few reasons why this check may fail, including + * a previously loaded seccomp filter, so it is hard to say for certain. + * Return one if the syscall is supported, zero otherwise. + * + */ +int sys_chk_seccomp_syscall(void) +{ + int rc; + int nr_seccomp; + + /* NOTE: it is reasonably safe to assume that we should be able to call + * seccomp() when the caller first starts, but we can't rely on + * it later so we need to cache our findings for use later */ + if (state.sup_syscall >= 0) + return state.sup_syscall; + +#if SYSCALL_ALLOWLIST_ENABLE + /* architecture allowlist */ + switch (arch_def_native->token) { + case SCMP_ARCH_X86_64: + case SCMP_ARCH_ARM: + case SCMP_ARCH_AARCH64: + case SCMP_ARCH_PPC64: + case SCMP_ARCH_PPC64LE: + case SCMP_ARCH_S390: + case SCMP_ARCH_S390X: + case SCMP_ARCH_RISCV64: + break; + default: + goto unsupported; + } +#endif + + nr_seccomp = arch_syscall_resolve_name(arch_def_native, "seccomp"); + if (nr_seccomp < 0) + goto unsupported; + + /* this is an invalid call because the second argument is non-zero, but + * depending on the errno value of ENOSYS or EINVAL we can guess if the + * seccomp() syscall is supported or not */ + rc = syscall(nr_seccomp, SECCOMP_SET_MODE_STRICT, 1, NULL); + if (rc < 0 && errno == EINVAL) + goto supported; + +unsupported: + state.sup_syscall = 0; + return 0; +supported: + state.nr_seccomp = nr_seccomp; + state.sup_syscall = 1; + return 1; +} + +/** + * Force the seccomp() syscall support setting + * @param enable the intended support state + * + * This function overrides the current seccomp() syscall support setting; this + * is very much a "use at your own risk" function. + * + */ +void sys_set_seccomp_syscall(bool enable) +{ + state.sup_syscall = (enable ? 1 : 0); +} + +/** + * Check to see if a seccomp action is supported + * @param action the seccomp action + * + * This function checks to see if a seccomp action is supported by the system. + * Return one if the action is supported, zero otherwise. + * + */ +int sys_chk_seccomp_action(uint32_t action) +{ + if (action == SCMP_ACT_KILL_PROCESS) { + if (state.sup_kill_process < 0) { + if (sys_chk_seccomp_syscall() == 1 && + syscall(state.nr_seccomp, + SECCOMP_GET_ACTION_AVAIL, 0, &action) == 0) + state.sup_kill_process = 1; + else + state.sup_kill_process = 0; + } + + return state.sup_kill_process; + } else if (action == SCMP_ACT_KILL_THREAD) { + return 1; + } else if (action == SCMP_ACT_TRAP) { + return 1; + } else if ((action == SCMP_ACT_ERRNO(action & 0x0000ffff)) && + ((action & 0x0000ffff) < MAX_ERRNO)) { + return 1; + } else if (action == SCMP_ACT_TRACE(action & 0x0000ffff)) { + return 1; + } else if (action == SCMP_ACT_LOG) { + if (state.sup_action_log < 0) { + if (sys_chk_seccomp_syscall() == 1 && + syscall(state.nr_seccomp, + SECCOMP_GET_ACTION_AVAIL, 0, &action) == 0) + state.sup_action_log = 1; + else + state.sup_action_log = 0; + } + + return state.sup_action_log; + } else if (action == SCMP_ACT_ALLOW) { + return 1; + } else if (action == SCMP_ACT_NOTIFY) { + if (state.sup_user_notif < 0) { + struct seccomp_notif_sizes sizes; + if (sys_chk_seccomp_syscall() == 1 && + syscall(state.nr_seccomp, + SECCOMP_GET_NOTIF_SIZES, 0, &sizes) == 0) + state.sup_user_notif = 1; + else + state.sup_user_notif = 0; + } + + return state.sup_user_notif; + } + + return 0; +} + +/** + * Force a seccomp action support setting + * @param action the seccomp action + * @param enable the intended support state + * + * This function overrides the current seccomp action support setting; this + * is very much a "use at your own risk" function. + */ +void sys_set_seccomp_action(uint32_t action, bool enable) +{ + switch (action) { + case SCMP_ACT_LOG: + state.sup_action_log = (enable ? 1 : 0); + break; + case SCMP_ACT_KILL_PROCESS: + state.sup_kill_process = (enable ? 1 : 0); + break; + case SCMP_ACT_NOTIFY: + state.sup_user_notif = (enable ? 1 : 0); + break; + } +} + +/** + * Check to see if a seccomp() flag is supported by the kernel + * @param flag the seccomp() flag + * + * This function checks to see if a seccomp() flag is supported by the kernel. + * Return one if the flag is supported, zero otherwise. + * + */ +static int _sys_chk_flag_kernel(int flag) +{ + /* this is an invalid seccomp(2) call because the last argument + * is NULL, but depending on the errno value of EFAULT we can + * guess if the filter flag is supported or not */ + if (sys_chk_seccomp_syscall() == 1 && + syscall(state.nr_seccomp, + SECCOMP_SET_MODE_FILTER, flag, NULL) == -1 && + errno == EFAULT) + return 1; + + return 0; +} + +/** + * Check to see if a seccomp() flag is supported + * @param flag the seccomp() flag + * + * This function checks to see if a seccomp() flag is supported by the system. + * Return one if the syscall is supported, zero if unsupported, negative values + * on error. + * + */ +int sys_chk_seccomp_flag(int flag) +{ + switch (flag) { + case SECCOMP_FILTER_FLAG_TSYNC: + if (state.sup_flag_tsync < 0) + state.sup_flag_tsync = _sys_chk_flag_kernel(flag); + return state.sup_flag_tsync; + case SECCOMP_FILTER_FLAG_LOG: + if (state.sup_flag_log < 0) + state.sup_flag_log = _sys_chk_flag_kernel(flag); + return state.sup_flag_log; + case SECCOMP_FILTER_FLAG_SPEC_ALLOW: + if (state.sup_flag_spec_allow < 0) + state.sup_flag_spec_allow = _sys_chk_flag_kernel(flag); + return state.sup_flag_spec_allow; + case SECCOMP_FILTER_FLAG_NEW_LISTENER: + if (state.sup_flag_new_listener < 0) + state.sup_flag_new_listener = _sys_chk_flag_kernel(flag); + return state.sup_flag_new_listener; + case SECCOMP_FILTER_FLAG_TSYNC_ESRCH: + if (state.sup_flag_tsync_esrch < 0) + state.sup_flag_tsync_esrch = _sys_chk_flag_kernel(flag); + return state.sup_flag_tsync_esrch; + } + + return -EOPNOTSUPP; +} + +/** + * Force a seccomp() syscall flag support setting + * @param flag the seccomp() flag + * @param enable the intended support state + * + * This function overrides the current seccomp() syscall support setting for a + * given flag; this is very much a "use at your own risk" function. + * + */ +void sys_set_seccomp_flag(int flag, bool enable) +{ + switch (flag) { + case SECCOMP_FILTER_FLAG_TSYNC: + state.sup_flag_tsync = (enable ? 1 : 0); + break; + case SECCOMP_FILTER_FLAG_LOG: + state.sup_flag_log = (enable ? 1 : 0); + break; + case SECCOMP_FILTER_FLAG_SPEC_ALLOW: + state.sup_flag_spec_allow = (enable ? 1 : 0); + break; + case SECCOMP_FILTER_FLAG_NEW_LISTENER: + state.sup_flag_new_listener = (enable ? 1 : 0); + break; + case SECCOMP_FILTER_FLAG_TSYNC_ESRCH: + state.sup_flag_tsync_esrch = (enable ? 1 : 0); + break; + } +} + +/** + * Loads the filter into the kernel + * @param col the filter collection + * @param rawrc pass the raw return code if true + * + * This function loads the given seccomp filter context into the kernel. If + * the filter was loaded correctly, the kernel will be enforcing the filter + * when this function returns. Returns zero on success, negative values on + * error. + * + */ +int sys_filter_load(struct db_filter_col *col, bool rawrc) +{ + int rc; + bool tsync_notify; + bool listener_req; + struct bpf_program *prgm = NULL; + + rc = gen_bpf_generate(col, &prgm); + if (rc < 0) + return rc; + + /* attempt to set NO_NEW_PRIVS */ + if (col->attr.nnp_enable) { + rc = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0); + if (rc < 0) + goto filter_load_out; + } + + tsync_notify = state.sup_flag_tsync_esrch > 0 && state.notify_fd == -1; + listener_req = state.sup_user_notif > 0 && \ + col->notify_used && state.notify_fd == -1; + + /* load the filter into the kernel */ + if (sys_chk_seccomp_syscall() == 1) { + int flgs = 0; + if (tsync_notify) { + if (col->attr.tsync_enable) + flgs |= SECCOMP_FILTER_FLAG_TSYNC | \ + SECCOMP_FILTER_FLAG_TSYNC_ESRCH; + if (listener_req) + flgs |= SECCOMP_FILTER_FLAG_NEW_LISTENER; + } else if (col->attr.tsync_enable) { + if (listener_req) { + /* NOTE: we _should_ catch this in db.c */ + rc = -EFAULT; + goto filter_load_out; + } + flgs |= SECCOMP_FILTER_FLAG_TSYNC; + } else if (listener_req) + flgs |= SECCOMP_FILTER_FLAG_NEW_LISTENER; + if (col->attr.log_enable) + flgs |= SECCOMP_FILTER_FLAG_LOG; + if (col->attr.spec_allow) + flgs |= SECCOMP_FILTER_FLAG_SPEC_ALLOW; + rc = syscall(state.nr_seccomp, + SECCOMP_SET_MODE_FILTER, flgs, prgm); + if (tsync_notify && rc > 0) { + /* return 0 on NEW_LISTENER success, but save the fd */ + state.notify_fd = rc; + rc = 0; + } else if (rc > 0 && col->attr.tsync_enable) { + /* always return -ESRCH if we fail to sync threads */ + errno = ESRCH; + rc = -errno; + } else if (rc > 0 && state.sup_user_notif > 0) { + /* return 0 on NEW_LISTENER success, but save the fd */ + state.notify_fd = rc; + rc = 0; + } + } else + rc = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, prgm); + +filter_load_out: + /* cleanup and return */ + gen_bpf_release(prgm); + if (rc == -ESRCH) + return -ESRCH; + if (rc < 0) + return (rawrc ? -errno : -ECANCELED); + return rc; +} + +/** + * Return the userspace notification fd + * + * This function returns the userspace notification fd from + * SECCOMP_FILTER_FLAG_NEW_LISTENER. If the notification fd has not yet been + * set, or an error has occurred, -1 is returned. + * + */ +int sys_notify_fd(void) +{ + return state.notify_fd; +} + +/** + * Allocate a pair of notification request/response structures + * @param req the request location + * @param resp the response location + * + * This function allocates a pair of request/response structure by computing + * the correct sized based on the currently running kernel. It returns zero on + * success, and negative values on failure. + * + */ +int sys_notify_alloc(struct seccomp_notif **req, + struct seccomp_notif_resp **resp) +{ + int rc; + static struct seccomp_notif_sizes sizes = { 0, 0, 0 }; + + if (state.sup_syscall <= 0) + return -EOPNOTSUPP; + + if (sizes.seccomp_notif == 0 && sizes.seccomp_notif_resp == 0) { + rc = syscall(__NR_seccomp, SECCOMP_GET_NOTIF_SIZES, 0, &sizes); + if (rc < 0) + return -ECANCELED; + } + if (sizes.seccomp_notif == 0 || sizes.seccomp_notif_resp == 0) + return -EFAULT; + + if (req) { + *req = zmalloc(sizes.seccomp_notif); + if (!*req) + return -ENOMEM; + } + + if (resp) { + *resp = zmalloc(sizes.seccomp_notif_resp); + if (!*resp) { + if (req) + free(*req); + return -ENOMEM; + } + } + + return 0; +} + +/** + * Receive a notification from a seccomp notification fd + * @param fd the notification fd + * @param req the request buffer to save into + * + * Blocks waiting for a notification on this fd. This function is thread safe + * (synchronization is performed in the kernel). Returns zero on success, + * negative values on error. + * + */ +int sys_notify_receive(int fd, struct seccomp_notif *req) +{ + if (state.sup_user_notif <= 0) + return -EOPNOTSUPP; + + if (ioctl(fd, SECCOMP_IOCTL_NOTIF_RECV, req) < 0) + return -ECANCELED; + + return 0; +} + +/** + * Send a notification response to a seccomp notification fd + * @param fd the notification fd + * @param resp the response buffer to use + * + * Sends a notification response on this fd. This function is thread safe + * (synchronization is performed in the kernel). Returns zero on success, + * negative values on error. + * + */ +int sys_notify_respond(int fd, struct seccomp_notif_resp *resp) +{ + if (state.sup_user_notif <= 0) + return -EOPNOTSUPP; + + if (ioctl(fd, SECCOMP_IOCTL_NOTIF_SEND, resp) < 0) + return -ECANCELED; + return 0; +} + +/** + * Check if a notification id is still valid + * @param fd the notification fd + * @param id the id to test + * + * Checks to see if a notification id is still valid. Returns 0 on success, and + * negative values on failure. + * + */ +int sys_notify_id_valid(int fd, uint64_t id) +{ + int rc; + if (state.sup_user_notif <= 0) + return -EOPNOTSUPP; + + rc = ioctl(fd, SECCOMP_IOCTL_NOTIF_ID_VALID, &id); + if (rc < 0 && errno == EINVAL) + /* It is possible that libseccomp was built against newer kernel + * headers than the kernel it is running on. If so, the older + * runtime kernel may not support the "fixed" + * SECCOMP_IOCTL_NOTIF_ID_VALID ioctl number which was introduced in + * kernel commit 47e33c05f9f0 ("seccomp: Fix ioctl number for + * SECCOMP_IOCTL_NOTIF_ID_VALID"). Try the old value. */ + rc = ioctl(fd, SECCOMP_IOCTL_NOTIF_ID_VALID_WRONG_DIR, &id); + if (rc < 0) + return -ENOENT; + return 0; +} diff --git a/src/system.h b/src/system.h new file mode 100644 index 0000000..10d3ccb --- /dev/null +++ b/src/system.h @@ -0,0 +1,207 @@ +/** + * Seccomp System Interfaces + * + * Copyright (c) 2012 Red Hat <pmoore@redhat.com> + * Author: Paul Moore <paul@paul-moore.com> + */ + +/* + * 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>. + */ + +#ifndef _SYSTEM_H +#define _SYSTEM_H + +#include <inttypes.h> +#include <stdbool.h> +#include <linux/filter.h> +#include <linux/types.h> +#include <sys/prctl.h> +#include <sys/ioctl.h> +#include "configure.h" + +/* NOTE: this was taken from the Linux Kernel sources */ +#define MAX_ERRNO 4095 + +struct db_filter_col; + +#ifdef HAVE_LINUX_SECCOMP_H + +/* system header file */ +#include <linux/seccomp.h> + +#else + +/* NOTE: the definitions below were taken from the Linux Kernel sources */ + +/* Valid values for seccomp.mode and prctl(PR_SET_SECCOMP, <mode>) */ +#define SECCOMP_MODE_DISABLED 0 /* seccomp is not in use. */ +#define SECCOMP_MODE_STRICT 1 /* uses hard-coded filter. */ +#define SECCOMP_MODE_FILTER 2 /* uses user-supplied filter. */ + +/* + * All BPF programs must return a 32-bit value. + * The bottom 16-bits are for optional return data. + * The upper 16-bits are ordered from least permissive values to most. + * + * The ordering ensures that a min_t() over composed return values always + * selects the least permissive choice. + */ +#define SECCOMP_RET_KILL_PROCESS 0x80000000U /* kill the process immediately */ +#define SECCOMP_RET_KILL_THREAD 0x00000000U /* kill the thread immediately */ +#define SECCOMP_RET_KILL SECCOMP_RET_KILL_THREAD /* default to killing the thread */ +#define SECCOMP_RET_TRAP 0x00030000U /* disallow and force a SIGSYS */ +#define SECCOMP_RET_ERRNO 0x00050000U /* returns an errno */ +#define SECCOMP_RET_USER_NOTIF 0x7fc00000U /* notifies userspace */ +#define SECCOMP_RET_TRACE 0x7ff00000U /* pass to a tracer or disallow */ +#define SECCOMP_RET_ALLOW 0x7fff0000U /* allow */ + +/* Masks for the return value sections. */ +#define SECCOMP_RET_ACTION 0x7fff0000U +#define SECCOMP_RET_DATA 0x0000ffffU + +/** + * struct seccomp_data - the format the BPF program executes over. + * @nr: the system call number + * @arch: indicates system call convention as an AUDIT_ARCH_* value + * as defined in <linux/audit.h>. + * @instruction_pointer: at the time of the system call. + * @args: up to 6 system call arguments always stored as 64-bit values + * regardless of the architecture. + */ +struct seccomp_data { + int nr; + __u32 arch; + __u64 instruction_pointer; + __u64 args[6]; +}; + +#endif /* HAVE_LINUX_SECCOMP_H */ + +/* rename some of the socket filter types to make more sense */ +typedef struct sock_filter bpf_instr_raw; + +/* no new privs defintions */ +#ifndef PR_SET_NO_NEW_PRIVS +#define PR_SET_NO_NEW_PRIVS 38 +#endif + +#ifndef PR_GET_NO_NEW_PRIVS +#define PR_GET_NO_NEW_PRIVS 39 +#endif + +/* operations for the seccomp() syscall */ +#ifndef SECCOMP_SET_MODE_STRICT +#define SECCOMP_SET_MODE_STRICT 0 +#endif +#ifndef SECCOMP_SET_MODE_FILTER +#define SECCOMP_SET_MODE_FILTER 1 +#endif +#ifndef SECCOMP_GET_ACTION_AVAIL +#define SECCOMP_GET_ACTION_AVAIL 2 +#endif +#ifndef SECCOMP_GET_NOTIF_SIZES +#define SECCOMP_GET_NOTIF_SIZES 3 +#endif + +/* flags for the seccomp() syscall */ +#ifndef SECCOMP_FILTER_FLAG_TSYNC +#define SECCOMP_FILTER_FLAG_TSYNC (1UL << 0) +#endif +#ifndef SECCOMP_FILTER_FLAG_LOG +#define SECCOMP_FILTER_FLAG_LOG (1UL << 1) +#endif +#ifndef SECCOMP_FILTER_FLAG_SPEC_ALLOW +#define SECCOMP_FILTER_FLAG_SPEC_ALLOW (1UL << 2) +#endif +#ifndef SECCOMP_FILTER_FLAG_NEW_LISTENER +#define SECCOMP_FILTER_FLAG_NEW_LISTENER (1UL << 3) +#endif +#ifndef SECCOMP_FILTER_FLAG_TSYNC_ESRCH +#define SECCOMP_FILTER_FLAG_TSYNC_ESRCH (1UL << 4) +#endif + +#ifndef SECCOMP_RET_LOG +#define SECCOMP_RET_LOG 0x7ffc0000U /* allow after logging */ +#endif + +/* SECCOMP_RET_ACTION_FULL was added in kernel v4.14. */ +#ifndef SECCOMP_RET_ACTION_FULL +#define SECCOMP_RET_ACTION_FULL 0xffff0000U +#endif + +/* SECCOMP_RET_LOG was added in kernel v4.14. */ +#ifndef SECCOMP_RET_LOG +#define SECCOMP_RET_LOG 0x7fc00000U +#endif + +/* SECCOMP_RET_USER_NOTIF was added in kernel v5.0. */ +#ifndef SECCOMP_RET_USER_NOTIF +#define SECCOMP_RET_USER_NOTIF 0x7fc00000U + +struct seccomp_notif_sizes { + __u16 seccomp_notif; + __u16 seccomp_notif_resp; + __u16 seccomp_data; +}; + +struct seccomp_notif { + __u64 id; + __u32 pid; + __u32 flags; + struct seccomp_data data; +}; + +struct seccomp_notif_resp { + __u64 id; + __s64 val; + __s32 error; + __u32 flags; +}; + +#define SECCOMP_IOC_MAGIC '!' +#define SECCOMP_IO(nr) _IO(SECCOMP_IOC_MAGIC, nr) +#define SECCOMP_IOR(nr, type) _IOR(SECCOMP_IOC_MAGIC, nr, type) +#define SECCOMP_IOW(nr, type) _IOW(SECCOMP_IOC_MAGIC, nr, type) +#define SECCOMP_IOWR(nr, type) _IOWR(SECCOMP_IOC_MAGIC, nr, type) + +/* flags for seccomp notification fd ioctl */ +#define SECCOMP_IOCTL_NOTIF_RECV SECCOMP_IOWR(0, struct seccomp_notif) +#define SECCOMP_IOCTL_NOTIF_SEND SECCOMP_IOWR(1, \ + struct seccomp_notif_resp) +#define SECCOMP_IOCTL_NOTIF_ID_VALID SECCOMP_IOW(2, __u64) +#endif /* SECCOMP_RET_USER_NOTIF */ + +/* non-public ioctl number for backwards compat (see system.c) */ +#define SECCOMP_IOCTL_NOTIF_ID_VALID_WRONG_DIR SECCOMP_IOR(2, __u64) + +void sys_reset_state(void); + +int sys_chk_seccomp_syscall(void); +void sys_set_seccomp_syscall(bool enable); + +int sys_chk_seccomp_action(uint32_t action); +void sys_set_seccomp_action(uint32_t action, bool enable); + +int sys_chk_seccomp_flag(int flag); +void sys_set_seccomp_flag(int flag, bool enable); + +int sys_filter_load(struct db_filter_col *col, bool rawrc); + +int sys_notify_fd(void); +int sys_notify_alloc(struct seccomp_notif **req, + struct seccomp_notif_resp **resp); +int sys_notify_receive(int fd, struct seccomp_notif *req); +int sys_notify_respond(int fd, struct seccomp_notif_resp *resp); +int sys_notify_id_valid(int fd, uint64_t id); +#endif |