From 1de1ae0b32dbfedc08ce0f3179fa8ec5d2912331 Mon Sep 17 00:00:00 2001 From: Albert S Date: Sat, 9 Nov 2019 21:13:40 +0100 Subject: [PATCH] introduce bitmasks indicating which namespaces to unshare --- qssb.h | 76 ++++++++++++++++++++++++++++++++++++---------------------- 1 file changed, 47 insertions(+), 29 deletions(-) diff --git a/qssb.h b/qssb.h index 77779fc..e9184c0 100644 --- a/qssb.h +++ b/qssb.h @@ -34,7 +34,9 @@ BPF_STMT(BPF_LD+BPF_W+BPF_ABS, \ offsetof(struct seccomp_data, nr)) -#define QSSB_ISOLATE_NETWORK 1<<1 +#define QSSB_UNSHARE_NETWORK 1<<1 +#define QSSB_UNSHARE_USER 1<<2 +#define QSSB_UNSHARE_MOUNT 1<<3 #ifndef QSSB_LOG_ERROR #define QSSB_LOG_ERROR(...) fprintf(stderr, __VA_ARGS__) @@ -67,7 +69,7 @@ struct qssb_policy *qssb_init_policy() result->drop_caps = 1; result->not_dumpable = 1; result->no_new_privs = 1; - result->namespace_options = 0; + result->namespace_options = QSSB_UNSHARE_MOUNT | QSSB_UNSHARE_USER; result->chdir_path = "/"; result->chroot_target_path = NULL; result->readonly_paths = NULL; @@ -173,37 +175,53 @@ static void qssb_free_policy(struct qssb_policy *ctxt) free(ctxt); } -/* Enters the user and mount namespaces */ -static int enter_namespaces() +/* Enters the specified namespaces */ +static int enter_namespaces(int namespace_options) { - int ret = unshare(CLONE_NEWUSER); - if(ret == -1) + if(namespace_options & QSSB_UNSHARE_USER) { - QSSB_LOG_ERROR("Error: Failed to unshare user namespaces: %s\n", strerror(errno)); - return ret; + int ret = unshare(CLONE_NEWUSER); + if(ret == -1) + { + QSSB_LOG_ERROR("Error: Failed to unshare user namespaces: %s\n", strerror(errno)); + return ret; + } + + uid_t current_uid = getuid(); + gid_t current_gid = getgid(); + + //TODO: check errors + FILE *fp = fopen("/proc/self/setgroups", "w"); + fprintf(fp, "deny"); + fclose(fp); + + fp = fopen("/proc/self/uid_map", "w"); + fprintf(fp, "0 %i", current_uid); + fclose(fp); + + fp = fopen("/proc/self/gid_map", "w"); + fprintf(fp, "0 %i", current_gid); + fclose(fp); } - uid_t current_uid = getuid(); - gid_t current_gid = getgid(); - - //TODO: check errors - FILE *fp = fopen("/proc/self/setgroups", "w"); - fprintf(fp, "deny"); - fclose(fp); - - fp = fopen("/proc/self/uid_map", "w"); - fprintf(fp, "0 %i", current_uid); - fclose(fp); - - fp = fopen("/proc/self/gid_map", "w"); - fprintf(fp, "0 %i", current_gid); - fclose(fp); - - ret = unshare(CLONE_NEWNS); - if(ret == -1) + if(namespace_options & QSSB_UNSHARE_MOUNT) { - QSSB_LOG_ERROR("Error: Failed to unshare mount namespaces: %s\n", strerror(errno)); - return ret; + int ret = unshare(CLONE_NEWNS); + if(ret == -1) + { + QSSB_LOG_ERROR("Error: Failed to unshare mount namespaces: %s\n", strerror(errno)); + return ret; + } + } + + if(namespace_options & QSSB_UNSHARE_NETWORK) + { + int ret = unshare(CLONE_NEWNET); + if(ret == -1) + { + QSSB_LOG_ERROR("Error: Failed to unshare network namespace: %s\n", strerror(errno)); + return ret; + } } return 0; @@ -331,7 +349,7 @@ int qssb_enable_policy(struct qssb_policy *policy) policy->chroot_target_path = "/tmp/.TODOIMPLEMENT"; //TODO: implement } - if(enter_namespaces() < 0) + if(enter_namespaces(policy->namespace_options) < 0) { QSSB_LOG_ERROR("Error while trying to enter namespaces\n"); return -1;