This test type enables the creation of "live", not simulated, tests
which can be used to verify proper operation of the library on systems
that support seccomp mode 2.

Signed-off-by: Paul Moore <[email protected]>
---
 tests/regression |   64 +++++++++++++++++++++++++++++++++++
 tests/util.c     |  100 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 tests/util.h     |    6 +++
 tests/util.py    |   53 +++++++++++++++++++++++++++++
 4 files changed, 223 insertions(+)

diff --git a/tests/regression b/tests/regression
index a572966..e4df007 100755
--- a/tests/regression
+++ b/tests/regression
@@ -533,6 +533,63 @@ function run_test_basic() {
 }
 
 #
+# Run the specified "live" test
+#
+# Tests that belong to the "live" test type will attempt to run a live test
+# of the libseccomp library on the host system; for obvious reasons the host
+# system must support seccomp mode 2 for this to work correctly.
+#
+# Arguments:
+#     1    value of test number from batch file
+#     2    string containing line of test data from batch file
+#
+function run_test_live() {
+       local rc
+       local line=($2)
+
+       # parse the test line
+       line_cmd=${line[0]}
+       line_act=${line[1]}
+       line_test="$line_cmd $line_act"
+
+       # print out the input test data to the log file
+       print_data "$1" "$2"
+
+       # run the command
+       exec 4>/dev/null
+       run_test_command "$1" "$line_cmd" "$line_act" "" 4
+       rc=$?
+       exec 4>&-
+
+       # return value codes for this test type:
+       #  159: KILL
+       #  160: ALLOW
+       #  161: TRAP
+       #  162: TRACE (currently unsupported)
+       #  163: ERRNO
+       if [[ $line_act == "KILL" && $rc -eq 159 ]]; then
+               print_result $1 "SUCCESS" ""
+               stats_success=$(($stats_success+1))
+       elif [[ $line_act == "ALLOW" && $rc -eq 160 ]]; then
+               print_result $1 "SUCCESS" ""
+               stats_success=$(($stats_success+1))
+       elif [[ $line_act == "TRAP" && $rc -eq 161 ]]; then
+               print_result $1 "SUCCESS" ""
+               stats_success=$(($stats_success+1))
+       elif [[ $line_act == "TRACE" ]]; then
+               print_result $1 "ERROR" "unsupported action \"$line_act\""
+               stats_error=$(($stats_error+1))
+       elif [[ $line_act == "ERRNO" && $rc -eq 163 ]]; then
+               print_result $1 "SUCCESS" ""
+               stats_success=$(($stats_success+1))
+       else
+               print_result $1 "FAILURE" "$line_test rc=$rc"
+               stats_failure=$(($stats_failure+1))
+       fi
+       stats_all=$(($stats_all+1))
+}
+
+#
 # Run a single test from the specified batch
 #
 # Arguments:
