From 81749f1fe87e489c4e2e7408a0fae9370c3810b3 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Mon, 15 Apr 2024 19:09:30 +0200 Subject: Adding upstream version 2.5.5. Signed-off-by: Daniel Baumann --- tools/Makefile.am | 41 +++ tools/Makefile.in | 780 ++++++++++++++++++++++++++++++++++++++++++++++ tools/bpf.h | 131 ++++++++ tools/check-syntax | 161 ++++++++++ tools/scmp_api_level.c | 39 +++ tools/scmp_app_inspector | 103 ++++++ tools/scmp_arch_detect.c | 133 ++++++++ tools/scmp_bpf_disasm.c | 541 ++++++++++++++++++++++++++++++++ tools/scmp_bpf_sim.c | 370 ++++++++++++++++++++++ tools/scmp_sys_resolver.c | 96 ++++++ tools/util.c | 152 +++++++++ tools/util.h | 90 ++++++ 12 files changed, 2637 insertions(+) create mode 100644 tools/Makefile.am create mode 100644 tools/Makefile.in create mode 100644 tools/bpf.h create mode 100755 tools/check-syntax create mode 100644 tools/scmp_api_level.c create mode 100755 tools/scmp_app_inspector create mode 100644 tools/scmp_arch_detect.c create mode 100644 tools/scmp_bpf_disasm.c create mode 100644 tools/scmp_bpf_sim.c create mode 100644 tools/scmp_sys_resolver.c create mode 100644 tools/util.c create mode 100644 tools/util.h (limited to 'tools') diff --git a/tools/Makefile.am b/tools/Makefile.am new file mode 100644 index 0000000..92543a1 --- /dev/null +++ b/tools/Makefile.am @@ -0,0 +1,41 @@ +#### +# Seccomp Library Utility Tools +# + +# +# 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 . +# + +noinst_LTLIBRARIES = util.la +util_la_SOURCES = util.c util.h bpf.h +util_la_LDFLAGS = -module + +bin_PROGRAMS = \ + scmp_sys_resolver +noinst_PROGRAMS = \ + scmp_arch_detect \ + scmp_bpf_disasm \ + scmp_bpf_sim \ + scmp_api_level + +EXTRA_DIST = check-syntax scmp_app_inspector + +scmp_bpf_disasm_SOURCES = scmp_bpf_disasm.c bpf.h util.h +scmp_bpf_sim_SOURCES = scmp_bpf_sim.c bpf.h util.h +scmp_api_level_SOURCES = scmp_api_level.c + +scmp_sys_resolver_LDADD = ../src/libseccomp.la +scmp_arch_detect_LDADD = ../src/libseccomp.la +scmp_bpf_disasm_LDADD = util.la +scmp_bpf_sim_LDADD = util.la +scmp_api_level_LDADD = ../src/libseccomp.la diff --git a/tools/Makefile.in b/tools/Makefile.in new file mode 100644 index 0000000..5ad2a6e --- /dev/null +++ b/tools/Makefile.in @@ -0,0 +1,780 @@ +# 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 Utility Tools +# + +# +# 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 . +# + + +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@ +bin_PROGRAMS = scmp_sys_resolver$(EXEEXT) +noinst_PROGRAMS = scmp_arch_detect$(EXEEXT) scmp_bpf_disasm$(EXEEXT) \ + scmp_bpf_sim$(EXEEXT) scmp_api_level$(EXEEXT) +subdir = tools +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__installdirs = "$(DESTDIR)$(bindir)" +PROGRAMS = $(bin_PROGRAMS) $(noinst_PROGRAMS) +LTLIBRARIES = $(noinst_LTLIBRARIES) +util_la_LIBADD = +am_util_la_OBJECTS = util.lo +util_la_OBJECTS = $(am_util_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 = +util_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(util_la_LDFLAGS) $(LDFLAGS) -o $@ +am_scmp_api_level_OBJECTS = scmp_api_level.$(OBJEXT) +scmp_api_level_OBJECTS = $(am_scmp_api_level_OBJECTS) +scmp_api_level_DEPENDENCIES = ../src/libseccomp.la +scmp_arch_detect_SOURCES = scmp_arch_detect.c +scmp_arch_detect_OBJECTS = scmp_arch_detect.$(OBJEXT) +scmp_arch_detect_DEPENDENCIES = ../src/libseccomp.la +am_scmp_bpf_disasm_OBJECTS = scmp_bpf_disasm.$(OBJEXT) +scmp_bpf_disasm_OBJECTS = $(am_scmp_bpf_disasm_OBJECTS) +scmp_bpf_disasm_DEPENDENCIES = util.la +am_scmp_bpf_sim_OBJECTS = scmp_bpf_sim.$(OBJEXT) +scmp_bpf_sim_OBJECTS = $(am_scmp_bpf_sim_OBJECTS) +scmp_bpf_sim_DEPENDENCIES = util.la +scmp_sys_resolver_SOURCES = scmp_sys_resolver.c +scmp_sys_resolver_OBJECTS = scmp_sys_resolver.$(OBJEXT) +scmp_sys_resolver_DEPENDENCIES = ../src/libseccomp.la +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)/scmp_api_level.Po \ + ./$(DEPDIR)/scmp_arch_detect.Po ./$(DEPDIR)/scmp_bpf_disasm.Po \ + ./$(DEPDIR)/scmp_bpf_sim.Po ./$(DEPDIR)/scmp_sys_resolver.Po \ + ./$(DEPDIR)/util.Plo +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 = $(util_la_SOURCES) $(scmp_api_level_SOURCES) \ + scmp_arch_detect.c $(scmp_bpf_disasm_SOURCES) \ + $(scmp_bpf_sim_SOURCES) scmp_sys_resolver.c +DIST_SOURCES = $(util_la_SOURCES) $(scmp_api_level_SOURCES) \ + scmp_arch_detect.c $(scmp_bpf_disasm_SOURCES) \ + $(scmp_bpf_sim_SOURCES) scmp_sys_resolver.c +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) +# 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__DIST_COMMON = $(srcdir)/Makefile.in \ + $(top_srcdir)/build-aux/depcomp +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@ +noinst_LTLIBRARIES = util.la +util_la_SOURCES = util.c util.h bpf.h +util_la_LDFLAGS = -module +EXTRA_DIST = check-syntax scmp_app_inspector +scmp_bpf_disasm_SOURCES = scmp_bpf_disasm.c bpf.h util.h +scmp_bpf_sim_SOURCES = scmp_bpf_sim.c bpf.h util.h +scmp_api_level_SOURCES = scmp_api_level.c +scmp_sys_resolver_LDADD = ../src/libseccomp.la +scmp_arch_detect_LDADD = ../src/libseccomp.la +scmp_bpf_disasm_LDADD = util.la +scmp_bpf_sim_LDADD = util.la +scmp_api_level_LDADD = ../src/libseccomp.la +all: all-am + +.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 tools/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --foreign tools/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): +install-binPROGRAMS: $(bin_PROGRAMS) + @$(NORMAL_INSTALL) + @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ + if test -n "$$list"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(bindir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(bindir)" || exit 1; \ + fi; \ + for p in $$list; do echo "$$p $$p"; done | \ + sed 's/$(EXEEXT)$$//' | \ + while read p p1; do if test -f $$p \ + || test -f $$p1 \ + ; then echo "$$p"; echo "$$p"; else :; fi; \ + done | \ + sed -e 'p;s,.*/,,;n;h' \ + -e 's|.*|.|' \ + -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \ + sed 'N;N;N;s,\n, ,g' | \ + $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \ + { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ + if ($$2 == $$4) files[d] = files[d] " " $$1; \ + else { print "f", $$3 "/" $$4, $$1; } } \ + END { for (d in files) print "f", d, files[d] }' | \ + while read type dir files; do \ + if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ + test -z "$$files" || { \ + echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(bindir)$$dir'"; \ + $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \ + } \ + ; done + +uninstall-binPROGRAMS: + @$(NORMAL_UNINSTALL) + @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ + files=`for p in $$list; do echo "$$p"; done | \ + sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \ + -e 's/$$/$(EXEEXT)/' \ + `; \ + test -n "$$list" || exit 0; \ + echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \ + cd "$(DESTDIR)$(bindir)" && rm -f $$files + +clean-binPROGRAMS: + @list='$(bin_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 + +clean-noinstPROGRAMS: + @list='$(noinst_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 + +clean-noinstLTLIBRARIES: + -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) + @list='$(noinst_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}; \ + } + +util.la: $(util_la_OBJECTS) $(util_la_DEPENDENCIES) $(EXTRA_util_la_DEPENDENCIES) + $(AM_V_CCLD)$(util_la_LINK) $(util_la_OBJECTS) $(util_la_LIBADD) $(LIBS) + +scmp_api_level$(EXEEXT): $(scmp_api_level_OBJECTS) $(scmp_api_level_DEPENDENCIES) $(EXTRA_scmp_api_level_DEPENDENCIES) + @rm -f scmp_api_level$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(scmp_api_level_OBJECTS) $(scmp_api_level_LDADD) $(LIBS) + +scmp_arch_detect$(EXEEXT): $(scmp_arch_detect_OBJECTS) $(scmp_arch_detect_DEPENDENCIES) $(EXTRA_scmp_arch_detect_DEPENDENCIES) + @rm -f scmp_arch_detect$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(scmp_arch_detect_OBJECTS) $(scmp_arch_detect_LDADD) $(LIBS) + +scmp_bpf_disasm$(EXEEXT): $(scmp_bpf_disasm_OBJECTS) $(scmp_bpf_disasm_DEPENDENCIES) $(EXTRA_scmp_bpf_disasm_DEPENDENCIES) + @rm -f scmp_bpf_disasm$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(scmp_bpf_disasm_OBJECTS) $(scmp_bpf_disasm_LDADD) $(LIBS) + +scmp_bpf_sim$(EXEEXT): $(scmp_bpf_sim_OBJECTS) $(scmp_bpf_sim_DEPENDENCIES) $(EXTRA_scmp_bpf_sim_DEPENDENCIES) + @rm -f scmp_bpf_sim$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(scmp_bpf_sim_OBJECTS) $(scmp_bpf_sim_LDADD) $(LIBS) + +scmp_sys_resolver$(EXEEXT): $(scmp_sys_resolver_OBJECTS) $(scmp_sys_resolver_DEPENDENCIES) $(EXTRA_scmp_sys_resolver_DEPENDENCIES) + @rm -f scmp_sys_resolver$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(scmp_sys_resolver_OBJECTS) $(scmp_sys_resolver_LDADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/scmp_api_level.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/scmp_arch_detect.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/scmp_bpf_disasm.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/scmp_bpf_sim.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/scmp_sys_resolver.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/util.Plo@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 $@ $< + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-am +TAGS: tags + +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + set x; \ + here=`pwd`; \ + $(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-am + +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-am + +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 +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 $(PROGRAMS) $(LTLIBRARIES) +installdirs: + for dir in "$(DESTDIR)$(bindir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +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-binPROGRAMS clean-generic clean-libtool \ + clean-noinstLTLIBRARIES clean-noinstPROGRAMS mostlyclean-am + +distclean: distclean-am + -rm -f ./$(DEPDIR)/scmp_api_level.Po + -rm -f ./$(DEPDIR)/scmp_arch_detect.Po + -rm -f ./$(DEPDIR)/scmp_bpf_disasm.Po + -rm -f ./$(DEPDIR)/scmp_bpf_sim.Po + -rm -f ./$(DEPDIR)/scmp_sys_resolver.Po + -rm -f ./$(DEPDIR)/util.Plo + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +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-binPROGRAMS + +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 ./$(DEPDIR)/scmp_api_level.Po + -rm -f ./$(DEPDIR)/scmp_arch_detect.Po + -rm -f ./$(DEPDIR)/scmp_bpf_disasm.Po + -rm -f ./$(DEPDIR)/scmp_bpf_sim.Po + -rm -f ./$(DEPDIR)/scmp_sys_resolver.Po + -rm -f ./$(DEPDIR)/util.Plo + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-binPROGRAMS + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ + clean-binPROGRAMS clean-generic clean-libtool \ + clean-noinstLTLIBRARIES clean-noinstPROGRAMS 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-binPROGRAMS \ + 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-man install-pdf \ + install-pdf-am install-ps install-ps-am install-strip \ + installcheck installcheck-am installdirs 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-binPROGRAMS + +.PRECIOUS: Makefile + + +# 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/tools/bpf.h b/tools/bpf.h new file mode 100644 index 0000000..fd20441 --- /dev/null +++ b/tools/bpf.h @@ -0,0 +1,131 @@ +/** + * BPF Language Definitions + * + * Copyright (c) 2012 Red Hat + * Author: Paul Moore + */ + +/* + * 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 . + */ + +#ifndef _BPF_H +#define _BPF_H + +#include +#include + +/* most of these structures and values are designed to match the Linux Kernel's + * BPF interface (see /usr/include/linux/{filter,seccomp}.h), but we define our + * own here so that we can function independent of the host OS */ + +/* XXX - need to verify these values */ +#define BPF_SCRATCH_SIZE 6 + +/** + * Syscall record data format used by seccomp + */ +#define BPF_SYS_ARG_MAX 6 +struct seccomp_data { + int32_t nr; + uint32_t arch; + uint64_t instruction_pointer; + uint64_t args[BPF_SYS_ARG_MAX]; +}; +#define BPF_SYSCALL_MAX (sizeof(struct seccomp_data)) + +/** + * BPF instruction format + */ +struct sock_filter { + uint16_t code; + uint8_t jt; + uint8_t jf; + uint32_t k; +} __attribute__ ((packed)); +typedef struct sock_filter bpf_instr_raw; + +/* seccomp return masks */ +#define SECCOMP_RET_ACTION_FULL 0xffff0000U +#define SECCOMP_RET_ACTION 0x7fff0000U +#define SECCOMP_RET_DATA 0x0000ffffU + +/* seccomp action values */ +#define SECCOMP_RET_KILL_PROCESS 0x80000000U +#define SECCOMP_RET_KILL_THREAD 0x00000000U +#define SECCOMP_RET_KILL SECCOMP_RET_KILL_THREAD +#define SECCOMP_RET_TRAP 0x00030000U +#define SECCOMP_RET_ERRNO 0x00050000U +#define SECCOMP_RET_TRACE 0x7ff00000U +#define SECCOMP_RET_LOG 0x7ffc0000U +#define SECCOMP_RET_ALLOW 0x7fff0000U + +/* bpf command classes */ +#define BPF_CLASS(code) ((code) & 0x07) +#define BPF_LD 0x00 +#define BPF_LDX 0x01 +#define BPF_ST 0x02 +#define BPF_STX 0x03 +#define BPF_ALU 0x04 +#define BPF_JMP 0x05 +#define BPF_RET 0x06 +#define BPF_MISC 0x07 + +/* BPF_LD and BPF_LDX */ +#define BPF_SIZE(code) ((code) & 0x18) +#define BPF_W 0x00 +#define BPF_H 0x08 +#define BPF_B 0x10 +#define BPF_MODE(code) ((code) & 0xe0) +#define BPF_IMM 0x00 +#define BPF_ABS 0x20 +#define BPF_IND 0x40 +#define BPF_MEM 0x60 +#define BPF_LEN 0x80 +#define BPF_MSH 0xa0 + +#define BPF_OP(code) ((code) & 0xf0) +/* BPF_ALU */ +#define BPF_ADD 0x00 +#define BPF_SUB 0x10 +#define BPF_MUL 0x20 +#define BPF_DIV 0x30 +#define BPF_OR 0x40 +#define BPF_AND 0x50 +#define BPF_LSH 0x60 +#define BPF_RSH 0x70 +#define BPF_NEG 0x80 +#define BPF_MOD 0x90 +#define BPF_XOR 0xa0 + +/* BPF_JMP */ +#define BPF_JA 0x00 +#define BPF_JEQ 0x10 +#define BPF_JGT 0x20 +#define BPF_JGE 0x30 +#define BPF_JSET 0x40 + +#define BPF_SRC(code) ((code) & 0x08) +#define BPF_K 0x00 +#define BPF_X 0x08 + +/* BPF_RET (BPF_K and BPF_X also apply) */ +#define BPF_RVAL(code) ((code) & 0x18) +#define BPF_A 0x10 + +/* BPF_MISC */ +#define BPF_MISCOP(code) ((code) & 0xf8) +#define BPF_TAX 0x00 +#define BPF_TXA 0x80 + +#endif diff --git a/tools/check-syntax b/tools/check-syntax new file mode 100755 index 0000000..42790d3 --- /dev/null +++ b/tools/check-syntax @@ -0,0 +1,161 @@ +#!/bin/bash + +# +# libseccomp code syntax checking tool +# +# Copyright (c) 2013,2015 Red Hat +# Author: Paul Moore +# + +# +# 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 . +# + +CHK_C_LIST="include/seccomp.h.in \ + include/seccomp-syscalls.h \ + src/*.c src/*.h \ + tests/*.c tests/*.h \ + tools/*.c tools/*.h" +CHK_C_EXCLUDE="src/syscalls.perf.c" + +#### +# functions + +# +# Dependency verification +# +# Arguments: +# 1 Dependency to check for +# +function verify_deps() { + [[ -z "$1" ]] && return + if ! which "$1" >& /dev/null; then + echo "error: install \"$1\" and include it in your \$PATH" + exit 1 + fi +} + +# +# Print out script usage details +# +function usage() { +cat << EOF +usage: check-syntax [-h] + +libseccomp code syntax checking tool +optional arguments: + -h show this help message and exit + -f fix the file formatting +EOF +} + +# +# Generate a properly formatted C source/header file +# +# Arguments: +# 1 Source file +# +function tool_c_style() { + astyle --options=none --lineend=linux --mode=c \ + --style=linux \ + --indent=force-tab=8 \ + --indent-preprocessor \ + --indent-col1-comments \ + --min-conditional-indent=0 \ + --max-instatement-indent=80 \ + --pad-oper \ + --align-pointer=name \ + --align-reference=name \ + --max-code-length=80 \ + --break-after-logical < "$1" +} + +# +# Check the formatting on a C source/header file +# +# Arguments: +# 1 File to check +# +function tool_c_style_check() { + [[ -z "$1" || ! -r "$1" ]] && return + + tool_c_style "$1" | diff -pu --label="$1.orig" "$1" --label="$1" - +} + +# +# Fix the formatting on a C source/header file +# +# Arguments: +# 1 File to fix +# +function tool_c_style_fix() { + [[ -z "$1" || ! -r "$1" ]] && return + + tmp="$(mktemp --tmpdir=$(dirname "$1"))" + tool_c_style "$1" > "$tmp" + mv "$tmp" "$1" +} + +# +# Perform all known syntax checks for the configured C sources/headers +# +function check_c() { + for i in $CHK_C_LIST; do + echo "$CHK_C_EXCLUDE" | grep -q "$i" && continue + echo "Differences for $i" + tool_c_style_check "$i" + done +} + +# +# Perform all known syntax fixess for the configured C sources/headers +# +function fix_c() { + for i in $CHK_C_LIST; do + echo "$CHK_C_EXCLUDE" | grep -q "$i" && continue + echo "Fixing $i" + tool_c_style_fix "$i" + done +} + +#### +# main + +verify_deps astyle + +opt_fix=0 + +while getopts "fh" opt; do + case $opt in + f) + opt_fix=1 + ;; + h|*) + usage + exit 1 + ;; + esac +done + +# display the results +echo "=============== $(date) ===============" +echo "Code Syntax Check Results (\"check-syntax $*\")" +if [[ $opt_fix -eq 1 ]]; then + fix_c +else + check_c +fi +echo "============================================================" + +# exit +exit 0 diff --git a/tools/scmp_api_level.c b/tools/scmp_api_level.c new file mode 100644 index 0000000..01ed7b8 --- /dev/null +++ b/tools/scmp_api_level.c @@ -0,0 +1,39 @@ +/** + * API Level Detector + * + * Copyright (c) 2018 Paul Moore + * Author: Paul Moore + */ + +/* + * 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 . + */ + +#include +#include +#include + +#include + +/** + * main + */ +int main(int argc, char *argv[]) +{ + unsigned int level; + + level = seccomp_api_get(); + printf("%d\n", level); + + return 0; +} diff --git a/tools/scmp_app_inspector b/tools/scmp_app_inspector new file mode 100755 index 0000000..45b86b2 --- /dev/null +++ b/tools/scmp_app_inspector @@ -0,0 +1,103 @@ +#!/bin/bash + +# +# Runtime syscall inspector +# +# Copyright (c) 2012 Red Hat +# Author: Paul Moore +# + +# +# 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 . +# + +#### +# functions + +function verify_deps() { + [[ -z "$1" ]] && return + if ! which "$1" >& /dev/null; then + echo "error: install \"$1\" and include it in your \$PATH" + exit 1 + fi +} + +#### +# main + +# verify script dependencies +verify_deps strace +verify_deps sed +verify_deps sort +verify_deps uniq + +# get the command line arguments +opt_freq=0 +opt_args=0 +opt_out="/proc/self/fd/1" +while getopts "afo:h" opt; do + case $opt in + a) + opt_args=1 + ;; + f) + opt_freq=1 + ;; + o) + opt_out="$OPTARG" + ;; + h|*) + echo "usage $0 [-f] [-a] [-o ] []" + exit 1 + esac +done +shift $(expr $OPTIND - 1) + +# generate a temporary output file +raw=$(mktemp -t strace-raw_XXXXXX) +out="$raw-out" + +# capture the strace output +strace -o $raw -- $* + +# filter the raw strace +if [[ $opt_args -eq 0 ]]; then + if [[ $opt_freq -eq 0 ]]; then + cat $raw | sed -e 's/(.*//' | sort -u > $out + else + cat $raw | sed -e 's/(.*//' | sort | uniq -c | sort -nr > $out + fi +else + if [[ $opt_freq -eq 0 ]]; then + cat $raw | sed -e 's/)[ \t]*=.*$/)/' \ + | sed -e 's/".*,/"...",/g;s/\/\*.*\*\//.../g' \ + | sed -e 's/0x[a-f0-9]\+/.../g' \ + | sort -u > $out + else + cat $raw | sed -e 's/)[ \t]*=.*$/)/' \ + | sed -e 's/".*,/"...",/g;s/\/\*.*\*\//.../g' \ + | sed -e 's/0x[a-f0-9]\+/.../g' \ + | sort | uniq -c | sort -nr > $out + fi +fi + +# display the output +echo "============================================================" > $opt_out +echo "Syscall Report (\"$*\")" >> $opt_out +[[ $opt_freq -eq 1 ]] && echo " freq syscall" >> $opt_out +echo "============================================================" >> $opt_out +cat $out >> $opt_out + +# cleanup and exit +rm -f $raw $out +exit 0 diff --git a/tools/scmp_arch_detect.c b/tools/scmp_arch_detect.c new file mode 100644 index 0000000..b844a68 --- /dev/null +++ b/tools/scmp_arch_detect.c @@ -0,0 +1,133 @@ +/** + * Architecture Detector + * + * Copyright (c) 2013 Red Hat + * Author: Paul Moore + */ + +/* + * 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 . + */ + +#include +#include +#include +#include + +#include + +/** + * 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] [-t]\n", + program); + exit(EINVAL); +} + +/** + * main + */ +int main(int argc, char *argv[]) +{ + int opt; + int token = 0; + uint32_t arch; + + /* parse the command line */ + while ((opt = getopt(argc, argv, "ht")) > 0) { + switch (opt) { + case 't': + token = 1; + break; + case 'h': + default: + /* usage information */ + exit_usage(argv[0]); + } + } + + arch = seccomp_arch_native(); + if (token == 0) { + switch (arch) { + case SCMP_ARCH_X86: + printf("x86\n"); + break; + case SCMP_ARCH_X86_64: + printf("x86_64\n"); + break; + case SCMP_ARCH_X32: + printf("x32\n"); + break; + case SCMP_ARCH_ARM: + printf("arm\n"); + break; + case SCMP_ARCH_AARCH64: + printf("aarch64\n"); + break; + case SCMP_ARCH_MIPS: + printf("mips\n"); + break; + case SCMP_ARCH_MIPSEL: + printf("mipsel\n"); + break; + case SCMP_ARCH_MIPS64: + printf("mips64\n"); + break; + case SCMP_ARCH_MIPSEL64: + printf("mipsel64\n"); + break; + case SCMP_ARCH_MIPS64N32: + printf("mips64n32\n"); + break; + case SCMP_ARCH_MIPSEL64N32: + printf("mipsel64n32\n"); + break; + case SCMP_ARCH_PARISC: + printf("parisc\n"); + break; + case SCMP_ARCH_PARISC64: + printf("parisc64\n"); + break; + case SCMP_ARCH_PPC: + printf("ppc\n"); + break; + case SCMP_ARCH_PPC64: + printf("ppc64\n"); + break; + case SCMP_ARCH_PPC64LE: + printf("ppc64le\n"); + break; + case SCMP_ARCH_S390: + printf("s390\n"); + break; + case SCMP_ARCH_S390X: + printf("s390x\n"); + break; + case SCMP_ARCH_RISCV64: + printf("riscv64\n"); + break; + default: + printf("unknown\n"); + } + } else + printf("%d\n", arch); + + return 0; +} diff --git a/tools/scmp_bpf_disasm.c b/tools/scmp_bpf_disasm.c new file mode 100644 index 0000000..b682de7 --- /dev/null +++ b/tools/scmp_bpf_disasm.c @@ -0,0 +1,541 @@ +/** + * BPF Disassembler + * + * Copyright (c) 2012 Red Hat + * Author: Paul Moore + */ + +/* + * 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 . + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "bpf.h" +#include "util.h" + +#define _OP_FMT "%-3s" + +/** + * 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 -a [-d] [-h]\n", program); + exit(EINVAL); +} + +/** + * Decode the BPF operand + * @param bpf the BPF instruction + * + * Decode the BPF operand and print it to stdout. + * + */ +static const char *bpf_decode_op(const bpf_instr_raw *bpf) +{ + switch (bpf->code) { + case BPF_LD+BPF_W+BPF_IMM: + case BPF_LD+BPF_W+BPF_ABS: + case BPF_LD+BPF_W+BPF_IND: + case BPF_LD+BPF_W+BPF_MEM: + case BPF_LD+BPF_W+BPF_LEN: + case BPF_LD+BPF_W+BPF_MSH: + return "ld"; + case BPF_LD+BPF_H+BPF_IMM: + case BPF_LD+BPF_H+BPF_ABS: + case BPF_LD+BPF_H+BPF_IND: + case BPF_LD+BPF_H+BPF_MEM: + case BPF_LD+BPF_H+BPF_LEN: + case BPF_LD+BPF_H+BPF_MSH: + return "ldh"; + case BPF_LD+BPF_B+BPF_IMM: + case BPF_LD+BPF_B+BPF_ABS: + case BPF_LD+BPF_B+BPF_IND: + case BPF_LD+BPF_B+BPF_MEM: + case BPF_LD+BPF_B+BPF_LEN: + case BPF_LD+BPF_B+BPF_MSH: + return "ldb"; + case BPF_LDX+BPF_W+BPF_IMM: + case BPF_LDX+BPF_W+BPF_ABS: + case BPF_LDX+BPF_W+BPF_IND: + case BPF_LDX+BPF_W+BPF_MEM: + case BPF_LDX+BPF_W+BPF_LEN: + case BPF_LDX+BPF_W+BPF_MSH: + case BPF_LDX+BPF_H+BPF_IMM: + case BPF_LDX+BPF_H+BPF_ABS: + case BPF_LDX+BPF_H+BPF_IND: + case BPF_LDX+BPF_H+BPF_MEM: + case BPF_LDX+BPF_H+BPF_LEN: + case BPF_LDX+BPF_H+BPF_MSH: + case BPF_LDX+BPF_B+BPF_IMM: + case BPF_LDX+BPF_B+BPF_ABS: + case BPF_LDX+BPF_B+BPF_IND: + case BPF_LDX+BPF_B+BPF_MEM: + case BPF_LDX+BPF_B+BPF_LEN: + case BPF_LDX+BPF_B+BPF_MSH: + return "ldx"; + case BPF_ST: + return "st"; + case BPF_STX: + return "stx"; + case BPF_ALU+BPF_ADD+BPF_K: + case BPF_ALU+BPF_ADD+BPF_X: + return "add"; + case BPF_ALU+BPF_SUB+BPF_K: + case BPF_ALU+BPF_SUB+BPF_X: + return "sub"; + case BPF_ALU+BPF_MUL+BPF_K: + case BPF_ALU+BPF_MUL+BPF_X: + return "mul"; + case BPF_ALU+BPF_DIV+BPF_K: + case BPF_ALU+BPF_DIV+BPF_X: + return "div"; + case BPF_ALU+BPF_OR+BPF_K: + case BPF_ALU+BPF_OR+BPF_X: + return "or"; + case BPF_ALU+BPF_AND+BPF_K: + case BPF_ALU+BPF_AND+BPF_X: + return "and"; + case BPF_ALU+BPF_LSH+BPF_K: + case BPF_ALU+BPF_LSH+BPF_X: + return "lsh"; + case BPF_ALU+BPF_RSH+BPF_K: + case BPF_ALU+BPF_RSH+BPF_X: + return "rsh"; + case BPF_ALU+BPF_NEG+BPF_K: + case BPF_ALU+BPF_NEG+BPF_X: + return "neg"; + case BPF_ALU+BPF_MOD+BPF_K: + case BPF_ALU+BPF_MOD+BPF_X: + return "mod"; + case BPF_ALU+BPF_XOR+BPF_K: + case BPF_ALU+BPF_XOR+BPF_X: + return "xor"; + case BPF_JMP+BPF_JA+BPF_K: + case BPF_JMP+BPF_JA+BPF_X: + return "jmp"; + case BPF_JMP+BPF_JEQ+BPF_K: + case BPF_JMP+BPF_JEQ+BPF_X: + return "jeq"; + case BPF_JMP+BPF_JGT+BPF_K: + case BPF_JMP+BPF_JGT+BPF_X: + return "jgt"; + case BPF_JMP+BPF_JGE+BPF_K: + case BPF_JMP+BPF_JGE+BPF_X: + return "jge"; + case BPF_JMP+BPF_JSET+BPF_K: + case BPF_JMP+BPF_JSET+BPF_X: + return "jset"; + case BPF_RET+BPF_K: + case BPF_RET+BPF_X: + case BPF_RET+BPF_A: + return "ret"; + case BPF_MISC+BPF_TAX: + return "tax"; + case BPF_MISC+BPF_TXA: + return "txa"; + } + return "???"; +} + +/** + * Decode a RET action + * @param k the return action + * + * Decode the action and print it to stdout. + * + */ +static void bpf_decode_action(uint32_t k) +{ + uint32_t act = k & SECCOMP_RET_ACTION_FULL; + uint32_t data = k & SECCOMP_RET_DATA; + + switch (act) { + case SECCOMP_RET_KILL_PROCESS: + printf("KILL_PROCESS"); + break; + case SECCOMP_RET_KILL_THREAD: + printf("KILL"); + break; + case SECCOMP_RET_TRAP: + printf("TRAP"); + break; + case SECCOMP_RET_ERRNO: + printf("ERRNO(%u)", data); + break; + case SECCOMP_RET_TRACE: + printf("TRACE(%u)", data); + break; + case SECCOMP_RET_LOG: + printf("LOG"); + break; + case SECCOMP_RET_ALLOW: + printf("ALLOW"); + break; + default: + printf("0x%.8x", k); + } +} + +/** + * Decode the BPF arguments (JT, JF, and K) + * @param bpf the BPF instruction + * @param line the current line number + * + * Decode the BPF arguments (JT, JF, and K) and print the relevant information + * to stdout based on the operand. + * + */ +static void bpf_decode_args(const bpf_instr_raw *bpf, unsigned int line) +{ + switch (BPF_CLASS(bpf->code)) { + case BPF_LD: + case BPF_LDX: + switch (BPF_MODE(bpf->code)) { + case BPF_ABS: + printf("$data[%u]", bpf->k); + break; + case BPF_MEM: + printf("$temp[%u]", bpf->k); + break; + case BPF_IMM: + printf("%u", bpf->k); + break; + case BPF_IND: + printf("$data[X + %u]", bpf->k); + break; + case BPF_LEN: + printf("len($data)"); + break; + case BPF_MSH: + printf("4 * $data[%u] & 0x0f", bpf->k); + break; + } + break; + case BPF_ST: + case BPF_STX: + printf("$temp[%u]", bpf->k); + break; + case BPF_ALU: + if (BPF_SRC(bpf->code) == BPF_K) { + switch (BPF_OP(bpf->code)) { + case BPF_OR: + case BPF_AND: + printf("0x%.8x", bpf->k); + break; + default: + printf("%u", bpf->k); + } + } else + printf("%u", bpf->k); + break; + case BPF_JMP: + if (BPF_OP(bpf->code) == BPF_JA) { + printf("%.4u", (line + 1) + bpf->k); + } else { + printf("%-4u true:%.4u false:%.4u", + bpf->k, + (line + 1) + bpf->jt, + (line + 1) + bpf->jf); + } + break; + case BPF_RET: + if (BPF_RVAL(bpf->code) == BPF_A) { + /* XXX - accumulator? */ + printf("$acc"); + } else if (BPF_SRC(bpf->code) == BPF_K) { + bpf_decode_action(bpf->k); + } else if (BPF_SRC(bpf->code) == BPF_X) { + /* XXX - any idea? */ + printf("???"); + } + break; + case BPF_MISC: + break; + default: + printf("???"); + } +} + +/** + * Perform a simple decoding of the BPF program + * @param file the BPF program + * + * Read the BPF program and display the instructions. Returns zero on success, + * non-zero values on failure. + * + */ +static int bpf_decode(FILE *file) +{ + unsigned int line = 0; + bpf_instr_raw bpf; + + /* header */ + printf(" line OP JT JF K\n"); + printf("=================================\n"); + + while (fread(&bpf, sizeof(bpf), 1, file)) { + /* convert the bpf statement */ + bpf.code = ttoh16(arch, bpf.code); + bpf.k = ttoh32(arch, bpf.k); + + /* display a hex dump */ + printf(" %.4u: 0x%.2x 0x%.2x 0x%.2x 0x%.8x", + line, bpf.code, bpf.jt, bpf.jf, bpf.k); + + /* display the assembler statements */ + printf(" "); + printf(_OP_FMT, bpf_decode_op(&bpf)); + printf(" "); + bpf_decode_args(&bpf, line); + printf("\n"); + + line++; + } + + if (ferror(file)) + return errno; + return 0; +} + +/** + * Decode the BPF arguments (JT, JF, and K) + * @param bpf the BPF instruction + * @param line the current line number + * + * Decode the BPF arguments (JT, JF, and K) and print the relevant information + * to stdout based on the operand. + * + */ +static void bpf_dot_decode_args(const bpf_instr_raw *bpf, unsigned int line) +{ + const char *op = bpf_decode_op(bpf); + + printf("\tline%d[label=\"%s", line, op); + switch (BPF_CLASS(bpf->code)) { + case BPF_LD: + case BPF_LDX: + switch (BPF_MODE(bpf->code)) { + case BPF_ABS: + printf(" $data[%u]\",shape=parallelogram]\n", bpf->k); + break; + case BPF_MEM: + printf(" $temp[%u]\",shape=parallelogram]\n", bpf->k); + break; + case BPF_IMM: + printf(" %u\",shape=parallelogram]\n", bpf->k); + break; + case BPF_IND: + printf(" $data[X + %u]\",shape=parallelogram]\n", bpf->k); + break; + case BPF_LEN: + printf(" len($data)\",shape=parallelogram]\n"); + break; + case BPF_MSH: + printf(" 4 * $data[%u] & 0x0f\",shape=parallelogram]\n", bpf->k); + break; + } + break; + case BPF_ST: + case BPF_STX: + printf(" $temp[%u]\",shape=parallelogram]\n", + bpf->k); + break; + case BPF_ALU: + if (BPF_SRC(bpf->code) == BPF_K) { + switch (BPF_OP(bpf->code)) { + case BPF_OR: + case BPF_AND: + printf(" 0x%.8x\",shape=rectangle]\n", bpf->k); + break; + default: + printf(" %u\",shape=rectangle]\n", bpf->k); + } + } else + printf(" %u\",shape=rectangle]\n", bpf->k); + break; + case BPF_JMP: + if (BPF_OP(bpf->code) == BPF_JA) { + printf("\",shape=hexagon]\n"); + printf("\tline%d -> line%d\n", + line, (line + 1) + bpf->k); + } else { + printf(" %-4u", bpf->k); + /* Heuristic: if k > 256, also emit hex version */ + if (bpf->k > 256) + printf("\\n(0x%.8x)", bpf->k); + printf("\",shape=diamond]\n"); + printf("\tline%d -> line%d [label=\"true\"]\n", + line, (line + 1) + bpf->jt); + printf("\tline%d -> line%d [label=\"false\"]\n", + line, (line + 1) + bpf->jf); + } + break; + case BPF_RET: + if (BPF_RVAL(bpf->code) == BPF_A) { + /* XXX - accumulator? */ + printf(" $acc\", shape=\"box\", style=rounded]\n"); + } else if (BPF_SRC(bpf->code) == BPF_K) { + printf(" "); + bpf_decode_action(bpf->k); + printf("\", shape=\"box\", style=rounded]\n"); + } else if (BPF_SRC(bpf->code) == BPF_X) { + /* XXX - any idea? */ + printf(" ???\", shape=\"box\", style=rounded]\n"); + } + break; + case BPF_MISC: + printf("\"]\n"); + break; + default: + printf(" ???\"]\n"); + } +} + +/** + * Perform a simple decoding of the BPF program to a dot graph + * @param file the BPF program + * + * Read the BPF program and display the instructions. Returns zero on success, + * non-zero values on failure. + * + */ +static int bpf_dot_decode(FILE *file) +{ + unsigned int line = 0; + bpf_instr_raw bpf; + int prev_class = 0; + + /* header */ + printf("digraph {\n"); + printf("\tstart[shape=\"box\", style=rounded];\n"); + + while (fread(&bpf, sizeof(bpf), 1, file)) { + /* convert the bpf statement */ + bpf.code = ttoh16(arch, bpf.code); + bpf.k = ttoh32(arch, bpf.k); + + /* display the statement */ + bpf_dot_decode_args(&bpf, line); + + /* if previous line wasn't RET/JMP, link it to this line */ + if (line == 0) + printf("\tstart -> line%d\n", line); + else if ((prev_class != BPF_JMP) && (prev_class != BPF_RET)) + printf("\tline%d -> line%d\n", line - 1, line); + prev_class = BPF_CLASS(bpf.code); + + line++; + } + printf("}\n"); + + if (ferror(file)) + return errno; + return 0; +} + +/** + * main + */ +int main(int argc, char *argv[]) +{ + int rc; + int opt; + bool dot_out = false; + FILE *file; + + /* parse the command line */ + while ((opt = getopt(argc, argv, "a:dh")) > 0) { + switch (opt) { + case 'a': + if (strcmp(optarg, "x86") == 0) + arch = AUDIT_ARCH_I386; + else if (strcmp(optarg, "x86_64") == 0) + arch = AUDIT_ARCH_X86_64; + else if (strcmp(optarg, "x32") == 0) + arch = AUDIT_ARCH_X86_64; + else if (strcmp(optarg, "arm") == 0) + arch = AUDIT_ARCH_ARM; + else if (strcmp(optarg, "aarch64") == 0) + arch = AUDIT_ARCH_AARCH64; + else if (strcmp(optarg, "mips") == 0) + arch = AUDIT_ARCH_MIPS; + else if (strcmp(optarg, "mipsel") == 0) + arch = AUDIT_ARCH_MIPSEL; + else if (strcmp(optarg, "mips64") == 0) + arch = AUDIT_ARCH_MIPS64; + else if (strcmp(optarg, "mipsel64") == 0) + arch = AUDIT_ARCH_MIPSEL64; + else if (strcmp(optarg, "mips64n32") == 0) + arch = AUDIT_ARCH_MIPS64N32; + else if (strcmp(optarg, "mipsel64n32") == 0) + arch = AUDIT_ARCH_MIPSEL64N32; + else if (strcmp(optarg, "ppc64") == 0) + arch = AUDIT_ARCH_PPC64; + else if (strcmp(optarg, "ppc64le") == 0) + arch = AUDIT_ARCH_PPC64LE; + else if (strcmp(optarg, "ppc") == 0) + arch = AUDIT_ARCH_PPC; + else if (strcmp(optarg, "s390") == 0) + arch = AUDIT_ARCH_S390; + else if (strcmp(optarg, "s390x") == 0) + arch = AUDIT_ARCH_S390X; + else if (strcmp(optarg, "riscv64") == 0) + arch = AUDIT_ARCH_RISCV64; + else + exit_usage(argv[0]); + break; + case 'd': + dot_out = true; + break; + default: + /* usage information */ + exit_usage(argv[0]); + } + } + + if ((optind > 1) && (optind < argc)) { + int opt_file = optind - 1 ; + file = fopen(argv[opt_file], "r"); + if (file == NULL) { + fprintf(stderr, "error: unable to open \"%s\" (%s)\n", + argv[opt_file], strerror(errno)); + return errno; + } + } else + file = stdin; + + if (dot_out) + rc = bpf_dot_decode(file); + else + rc = bpf_decode(file); + fclose(file); + + return rc; +} diff --git a/tools/scmp_bpf_sim.c b/tools/scmp_bpf_sim.c new file mode 100644 index 0000000..a381314 --- /dev/null +++ b/tools/scmp_bpf_sim.c @@ -0,0 +1,370 @@ +/** + * BPF Simulator + * + * Copyright (c) 2012 Red Hat + * Author: Paul Moore + */ + +/* + * 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 . + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "bpf.h" +#include "util.h" + +#define BPF_PRG_MAX_LEN 4096 + +/** + * BPF simulator machine state + */ +struct sim_state { + uint32_t acc; + uint32_t temp[BPF_SCRATCH_SIZE]; +}; + +struct bpf_program { + size_t i_cnt; + bpf_instr_raw *i; +}; + +static unsigned int opt_verbose = 0; + +/** + * 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 -f [-v] [-h]" + " -a -s [-0 ] ... [-5 ]\n", + program); + exit(EINVAL); +} + +/** + * Handle a simulator fault + * @param rc the error or return code + * + * Print a "FAULT" to stderr to indicate a simulator fault, and an errno value + * if the simulator is running in verbose mode, then exit with EFAULT. + * + */ +static void exit_fault(unsigned int rc) +{ + if (opt_verbose) + fprintf(stderr, "FAULT: errno = %d\n", rc); + else + fprintf(stderr, "FAULT\n"); + exit(EFAULT); +} + +/** + * Handle a BPF program error + * @param rc the error or return code + * @param line the line number + * + * Print an "ERROR" to stderr to indicate a program error, and an errno value + * if the simulator is running in verbose mode, then exit with ENOEXEC. + * + */ +static void exit_error(unsigned int rc, unsigned int line) +{ + if (opt_verbose) + fprintf(stderr, "ERROR: errno = %d, line = %d\n", rc, line); + else + fprintf(stderr, "ERROR\n"); + exit(ENOEXEC); +} + +/** + * Handle a simulator return/action + * @param action the return value + * @param line the line number + * + * Display the action to stdout and exit with 0. + * + */ +static void end_action(uint32_t action, unsigned int line) +{ + uint32_t act = action & SECCOMP_RET_ACTION_FULL; + uint32_t data = action & SECCOMP_RET_DATA; + + switch (act) { + case SECCOMP_RET_KILL_PROCESS: + fprintf(stdout, "KILL_PROCESS\n"); + break; + case SECCOMP_RET_KILL_THREAD: + fprintf(stdout, "KILL\n"); + break; + case SECCOMP_RET_TRAP: + fprintf(stdout, "TRAP\n"); + break; + case SECCOMP_RET_ERRNO: + fprintf(stdout, "ERRNO(%u)\n", data); + break; + case SECCOMP_RET_TRACE: + fprintf(stdout, "TRACE(%u)\n", data); + break; + case SECCOMP_RET_LOG: + fprintf(stdout, "LOG\n"); + break; + case SECCOMP_RET_ALLOW: + fprintf(stdout, "ALLOW\n"); + break; + default: + exit_error(EDOM, line); + } + + exit(0); +} + +/** + * Execute a BPF program + * @param prg the loaded BPF program + * @param sys_data the syscall record being tested + * + * Simulate the BPF program with the given syscall record. + * + */ +static void bpf_execute(const struct bpf_program *prg, + const struct seccomp_data *sys_data) +{ + unsigned int ip, ip_c; + struct sim_state state; + bpf_instr_raw *bpf; + unsigned char *sys_data_b = (unsigned char *)sys_data; + uint16_t code; + uint8_t jt; + uint8_t jf; + uint32_t k; + + /* initialize the machine state */ + ip_c = 0; + ip = 0; + memset(&state, 0, sizeof(state)); + + while (ip < prg->i_cnt) { + /* get the instruction and bump the ip */ + ip_c = ip; + bpf = &prg->i[ip++]; + + code = ttoh16(arch, bpf->code); + jt = bpf->jt; + jf = bpf->jf; + k = ttoh32(arch, bpf->k); + + switch (code) { + case BPF_LD+BPF_W+BPF_ABS: + if (k < BPF_SYSCALL_MAX) { + uint32_t val = *((uint32_t *)&sys_data_b[k]); + state.acc = ttoh32(arch, val); + } else + exit_error(ERANGE, ip_c); + break; + case BPF_ALU+BPF_OR+BPF_K: + state.acc |= k; + break; + case BPF_ALU+BPF_AND+BPF_K: + state.acc &= k; + break; + case BPF_JMP+BPF_JA: + ip += k; + break; + case BPF_JMP+BPF_JEQ+BPF_K: + if (state.acc == k) + ip += jt; + else + ip += jf; + break; + case BPF_JMP+BPF_JGT+BPF_K: + if (state.acc > k) + ip += jt; + else + ip += jf; + break; + case BPF_JMP+BPF_JGE+BPF_K: + if (state.acc >= k) + ip += jt; + else + ip += jf; + break; + case BPF_RET+BPF_K: + end_action(k, ip_c); + break; + default: + /* since we don't support the full bpf language just + * yet, this could be either a fault or an error, we'll + * treat it as a fault until we provide full support */ + exit_fault(EOPNOTSUPP); + } + } + + /* if we've reached here there is a problem with the program */ + exit_error(ERANGE, ip_c); +} + +/** + * main + */ +int main(int argc, char *argv[]) +{ + int opt; + int iter; + char *opt_file = NULL; + FILE *file; + size_t file_read_len; + struct seccomp_data sys_data; + struct bpf_program bpf_prg; + + /* initialize the syscall record */ + memset(&sys_data, 0, sizeof(sys_data)); + + /* parse the command line */ + while ((opt = getopt(argc, argv, "a:f:hs:v0:1:2:3:4:5:")) > 0) { + switch (opt) { + case 'a': + if (strcmp(optarg, "x86") == 0) + arch = AUDIT_ARCH_I386; + else if (strcmp(optarg, "x86_64") == 0) + arch = AUDIT_ARCH_X86_64; + else if (strcmp(optarg, "x32") == 0) + arch = AUDIT_ARCH_X86_64; + else if (strcmp(optarg, "arm") == 0) + arch = AUDIT_ARCH_ARM; + else if (strcmp(optarg, "aarch64") == 0) + arch = AUDIT_ARCH_AARCH64; + else if (strcmp(optarg, "mips") == 0) + arch = AUDIT_ARCH_MIPS; + else if (strcmp(optarg, "mipsel") == 0) + arch = AUDIT_ARCH_MIPSEL; + else if (strcmp(optarg, "mips64") == 0) + arch = AUDIT_ARCH_MIPS64; + else if (strcmp(optarg, "mipsel64") == 0) + arch = AUDIT_ARCH_MIPSEL64; + else if (strcmp(optarg, "mips64n32") == 0) + arch = AUDIT_ARCH_MIPS64N32; + else if (strcmp(optarg, "mipsel64n32") == 0) + arch = AUDIT_ARCH_MIPSEL64N32; + else if (strcmp(optarg, "parisc") == 0) + arch = AUDIT_ARCH_PARISC; + else if (strcmp(optarg, "parisc64") == 0) + arch = AUDIT_ARCH_PARISC64; + else if (strcmp(optarg, "ppc") == 0) + arch = AUDIT_ARCH_PPC; + else if (strcmp(optarg, "ppc64") == 0) + arch = AUDIT_ARCH_PPC64; + else if (strcmp(optarg, "ppc64le") == 0) + arch = AUDIT_ARCH_PPC64LE; + else if (strcmp(optarg, "s390") == 0) + arch = AUDIT_ARCH_S390; + else if (strcmp(optarg, "s390x") == 0) + arch = AUDIT_ARCH_S390X; + else if (strcmp(optarg, "riscv64") == 0) + arch = AUDIT_ARCH_RISCV64; + else + exit_fault(EINVAL); + break; + case 'f': + if (opt_file) + exit_fault(EINVAL); + opt_file = strdup(optarg); + if (opt_file == NULL) + exit_fault(ENOMEM); + break; + case 's': + sys_data.nr = strtol(optarg, NULL, 0); + break; + case 'v': + opt_verbose = 1; + break; + case '0': + sys_data.args[0] = strtoull(optarg, NULL, 0); + break; + case '1': + sys_data.args[1] = strtoull(optarg, NULL, 0); + break; + case '2': + sys_data.args[2] = strtoull(optarg, NULL, 0); + break; + case '3': + sys_data.args[3] = strtoull(optarg, NULL, 0); + break; + case '4': + sys_data.args[4] = strtoull(optarg, NULL, 0); + break; + case '5': + sys_data.args[5] = strtoull(optarg, NULL, 0); + break; + case 'h': + default: + /* usage information */ + exit_usage(argv[0]); + } + } + + /* adjust the endianess of sys_data to match the target */ + sys_data.nr = htot32(arch, sys_data.nr); + sys_data.arch = htot32(arch, arch); + sys_data.instruction_pointer = htot64(arch, + sys_data.instruction_pointer); + for (iter = 0; iter < BPF_SYS_ARG_MAX; iter++) + sys_data.args[iter] = htot64(arch, sys_data.args[iter]); + + /* allocate space for the bpf program */ + /* XXX - we should make this dynamic */ + bpf_prg.i_cnt = 0; + bpf_prg.i = calloc(BPF_PRG_MAX_LEN, sizeof(*bpf_prg.i)); + if (bpf_prg.i == NULL) + exit_fault(ENOMEM); + + /* load the bpf program */ + if (opt_file == NULL) + exit_usage(argv[0]); + file = fopen(opt_file, "r"); + if (file == NULL) + exit_fault(errno); + do { + file_read_len = fread(&(bpf_prg.i[bpf_prg.i_cnt]), + sizeof(*bpf_prg.i), 1, file); + if (file_read_len == 1) + bpf_prg.i_cnt++; + + /* check the size */ + if (bpf_prg.i_cnt == BPF_PRG_MAX_LEN) + exit_fault(E2BIG); + } while (file_read_len > 0); + fclose(file); + + /* execute the bpf program */ + bpf_execute(&bpf_prg, &sys_data); + + /* we should never reach here */ + exit_fault(EFAULT); + return 0; +} diff --git a/tools/scmp_sys_resolver.c b/tools/scmp_sys_resolver.c new file mode 100644 index 0000000..9be2c24 --- /dev/null +++ b/tools/scmp_sys_resolver.c @@ -0,0 +1,96 @@ +/** + * Syscall resolver + * + * Copyright (c) 2012 Red Hat + * Author: Paul Moore + */ + +/* + * 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 . + */ + +#include +#include +#include +#include +#include +#include + +#include + +/** + * 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 ] [-t] |\n", + program); + exit(EINVAL); +} + +/** + * main + */ +int main(int argc, char *argv[]) +{ + int opt; + int translate = 0; + uint32_t arch; + int sys_num; + const char *sys_name; + + arch = seccomp_arch_native(); + + /* parse the command line */ + while ((opt = getopt(argc, argv, "a:ht")) > 0) { + switch (opt) { + case 'a': + arch = seccomp_arch_resolve_name(optarg); + if (arch == 0) + exit_usage(argv[0]); + break; + case 't': + translate = 1; + break; + case 'h': + default: + /* usage information */ + exit_usage(argv[0]); + } + } + + /* sanity checks */ + if (optind >= argc) + exit_usage(argv[0]); + + /* perform the syscall lookup */ + if (isdigit(argv[optind][0]) || argv[optind][0] == '-') { + sys_num = atoi(argv[optind]); + sys_name = seccomp_syscall_resolve_num_arch(arch, sys_num); + printf("%s\n", (sys_name ? sys_name : "UNKNOWN")); + } else if (translate) { + sys_num = seccomp_syscall_resolve_name_rewrite(arch, + argv[optind]); + printf("%d\n", sys_num); + } else { + sys_num = seccomp_syscall_resolve_name_arch(arch, argv[optind]); + printf("%d\n", sys_num); + } + + return 0; +} diff --git a/tools/util.c b/tools/util.c new file mode 100644 index 0000000..5687b30 --- /dev/null +++ b/tools/util.c @@ -0,0 +1,152 @@ +/** + * Tool utility functions + * + * Copyright (c) 2014 Red Hat + * Author: Paul Moore + */ + +/* + * 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 . + */ + +#include +#include +#include +#include + +#ifndef _BSD_SOURCE +#define _BSD_SOURCE +#endif +#include + +#include "util.h" + +/* determine the native architecture */ +#if __i386__ +#define ARCH_NATIVE AUDIT_ARCH_I386 +#elif __x86_64__ +#ifdef __ILP32__ +#define ARCH_NATIVE AUDIT_ARCH_X86_64 +#else +#define ARCH_NATIVE AUDIT_ARCH_X86_64 +#endif /* __ILP32__ */ +#elif __arm__ +#define ARCH_NATIVE AUDIT_ARCH_ARM +#elif __aarch64__ +#define ARCH_NATIVE AUDIT_ARCH_AARCH64 +#elif __mips__ && _MIPS_SIM == _MIPS_SIM_ABI32 +#if __MIPSEB__ +#define ARCH_NATIVE AUDIT_ARCH_MIPS +#elif __MIPSEL__ +#define ARCH_NATIVE AUDIT_ARCH_MIPSEL +#endif /* _MIPS_SIM_ABI32 */ +#elif __mips__ && _MIPS_SIM == _MIPS_SIM_ABI64 +#if __MIPSEB__ +#define ARCH_NATIVE AUDIT_ARCH_MIPS64 +#elif __MIPSEL__ +#define ARCH_NATIVE AUDIT_ARCH_MIPSEL64 +#endif /* _MIPS_SIM_ABI64 */ +#elif __mips__ && _MIPS_SIM == _MIPS_SIM_NABI32 +#if __MIPSEB__ +#define ARCH_NATIVE AUDIT_ARCH_MIPS64N32 +#elif __MIPSEL__ +#define ARCH_NATIVE AUDIT_ARCH_MIPSEL64N32 +#endif /* _MIPS_SIM_NABI32 */ +#elif __hppa64__ +#define ARCH_NATIVE AUDIT_ARCH_PARISC64 +#elif __hppa__ +#define ARCH_NATIVE AUDIT_ARCH_PARISC +#elif __PPC64__ +#ifdef __BIG_ENDIAN__ +#define ARCH_NATIVE AUDIT_ARCH_PPC64 +#else +#define ARCH_NATIVE AUDIT_ARCH_PPC64LE +#endif +#elif __PPC__ +#define ARCH_NATIVE AUDIT_ARCH_PPC +#elif __s390x__ /* s390x must be checked before s390 */ +#define ARCH_NATIVE AUDIT_ARCH_S390X +#elif __s390__ +#define ARCH_NATIVE AUDIT_ARCH_S390 +#elif __riscv && __riscv_xlen == 64 +#define ARCH_NATIVE AUDIT_ARCH_RISCV64 +#else +#error the simulator code needs to know about your machine type +#endif + +/* default to the native arch */ +uint32_t arch = ARCH_NATIVE; + +/** + * Convert a 16-bit target integer into the host's endianess + * @param arch_token the architecture token + * @param val the 16-bit integer + * + * Convert the endianess of the supplied value and return it to the caller. + * + */ +uint16_t ttoh16(uint32_t arch_token, uint16_t val) +{ + if (arch_token & __AUDIT_ARCH_LE) + return le16toh(val); + else + return be16toh(val); +} + +/** + * Convert a 32-bit target integer into the host's endianess + * @param arch_token the architecture token + * @param val the 32-bit integer + * + * Convert the endianess of the supplied value and return it to the caller. + * + */ +uint32_t ttoh32(uint32_t arch_token, uint32_t val) +{ + if (arch_token & __AUDIT_ARCH_LE) + return le32toh(val); + else + return be32toh(val); +} + +/** + * Convert a 32-bit host integer into the target's endianess + * @param arch_token the architecture token + * @param val the 32-bit integer + * + * Convert the endianess of the supplied value and return it to the caller. + * + */ +uint32_t htot32(uint32_t arch_token, uint32_t val) +{ + if (arch_token & __AUDIT_ARCH_LE) + return htole32(val); + else + return htobe32(val); +} + +/** + * Convert a 64-bit host integer into the target's endianess + * @param arch_token the architecture token + * @param val the 64-bit integer + * + * Convert the endianess of the supplied value and return it to the caller. + * + */ +uint64_t htot64(uint32_t arch_token, uint64_t val) +{ + if (arch_token & __AUDIT_ARCH_LE) + return htole64(val); + else + return htobe64(val); +} diff --git a/tools/util.h b/tools/util.h new file mode 100644 index 0000000..6c2ca33 --- /dev/null +++ b/tools/util.h @@ -0,0 +1,90 @@ +/** + * Tool utility functions + * + * Copyright (c) 2014 Red Hat + * Author: Paul Moore + */ + +/* + * 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 . + */ + +#ifndef _UTIL_H +#define _UTIL_H + +#include +#include +#include + +/** + * The ARM architecture tokens + */ +/* AArch64 support for audit was merged in 3.17-rc1 */ +#ifndef AUDIT_ARCH_AARCH64 +#ifndef EM_AARCH64 +#define EM_AARCH64 183 +#endif /* EM_AARCH64 */ +#define AUDIT_ARCH_AARCH64 (EM_AARCH64|__AUDIT_ARCH_64BIT|__AUDIT_ARCH_LE) +#endif /* AUDIT_ARCH_AARCH64 */ + +/** + * The MIPS architecture tokens + */ +#ifndef __AUDIT_ARCH_CONVENTION_MIPS64_N32 +#define __AUDIT_ARCH_CONVENTION_MIPS64_N32 0x20000000 +#endif +#ifndef EM_MIPS +#define EM_MIPS 8 +#endif +#ifndef AUDIT_ARCH_MIPS +#define AUDIT_ARCH_MIPS (EM_MIPS) +#endif +#ifndef AUDIT_ARCH_MIPS64 +#define AUDIT_ARCH_MIPS64 (EM_MIPS|__AUDIT_ARCH_64BIT) +#endif +/* MIPS64N32 support was merged in 3.15 */ +#ifndef AUDIT_ARCH_MIPS64N32 +#define AUDIT_ARCH_MIPS64N32 (EM_MIPS|__AUDIT_ARCH_64BIT|\ + __AUDIT_ARCH_CONVENTION_MIPS64_N32) +#endif +/* MIPSEL64N32 support was merged in 3.15 */ +#ifndef AUDIT_ARCH_MIPSEL64N32 +#define AUDIT_ARCH_MIPSEL64N32 (EM_MIPS|__AUDIT_ARCH_64BIT|__AUDIT_ARCH_LE|\ + __AUDIT_ARCH_CONVENTION_MIPS64_N32) +#endif + +#ifndef AUDIT_ARCH_AARCH64 +/* AArch64 support for audit was merged in 3.17-rc1 */ +#define AUDIT_ARCH_AARCH64 (EM_AARCH64|__AUDIT_ARCH_64BIT|__AUDIT_ARCH_LE) +#endif + +#ifndef AUDIT_ARCH_PPC64LE +#define AUDIT_ARCH_PPC64LE (EM_PPC64|__AUDIT_ARCH_64BIT|__AUDIT_ARCH_LE) +#endif + +#ifndef AUDIT_ARCH_RISCV64 +#ifndef EM_RISCV +#define EM_RISCV 243 +#endif /* EM_RISCV */ +#define AUDIT_ARCH_RISCV64 (EM_RISCV|__AUDIT_ARCH_64BIT|__AUDIT_ARCH_LE) +#endif /* AUDIT_ARCH_RISCV64 */ + +extern uint32_t arch; + +uint16_t ttoh16(uint32_t arch, uint16_t val); +uint32_t ttoh32(uint32_t arch, uint32_t val); + +uint32_t htot32(uint32_t arch, uint32_t val); +uint64_t htot64(uint32_t arch, uint64_t val); + +#endif -- cgit v1.2.3