From fa06287b13570f4d45e9d14b749f6a9b5b618de7 Mon Sep 17 00:00:00 2001 From: Albert S Date: Wed, 11 Aug 2021 20:54:40 +0200 Subject: [PATCH] Use new qssb_append_*_syscall functions, remove old fields --- qssb.h | 79 +++++++++++++++++++++------------------------------------- test.c | 18 +++++++------ 2 files changed, 39 insertions(+), 58 deletions(-) diff --git a/qssb.h b/qssb.h index 192a92c..fb8fa01 100644 --- a/qssb.h +++ b/qssb.h @@ -212,8 +212,6 @@ struct qssb_policy /* Bind mounts all paths in path_policies into the chroot and applies non-landlock policies */ int mount_path_policies_to_chroot; - int *blacklisted_syscalls; - int *whitelisted_syscalls; char chroot_target_path[PATH_MAX]; const char *chdir_path; @@ -283,7 +281,6 @@ int qssb_append_denied_syscalls(struct qssb_policy *qssb_policy, int *syscalls, struct qssb_policy *qssb_init_policy() { struct qssb_policy *result = (struct qssb_policy *) calloc(1, sizeof(struct qssb_policy)); - result->blacklisted_syscalls = default_blacklisted_syscals; result->drop_caps = 1; result->not_dumpable = 1; result->no_new_privs = 1; @@ -632,13 +629,13 @@ static int drop_caps() /* * Enables the per_syscall seccomp action for system calls * - * syscalls: array of system calls numbers. -1 must be the last entry. + * syscalls: array of system calls numbers. * per_syscall: action to apply for each system call * default_action: the default action at the end * * @returns: 0 on success, -1 on error */ -static int seccomp_enable(int *syscalls, unsigned int per_syscall, unsigned int default_action) +static int seccomp_enable(int *syscalls, size_t n, unsigned int per_syscall, unsigned int default_action) { struct sock_filter filter[1024] = { @@ -646,15 +643,13 @@ static int seccomp_enable(int *syscalls, unsigned int per_syscall, unsigned int }; unsigned short int current_filter_index = 1; - while(*syscalls >= 0) + for(size_t i = 0; i < n; i++) { - unsigned int sysc = (unsigned int) *syscalls; + unsigned int sysc = (unsigned int) syscalls[i]; struct sock_filter syscall = BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, sysc, 0, 1); struct sock_filter action = BPF_STMT(BPF_RET+BPF_K, per_syscall); filter[current_filter_index++] = syscall; filter[current_filter_index++] = action; - - ++syscalls; } struct sock_filter da = BPF_STMT(BPF_RET+BPF_K, default_action); @@ -678,21 +673,21 @@ static int seccomp_enable(int *syscalls, unsigned int per_syscall, unsigned int /* * Blacklists the specified systemcalls. * - * syscalls: array of system calls numbers. -1 must be the last entry. + * syscalls: array of system calls numbers. */ -static int seccomp_enable_blacklist(int *syscalls) +static int seccomp_enable_blacklist(int *syscalls, size_t n) { - return seccomp_enable(syscalls, SECCOMP_RET_KILL, SECCOMP_RET_ALLOW); + return seccomp_enable(syscalls, n, SECCOMP_RET_KILL, SECCOMP_RET_ALLOW); } /* * Whitelists the specified systemcalls. * - * syscalls: array of system calls numbers. -1 must be the last entry. + * syscalls: array of system calls numbers. */ -static int seccomp_enable_whitelist(int *syscalls) +static int seccomp_enable_whitelist(int *syscalls, size_t n) { - return seccomp_enable(syscalls, SECCOMP_RET_ALLOW, SECCOMP_RET_KILL); + return seccomp_enable(syscalls, n, SECCOMP_RET_ALLOW, SECCOMP_RET_KILL); } #if HAVE_LANDLOCK == 1 @@ -814,9 +809,9 @@ static int landlock_prepare_ruleset(struct qssb_path_policy *policies) /* Checks for illogical or dangerous combinations */ static int check_policy_sanity(struct qssb_policy *policy) { - if(policy->blacklisted_syscalls != NULL && policy->whitelisted_syscalls != NULL) + if(policy->denied_syscalls.used > 0 && policy->allowed_syscalls.used > 0) { - QSSB_LOG_ERROR("Error: Cannot mix blacklisted and whitelisted systemcalls\n"); + QSSB_LOG_ERROR("Error: Cannot mix allowed and denied systemcalls in policy\n"); return -EINVAL; } @@ -836,7 +831,7 @@ static int check_policy_sanity(struct qssb_policy *policy) if(policy->no_new_privs != 1) { - if(policy->blacklisted_syscalls != NULL || policy->whitelisted_syscalls != NULL) + if(policy->allowed_syscalls.used > 0 || policy->denied_syscalls.used > 0) { QSSB_LOG_ERROR("no_new_privs = 1 is required for seccomp filtering!\n"); return -1; @@ -902,37 +897,15 @@ static int enable_no_fs(struct qssb_policy *policy) return -1; } - if(policy->whitelisted_syscalls == NULL) + if(policy->allowed_syscalls.used == 0) { - if(policy->blacklisted_syscalls == NULL) - { - policy->blacklisted_syscalls = fs_access_syscalls; - } - else - { - size_t nbl = 0; - size_t nfs = sizeof(fs_access_syscalls)/sizeof(fs_access_syscalls[0]); - int *tmp = policy->blacklisted_syscalls; - while(*tmp != -1) - { - ++nbl; - ++tmp; - } - size_t n = (nbl + nfs) + 1; - tmp = (int *) calloc(n, sizeof(int)); - int *tmp_begin = tmp; - if(tmp == NULL) - { - QSSB_LOG_ERROR("Failed to expand blacklisted syscall array\n"); - return -1; - } - memcpy(tmp, policy->blacklisted_syscalls, nbl*sizeof(int)); - tmp+=nbl; - memcpy(tmp, fs_access_syscalls, nfs*sizeof(int)); - tmp+=(nfs+1); - *tmp = -1; + size_t fs_access_syscalls_count = sizeof(fs_access_syscalls)/sizeof(fs_access_syscalls[0]); - policy->blacklisted_syscalls = tmp_begin; + int ret = qssb_append_denied_syscalls(policy, fs_access_syscalls, fs_access_syscalls_count); + if(ret != 0) + { + QSSB_LOG_ERROR("Failed to add system calls to blacklist\n"); + return -1; } } return 0; @@ -1085,18 +1058,22 @@ int qssb_enable_policy(struct qssb_policy *policy) close(landlock_ruleset_fd); #endif - if(policy->whitelisted_syscalls != NULL) + if(policy->allowed_syscalls.used > 0) { - if(seccomp_enable_whitelist(policy->whitelisted_syscalls) <0) + int *syscalls = (int *)policy->allowed_syscalls.data; + size_t n = policy->allowed_syscalls.used / sizeof(int); + if(seccomp_enable_whitelist(syscalls, n) < 0) { QSSB_LOG_ERROR("seccomp_enable_whitelist failed\n"); return -1; } } - if(policy->blacklisted_syscalls != NULL) + if(policy->denied_syscalls.used > 0) { - if(seccomp_enable_blacklist(policy->blacklisted_syscalls) <0) + int *syscalls = (int *)policy->denied_syscalls.data; + size_t n = policy->denied_syscalls.used / sizeof(int); + if(seccomp_enable_blacklist(syscalls, n) < 0) { QSSB_LOG_ERROR("seccomp_enable_blacklist failed\n"); return -1; diff --git a/test.c b/test.c index 234599f..28d6c71 100644 --- a/test.c +++ b/test.c @@ -15,9 +15,11 @@ int test_default_main(int argc, char *argv[]) int test_both_syscalls(int argc, char *argv[]) { struct qssb_policy *policy = qssb_init_policy(); - int bla[] = { 1,2,3}; - policy->blacklisted_syscalls = &bla; - policy->whitelisted_syscalls = &bla; + int syscalls[] = {1,2,3}; + + qssb_append_denied_syscalls(policy, syscalls, 3); + qssb_append_allowed_syscalls(policy, syscalls, 3); + int ret = qssb_enable_policy(policy); if(ret != 0) { @@ -29,8 +31,9 @@ int test_both_syscalls(int argc, char *argv[]) int test_seccomp_blacklisted(int argc, char *argv[]) { struct qssb_policy *policy = qssb_init_policy(); - int blacklisted[] = { QSSB_SYS(getuid) }; - policy->blacklisted_syscalls = blacklisted; + + qssb_append_denied_syscall(policy, QSSB_SYS(getuid)); + int ret = qssb_enable_policy(policy); uid_t pid = geteuid(); pid = getuid(); @@ -40,8 +43,9 @@ int test_seccomp_blacklisted(int argc, char *argv[]) int test_seccomp_blacklisted_call_permitted(int argc, char *argv[]) { struct qssb_policy *policy = qssb_init_policy(); - int blacklisted[] = { QSSB_SYS(getuid) }; - policy->blacklisted_syscalls = blacklisted; + + qssb_append_denied_syscall(policy, QSSB_SYS(getuid)); + int ret = qssb_enable_policy(policy); //geteuid is not blacklisted, so must succeed uid_t pid = geteuid();