@@ -555,6 +612,13 @@ function run_test() {
                run_test_bpf_sim "$1" $2 "$3"
        elif [[ "$4" == "bpf-sim-fuzz" ]]; then
                run_test_bpf_sim_fuzz "$1" $2 "$3"
+       elif [[ "$4" == "live" ]]; then
+               # only run this test if explicitly requested
+               if [[ -n $type ]]; then
+                       run_test_live "$testnumstr" "$3"
+               else
+                       stats_skipped=$(($stats_skipped+1))
+               fi
        else
                print_result $testnumstr "ERROR" "test type $4 not supported"
                stats_error=$(($stats_error+1))
diff --git a/tests/util.c b/tests/util.c
index ce507fa..02b0043 100644
--- a/tests/util.c
+++ b/tests/util.c
@@ -20,16 +20,34 @@
  */
 
 #include <errno.h>
+#include <fcntl.h>
 #include <getopt.h>
+#include <signal.h>
 #include <stdio.h>
 #include <string.h>
 #include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
 
 #include <seccomp.h>
 
 #include "util.h"
 
 /**
+ * SIGSYS signal handler
+ * @param nr the signal number
+ * @param info siginfo_t pointer
+ * @param void_context handler context
+ *
+ * Simple signal handler for SIGSYS which exits with error code 161.
+ *
+ */
+static void _trap_handler(int signal, siginfo_t *info, void *ctx)
+{
+       _exit(161);
+}
+
+/**
  * Parse the arguments passed to main
  * @param argc the argument count
  * @param argv the argument pointer
@@ -107,3 +125,85 @@ int util_filter_output(const struct util_options *opts,
 
        return rc;
 }
+
+/**
+ * Install a TRAP action signal handler
+ *
+ * This function installs the TRAP action signal handler and is based on
+ * examples from Will Drewry and Kees Cook.  Returns zero on success, negative
+ * values on failure.
+ *
+ */
+int util_trap_install(void)
+{
+       struct sigaction signal_handler;
+       sigset_t signal_mask;
+
+       memset(&signal_handler, 0, sizeof(signal_handler));
+       sigemptyset(&signal_mask);
+       sigaddset(&signal_mask, SIGSYS);
+
+       signal_handler.sa_sigaction = &_trap_handler;
+       signal_handler.sa_flags = SA_SIGINFO;
+       if (sigaction(SIGSYS, &signal_handler, NULL) < 0)
+               return -errno;
+       if (sigprocmask(SIG_UNBLOCK, &signal_mask, NULL))
+               return -errno;
+
+       return 0;
+}
+
+/**
+ * Parse a filter action string into an action value
+ * @param action the action string
+ *
+ * Parse a seccomp action string into the associated integer value.  Returns
+ * the correct value on success, -1 on failure.
+ *
+ */
+int util_action_parse(const char *action)
+{
+       if (action == NULL)
+               return -1;
+
+       if (strcasecmp(action, "KILL") == 0)
+               return SCMP_ACT_KILL;
+       else if (strcasecmp(action, "TRAP") == 0)
+               return SCMP_ACT_TRAP;
+       else if (strcasecmp(action, "ERRNO") == 0)
+               return SCMP_ACT_ERRNO(163);
+       else if (strcasecmp(action, "TRACE") == 0)
+               return -1; /* not yet supported */
+       else if (strcasecmp(action, "ALLOW") == 0)
+               return SCMP_ACT_ALLOW;
+
+       return -1;
+}
+
+/**
+ * Write a string to a file
+ * @param path the file path
+ *
+ * Open the specified file, write a string to the file, and close the file.
+ * Return zero on success, negative values on error.
+ *
+ */
+int util_file_write(const char *path)
+{
+       int fd;
+       const char buf[] = "testing";
+       ssize_t buf_len = strlen(buf);
+
+       fd = open(path, O_WRONLY|O_CREAT, S_IRUSR|S_IWUSR);
+       if (fd < 0)
+               return errno;
+       if (write(fd, buf, buf_len) < buf_len) {
+               int rc = errno;
+               close(fd);
+               return rc;
+       }
+       if (close(fd) < 0)
+               return errno;
+
+       return 0;
+}
diff --git a/tests/util.h b/tests/util.h
index 68af8a0..b3c5a29 100644
--- a/tests/util.h
+++ b/tests/util.h
@@ -31,4 +31,10 @@ int util_getopt(int argc, char *argv[], struct util_options 
*opts);
 int util_filter_output(const struct util_options *opts,
                       const scmp_filter_ctx ctx);
 
+int util_trap_install(void);
+
+int util_action_parse(const char *action);
+
+int util_file_write(const char *path);
+
 #endif
diff --git a/tests/util.py b/tests/util.py
index 8e4c689..20704f6 100644
--- a/tests/util.py
+++ b/tests/util.py
@@ -22,7 +22,16 @@
 """ Python utility code for the libseccomp test suite """
 
 import argparse
+import os
 import sys
+import signal
+
+from seccomp import *
+
+def trap_handler(signum, frame):
+    """ SIGSYS signal handler, internal use only
+    """
+    os._exit(161)
 
 def get_opt():
     """ Parse the arguments passed to main
@@ -52,5 +61,49 @@ def filter_output(args, ctx):
     else:
         ctx.export_pfc(sys.stdout)
 
+def install_trap():
+    """ Install a TRAP action signal handler
+
+    Description:
+    Install the TRAP action signal handler.
+    """
+    signal.signal(signal.SIGSYS, trap_handler)
+
+def parse_action(action):
+    """ Parse a filter action string into an action value
+
+    Arguments:
+    action - the action string
+
+    Description:
+    Parse a seccomp action string into the associated integer value.
+    """
+    if action == "KILL":
+        return KILL
+    elif action == "TRAP":
+        return TRAP
+    elif action == "ERRNO":
+        return ERRNO(163)
+    elif action == "TRACE":
+        raise RuntimeError("the TRACE action is not currently supported")
+    elif action == "ALLOW":
+        return ALLOW
+    raise RuntimeError("invalid action string")
+
+
+def write_file(path):
+    """ Write a string to a file
+
+    Arguments:
+    path - the file path
+
+    Description:
+    Open the specified file, write a string to the file, and close the file.
+    """
+    fd = os.open(path, os.O_WRONLY|os.O_CREAT, 0600)
+    if not os.write(fd, "testing") == len("testing"):
+        raise IOError("failed to write the full test string in write_file()")
+    os.close(fd)
+
 # kate: syntax python;
 # kate: indent-mode python; space-indent on; indent-width 4; mixedindent off;


------------------------------------------------------------------------------
Free Next-Gen Firewall Hardware Offer
Buy your Sophos next-gen firewall before the end March 2013 
and get the hardware for free! Learn more.
http://p.sf.net/sfu/sophos-d2d-feb
_______________________________________________
libseccomp-discuss mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/libseccomp-discuss

Reply via email to