summaryrefslogtreecommitdiff
path: root/src/test/test-seccomp.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/test/test-seccomp.c')
-rw-r--r--src/test/test-seccomp.c205
1 files changed, 142 insertions, 63 deletions
diff --git a/src/test/test-seccomp.c b/src/test/test-seccomp.c
index d82cb5c1c5..fbfeedd536 100644
--- a/src/test/test-seccomp.c
+++ b/src/test/test-seccomp.c
@@ -20,6 +20,7 @@
#include "seccomp-util.h"
#include "set.h"
#include "string-util.h"
+#include "tests.h"
#include "util.h"
#include "virt.h"
@@ -35,6 +36,8 @@ static void test_seccomp_arch_to_string(void) {
uint32_t a, b;
const char *name;
+ log_info("/* %s */", __func__);
+
a = seccomp_arch_native();
assert_se(a > 0);
name = seccomp_arch_to_string(a);
@@ -46,6 +49,8 @@ static void test_seccomp_arch_to_string(void) {
static void test_architecture_table(void) {
const char *n, *n2;
+ log_info("/* %s */", __func__);
+
NULSTR_FOREACH(n,
"native\0"
"x86\0"
@@ -74,6 +79,8 @@ static void test_architecture_table(void) {
}
static void test_syscall_filter_set_find(void) {
+ log_info("/* %s */", __func__);
+
assert_se(!syscall_filter_set_find(NULL));
assert_se(!syscall_filter_set_find(""));
assert_se(!syscall_filter_set_find("quux"));
@@ -88,10 +95,16 @@ static void test_filter_sets(void) {
unsigned i;
int r;
- if (!is_seccomp_available())
+ log_info("/* %s */", __func__);
+
+ if (!is_seccomp_available()) {
+ log_notice("Seccomp not available, skipping %s", __func__);
return;
- if (geteuid() != 0)
+ }
+ if (geteuid() != 0) {
+ log_notice("Not root, skipping %s", __func__);
return;
+ }
for (i = 0; i < _SYSCALL_FILTER_SET_MAX; i++) {
pid_t pid;
@@ -104,11 +117,11 @@ static void test_filter_sets(void) {
if (pid == 0) { /* Child? */
int fd;
- /* if we look at the default set (or one that includes it), whitelist instead of blacklist */
+ /* If we look at the default set (or one that includes it), whitelist instead of blacklist */
if (IN_SET(i, SYSCALL_FILTER_SET_DEFAULT, SYSCALL_FILTER_SET_SYSTEM_SERVICE))
- r = seccomp_load_syscall_filter_set(SCMP_ACT_ERRNO(EUCLEAN), syscall_filter_sets + i, SCMP_ACT_ALLOW);
+ r = seccomp_load_syscall_filter_set(SCMP_ACT_ERRNO(EUCLEAN), syscall_filter_sets + i, SCMP_ACT_ALLOW, true);
else
- r = seccomp_load_syscall_filter_set(SCMP_ACT_ALLOW, syscall_filter_sets + i, SCMP_ACT_ERRNO(EUCLEAN));
+ r = seccomp_load_syscall_filter_set(SCMP_ACT_ALLOW, syscall_filter_sets + i, SCMP_ACT_ERRNO(EUCLEAN), true);
if (r < 0)
_exit(EXIT_FAILURE);
@@ -128,11 +141,50 @@ static void test_filter_sets(void) {
}
}
+static void test_filter_sets_ordered(void) {
+ size_t i;
+
+ log_info("/* %s */", __func__);
+
+ /* Ensure "@default" always remains at the beginning of the list */
+ assert_se(SYSCALL_FILTER_SET_DEFAULT == 0);
+ assert_se(streq(syscall_filter_sets[0].name, "@default"));
+
+ for (i = 0; i < _SYSCALL_FILTER_SET_MAX; i++) {
+ const char *k, *p = NULL;
+
+ /* Make sure each group has a description */
+ assert_se(!isempty(syscall_filter_sets[0].help));
+
+ /* Make sure the groups are ordered alphabetically, except for the first entry */
+ assert_se(i < 2 || strcmp(syscall_filter_sets[i-1].name, syscall_filter_sets[i].name) < 0);
+
+ NULSTR_FOREACH(k, syscall_filter_sets[i].value) {
+
+ /* Ensure each syscall list is in itself ordered, but groups before names */
+ assert_se(!p ||
+ (*p == '@' && *k != '@') ||
+ (((*p == '@' && *k == '@') ||
+ (*p != '@' && *k != '@')) &&
+ strcmp(p, k) < 0));
+
+ p = k;
+ }
+ }
+}
+
static void test_restrict_namespace(void) {
char *s = NULL;
unsigned long ul;
pid_t pid;
+ if (!have_namespaces()) {
+ log_notice("Testing without namespaces, skipping %s", __func__);
+ return;
+ }
+
+ log_info("/* %s */", __func__);
+
assert_se(namespace_flags_to_string(0, &s) == 0 && streq(s, ""));
s = mfree(s);
assert_se(namespace_flags_to_string(CLONE_NEWNS, &s) == 0 && streq(s, "mnt"));
@@ -160,10 +212,14 @@ static void test_restrict_namespace(void) {
assert_se(namespace_flags_from_string(s, &ul) == 0 && ul == NAMESPACE_FLAGS_ALL);
s = mfree(s);
- if (!is_seccomp_available())
+ if (!is_seccomp_available()) {
+ log_notice("Seccomp not available, skipping remaining tests in %s", __func__);
return;
- if (geteuid() != 0)
+ }
+ if (geteuid() != 0) {
+ log_notice("Not root, skipping remaining tests in %s", __func__);
return;
+ }
pid = fork();
assert_se(pid >= 0);
@@ -223,13 +279,22 @@ static void test_restrict_namespace(void) {
static void test_protect_sysctl(void) {
pid_t pid;
- if (!is_seccomp_available())
+ log_info("/* %s */", __func__);
+
+ if (!is_seccomp_available()) {
+ log_notice("Seccomp not available, skipping %s", __func__);
return;
- if (geteuid() != 0)
+ }
+ if (geteuid() != 0) {
+ log_notice("Not root, skipping %s", __func__);
return;
+ }
- if (detect_container() > 0) /* in containers _sysctl() is likely missing anyway */
+ /* in containers _sysctl() is likely missing anyway */
+ if (detect_container() > 0) {
+ log_notice("Testing in container, skipping %s", __func__);
return;
+ }
pid = fork();
assert_se(pid >= 0);
@@ -256,10 +321,16 @@ static void test_protect_sysctl(void) {
static void test_restrict_address_families(void) {
pid_t pid;
- if (!is_seccomp_available())
+ log_info("/* %s */", __func__);
+
+ if (!is_seccomp_available()) {
+ log_notice("Seccomp not available, skipping %s", __func__);
return;
- if (geteuid() != 0)
+ }
+ if (geteuid() != 0) {
+ log_notice("Not root, skipping %s", __func__);
return;
+ }
pid = fork();
assert_se(pid >= 0);
@@ -339,13 +410,22 @@ static void test_restrict_address_families(void) {
static void test_restrict_realtime(void) {
pid_t pid;
- if (!is_seccomp_available())
+ log_info("/* %s */", __func__);
+
+ if (!is_seccomp_available()) {
+ log_notice("Seccomp not available, skipping %s", __func__);
return;
- if (geteuid() != 0)
+ }
+ if (geteuid() != 0) {
+ log_notice("Not root, skipping %s", __func__);
return;
+ }
- if (detect_container() > 0) /* in containers RT privs are likely missing anyway */
+ /* in containers RT privs are likely missing anyway */
+ if (detect_container() > 0) {
+ log_notice("Testing in container, skipping %s", __func__);
return;
+ }
pid = fork();
assert_se(pid >= 0);
@@ -377,10 +457,16 @@ static void test_restrict_realtime(void) {
static void test_memory_deny_write_execute_mmap(void) {
pid_t pid;
- if (!is_seccomp_available())
+ log_info("/* %s */", __func__);
+
+ if (!is_seccomp_available()) {
+ log_notice("Seccomp not available, skipping %s", __func__);
return;
- if (geteuid() != 0)
+ }
+ if (geteuid() != 0) {
+ log_notice("Not root, skipping %s", __func__);
return;
+ }
pid = fork();
assert_se(pid >= 0);
@@ -421,10 +507,16 @@ static void test_memory_deny_write_execute_shmat(void) {
int shmid;
pid_t pid;
- if (!is_seccomp_available())
+ log_info("/* %s */", __func__);
+
+ if (!is_seccomp_available()) {
+ log_notice("Seccomp not available, skipping %s", __func__);
return;
- if (geteuid() != 0)
+ }
+ if (geteuid() != 0) {
+ log_notice("Not root, skipping %s", __func__);
return;
+ }
shmid = shmget(IPC_PRIVATE, page_size(), 0);
assert_se(shmid >= 0);
@@ -467,10 +559,16 @@ static void test_memory_deny_write_execute_shmat(void) {
static void test_restrict_archs(void) {
pid_t pid;
- if (!is_seccomp_available())
+ log_info("/* %s */", __func__);
+
+ if (!is_seccomp_available()) {
+ log_notice("Seccomp not available, skipping %s", __func__);
return;
- if (geteuid() != 0)
+ }
+ if (geteuid() != 0) {
+ log_notice("Not root, skipping %s", __func__);
return;
+ }
pid = fork();
assert_se(pid >= 0);
@@ -501,10 +599,16 @@ static void test_restrict_archs(void) {
static void test_load_syscall_filter_set_raw(void) {
pid_t pid;
- if (!is_seccomp_available())
+ log_info("/* %s */", __func__);
+
+ if (!is_seccomp_available()) {
+ log_notice("Seccomp not available, skipping %s", __func__);
return;
- if (geteuid() != 0)
+ }
+ if (geteuid() != 0) {
+ log_notice("Not root, skipping %s", __func__);
return;
+ }
pid = fork();
assert_se(pid >= 0);
@@ -515,7 +619,7 @@ static void test_load_syscall_filter_set_raw(void) {
assert_se(access("/", F_OK) >= 0);
assert_se(poll(NULL, 0, 0) == 0);
- assert_se(seccomp_load_syscall_filter_set_raw(SCMP_ACT_ALLOW, NULL, SCMP_ACT_KILL) >= 0);
+ assert_se(seccomp_load_syscall_filter_set_raw(SCMP_ACT_ALLOW, NULL, SCMP_ACT_KILL, true) >= 0);
assert_se(access("/", F_OK) >= 0);
assert_se(poll(NULL, 0, 0) == 0);
@@ -526,7 +630,7 @@ static void test_load_syscall_filter_set_raw(void) {
assert_se(hashmap_put(s, UINT32_TO_PTR(__NR_faccessat + 1), INT_TO_PTR(-1)) >= 0);
#endif
- assert_se(seccomp_load_syscall_filter_set_raw(SCMP_ACT_ALLOW, s, SCMP_ACT_ERRNO(EUCLEAN)) >= 0);
+ assert_se(seccomp_load_syscall_filter_set_raw(SCMP_ACT_ALLOW, s, SCMP_ACT_ERRNO(EUCLEAN), true) >= 0);
assert_se(access("/", F_OK) < 0);
assert_se(errno == EUCLEAN);
@@ -542,7 +646,7 @@ static void test_load_syscall_filter_set_raw(void) {
assert_se(hashmap_put(s, UINT32_TO_PTR(__NR_faccessat + 1), INT_TO_PTR(EILSEQ)) >= 0);
#endif
- assert_se(seccomp_load_syscall_filter_set_raw(SCMP_ACT_ALLOW, s, SCMP_ACT_ERRNO(EUCLEAN)) >= 0);
+ assert_se(seccomp_load_syscall_filter_set_raw(SCMP_ACT_ALLOW, s, SCMP_ACT_ERRNO(EUCLEAN), true) >= 0);
assert_se(access("/", F_OK) < 0);
assert_se(errno == EILSEQ);
@@ -558,7 +662,7 @@ static void test_load_syscall_filter_set_raw(void) {
assert_se(hashmap_put(s, UINT32_TO_PTR(__NR_ppoll + 1), INT_TO_PTR(-1)) >= 0);
#endif
- assert_se(seccomp_load_syscall_filter_set_raw(SCMP_ACT_ALLOW, s, SCMP_ACT_ERRNO(EUNATCH)) >= 0);
+ assert_se(seccomp_load_syscall_filter_set_raw(SCMP_ACT_ALLOW, s, SCMP_ACT_ERRNO(EUNATCH), true) >= 0);
assert_se(access("/", F_OK) < 0);
assert_se(errno == EILSEQ);
@@ -575,7 +679,7 @@ static void test_load_syscall_filter_set_raw(void) {
assert_se(hashmap_put(s, UINT32_TO_PTR(__NR_ppoll + 1), INT_TO_PTR(EILSEQ)) >= 0);
#endif
- assert_se(seccomp_load_syscall_filter_set_raw(SCMP_ACT_ALLOW, s, SCMP_ACT_ERRNO(EUNATCH)) >= 0);
+ assert_se(seccomp_load_syscall_filter_set_raw(SCMP_ACT_ALLOW, s, SCMP_ACT_ERRNO(EUNATCH), true) >= 0);
assert_se(access("/", F_OK) < 0);
assert_se(errno == EILSEQ);
@@ -593,10 +697,16 @@ static void test_lock_personality(void) {
unsigned long current;
pid_t pid;
- if (!is_seccomp_available())
+ log_info("/* %s */", __func__);
+
+ if (!is_seccomp_available()) {
+ log_notice("Seccomp not available, skipping %s", __func__);
return;
- if (geteuid() != 0)
+ }
+ if (geteuid() != 0) {
+ log_notice("Not root, skipping %s", __func__);
return;
+ }
assert_se(opinionated_personality(&current) >= 0);
@@ -636,44 +746,14 @@ static void test_lock_personality(void) {
assert_se(wait_for_terminate_and_check("lockpersonalityseccomp", pid, WAIT_LOG) == EXIT_SUCCESS);
}
-static void test_filter_sets_ordered(void) {
- size_t i;
-
- /* Ensure "@default" always remains at the beginning of the list */
- assert_se(SYSCALL_FILTER_SET_DEFAULT == 0);
- assert_se(streq(syscall_filter_sets[0].name, "@default"));
-
- for (i = 0; i < _SYSCALL_FILTER_SET_MAX; i++) {
- const char *k, *p = NULL;
-
- /* Make sure each group has a description */
- assert_se(!isempty(syscall_filter_sets[0].help));
-
- /* Make sure the groups are ordered alphabetically, except for the first entry */
- assert_se(i < 2 || strcmp(syscall_filter_sets[i-1].name, syscall_filter_sets[i].name) < 0);
-
- NULSTR_FOREACH(k, syscall_filter_sets[i].value) {
-
- /* Ensure each syscall list is in itself ordered, but groups before names */
- assert_se(!p ||
- (*p == '@' && *k != '@') ||
- (((*p == '@' && *k == '@') ||
- (*p != '@' && *k != '@')) &&
- strcmp(p, k) < 0));
-
- p = k;
- }
- }
-}
-
int main(int argc, char *argv[]) {
-
- log_set_max_level(LOG_DEBUG);
+ test_setup_logging(LOG_DEBUG);
test_seccomp_arch_to_string();
test_architecture_table();
test_syscall_filter_set_find();
test_filter_sets();
+ test_filter_sets_ordered();
test_restrict_namespace();
test_protect_sysctl();
test_restrict_address_families();
@@ -683,7 +763,6 @@ int main(int argc, char *argv[]) {
test_restrict_archs();
test_load_syscall_filter_set_raw();
test_lock_personality();
- test_filter_sets_ordered();
return 0;
}