409 lines
13 KiB
Diff
409 lines
13 KiB
Diff
From db80cc666f47124c166771fbd018855f62ea0de3 Mon Sep 17 00:00:00 2001
|
|
From: LiFeng <lifeng68@huawei.com>
|
|
Date: Fri, 18 Jan 2019 02:11:11 -0500
|
|
Subject: [PATCH 050/139] seccomp: add rules for specified architecture only
|
|
|
|
LXC MR: https://github.com/lxc/lxc/pull/2786
|
|
|
|
Signed-off-by: LiFeng <lifeng68@huawei.com>
|
|
---
|
|
src/lxc/seccomp.c | 234 ++++++++++++++++++++++++++++++------------------------
|
|
1 file changed, 132 insertions(+), 102 deletions(-)
|
|
|
|
diff --git a/src/lxc/seccomp.c b/src/lxc/seccomp.c
|
|
index 27bdc22..4a9143b 100644
|
|
--- a/src/lxc/seccomp.c
|
|
+++ b/src/lxc/seccomp.c
|
|
@@ -291,7 +291,7 @@ on_error:
|
|
#endif
|
|
|
|
#if HAVE_DECL_SECCOMP_SYSCALL_RESOLVE_NAME_ARCH
|
|
-enum lxc_hostarch_t {
|
|
+enum lxc_arch_t {
|
|
lxc_seccomp_arch_all = 0,
|
|
lxc_seccomp_arch_native,
|
|
lxc_seccomp_arch_i386,
|
|
@@ -345,8 +345,8 @@ int get_hostarch(void)
|
|
return lxc_seccomp_arch_unknown;
|
|
}
|
|
|
|
-scmp_filter_ctx get_new_ctx(enum lxc_hostarch_t n_arch,
|
|
- uint32_t default_policy_action, bool *needs_merge)
|
|
+scmp_filter_ctx get_new_ctx(enum lxc_arch_t n_arch,
|
|
+ uint32_t default_policy_action)
|
|
{
|
|
int ret;
|
|
uint32_t arch;
|
|
@@ -464,10 +464,7 @@ scmp_filter_ctx get_new_ctx(enum lxc_hostarch_t n_arch,
|
|
return NULL;
|
|
}
|
|
TRACE("Removed native arch from main seccomp context");
|
|
-
|
|
- *needs_merge = true;
|
|
} else {
|
|
- *needs_merge = false;
|
|
TRACE("Arch %d already present in main seccomp context", (int)n_arch);
|
|
}
|
|
|
|
@@ -550,6 +547,27 @@ bool do_resolve_add_rule(uint32_t arch, char *line, scmp_filter_ctx ctx,
|
|
return true;
|
|
}
|
|
|
|
+#define SCMP_ARCH_INDEX_MAX 3
|
|
+
|
|
+struct scmp_ctx_info {
|
|
+ uint32_t architectures[SCMP_ARCH_INDEX_MAX];
|
|
+ enum lxc_arch_t lxc_arch[SCMP_ARCH_INDEX_MAX];
|
|
+ scmp_filter_ctx contexts[SCMP_ARCH_INDEX_MAX];
|
|
+ bool needs_merge[SCMP_ARCH_INDEX_MAX];
|
|
+};
|
|
+
|
|
+static int get_arch_index(enum lxc_arch_t arch, struct scmp_ctx_info *ctx)
|
|
+{
|
|
+ int i;
|
|
+
|
|
+ for (i = 0; i < SCMP_ARCH_INDEX_MAX; i++) {
|
|
+ if (ctx->lxc_arch[i] == arch)
|
|
+ return i;
|
|
+ }
|
|
+
|
|
+ return -1;
|
|
+}
|
|
+
|
|
/*
|
|
* v2 consists of
|
|
* [x86]
|
|
@@ -568,15 +586,11 @@ static int parse_config_v2(FILE *f, char *line, size_t *line_bufsz, struct lxc_c
|
|
{
|
|
int ret;
|
|
char *p;
|
|
- enum lxc_hostarch_t cur_rule_arch, native_arch;
|
|
+ enum lxc_arch_t cur_rule_arch, native_arch;
|
|
bool blacklist = false;
|
|
uint32_t default_policy_action = -1, default_rule_action = -1;
|
|
struct seccomp_v2_rule rule;
|
|
- struct scmp_ctx_info {
|
|
- uint32_t architectures[3];
|
|
- scmp_filter_ctx contexts[3];
|
|
- bool needs_merge[3];
|
|
- } ctx;
|
|
+ struct scmp_ctx_info ctx;
|
|
|
|
if (strncmp(line, "blacklist", 9) == 0)
|
|
blacklist = true;
|
|
@@ -617,23 +631,23 @@ static int parse_config_v2(FILE *f, char *line, size_t *line_bufsz, struct lxc_c
|
|
cur_rule_arch = lxc_seccomp_arch_all;
|
|
|
|
ctx.architectures[0] = SCMP_ARCH_X86;
|
|
+ ctx.lxc_arch[0] = lxc_seccomp_arch_i386;
|
|
ctx.contexts[0] = get_new_ctx(lxc_seccomp_arch_i386,
|
|
- default_policy_action,
|
|
- &ctx.needs_merge[0]);
|
|
+ default_policy_action);
|
|
if (!ctx.contexts[0])
|
|
goto bad;
|
|
|
|
ctx.architectures[1] = SCMP_ARCH_X32;
|
|
+ ctx.lxc_arch[1] = lxc_seccomp_arch_x32;
|
|
ctx.contexts[1] = get_new_ctx(lxc_seccomp_arch_x32,
|
|
- default_policy_action,
|
|
- &ctx.needs_merge[1]);
|
|
+ default_policy_action);
|
|
if (!ctx.contexts[1])
|
|
goto bad;
|
|
|
|
ctx.architectures[2] = SCMP_ARCH_X86_64;
|
|
+ ctx.lxc_arch[2] = lxc_seccomp_arch_amd64;
|
|
ctx.contexts[2] = get_new_ctx(lxc_seccomp_arch_amd64,
|
|
- default_policy_action,
|
|
- &ctx.needs_merge[2]);
|
|
+ default_policy_action);
|
|
if (!ctx.contexts[2])
|
|
goto bad;
|
|
#ifdef SCMP_ARCH_PPC
|
|
@@ -641,17 +655,17 @@ static int parse_config_v2(FILE *f, char *line, size_t *line_bufsz, struct lxc_c
|
|
cur_rule_arch = lxc_seccomp_arch_all;
|
|
|
|
ctx.architectures[0] = SCMP_ARCH_PPC;
|
|
+ ctx.lxc_arch[0] = lxc_seccomp_arch_ppc;
|
|
ctx.contexts[0] = get_new_ctx(lxc_seccomp_arch_ppc,
|
|
- default_policy_action,
|
|
- &ctx.needs_merge[0]);
|
|
+ default_policy_action);
|
|
if (!ctx.contexts[0])
|
|
goto bad;
|
|
|
|
- ctx.architectures[2] = SCMP_ARCH_PPC64;
|
|
- ctx.contexts[2] = get_new_ctx(lxc_seccomp_arch_ppc64,
|
|
- default_policy_action,
|
|
- &ctx.needs_merge[2]);
|
|
- if (!ctx.contexts[2])
|
|
+ ctx.architectures[1] = SCMP_ARCH_PPC64;
|
|
+ ctx.lxc_arch[1] = lxc_seccomp_arch_ppc64;
|
|
+ ctx.contexts[1] = get_new_ctx(lxc_seccomp_arch_ppc64,
|
|
+ default_policy_action);
|
|
+ if (!ctx.contexts[1])
|
|
goto bad;
|
|
#endif
|
|
#ifdef SCMP_ARCH_ARM
|
|
@@ -659,18 +673,18 @@ static int parse_config_v2(FILE *f, char *line, size_t *line_bufsz, struct lxc_c
|
|
cur_rule_arch = lxc_seccomp_arch_all;
|
|
|
|
ctx.architectures[0] = SCMP_ARCH_ARM;
|
|
+ ctx.lxc_arch[0] = lxc_seccomp_arch_arm;
|
|
ctx.contexts[0] = get_new_ctx(lxc_seccomp_arch_arm,
|
|
- default_policy_action,
|
|
- &ctx.needs_merge[0]);
|
|
+ default_policy_action);
|
|
if (!ctx.contexts[0])
|
|
goto bad;
|
|
|
|
#ifdef SCMP_ARCH_AARCH64
|
|
- ctx.architectures[2] = SCMP_ARCH_AARCH64;
|
|
- ctx.contexts[2] = get_new_ctx(lxc_seccomp_arch_arm64,
|
|
- default_policy_action,
|
|
- &ctx.needs_merge[2]);
|
|
- if (!ctx.contexts[2])
|
|
+ ctx.architectures[1] = SCMP_ARCH_AARCH64;
|
|
+ ctx.lxc_arch[1] = lxc_seccomp_arch_arm64;
|
|
+ ctx.contexts[1] = get_new_ctx(lxc_seccomp_arch_arm64,
|
|
+ default_policy_action);
|
|
+ if (!ctx.contexts[1])
|
|
goto bad;
|
|
#endif
|
|
#endif
|
|
@@ -679,46 +693,46 @@ static int parse_config_v2(FILE *f, char *line, size_t *line_bufsz, struct lxc_c
|
|
cur_rule_arch = lxc_seccomp_arch_all;
|
|
|
|
ctx.architectures[0] = SCMP_ARCH_MIPS;
|
|
+ ctx.lxc_arch[0] = lxc_seccomp_arch_mips;
|
|
ctx.contexts[0] = get_new_ctx(lxc_seccomp_arch_mips,
|
|
- default_policy_action,
|
|
- &ctx.needs_merge[0]);
|
|
+ default_policy_action);
|
|
if (!ctx.contexts[0])
|
|
goto bad;
|
|
|
|
ctx.architectures[1] = SCMP_ARCH_MIPS64N32;
|
|
+ ctx.lxc_arch[1] = lxc_seccomp_arch_mips64n32;
|
|
ctx.contexts[1] = get_new_ctx(lxc_seccomp_arch_mips64n32,
|
|
- default_policy_action,
|
|
- &ctx.needs_merge[1]);
|
|
+ default_policy_action);
|
|
if (!ctx.contexts[1])
|
|
goto bad;
|
|
|
|
ctx.architectures[2] = SCMP_ARCH_MIPS64;
|
|
+ ctx.lxc_arch[2] = lxc_seccomp_arch_mips64;
|
|
ctx.contexts[2] = get_new_ctx(lxc_seccomp_arch_mips64,
|
|
- default_policy_action,
|
|
- &ctx.needs_merge[2]);
|
|
+ default_policy_action);
|
|
if (!ctx.contexts[2])
|
|
goto bad;
|
|
} else if (native_arch == lxc_seccomp_arch_mipsel64) {
|
|
cur_rule_arch = lxc_seccomp_arch_all;
|
|
|
|
ctx.architectures[0] = SCMP_ARCH_MIPSEL;
|
|
+ ctx.lxc_arch[0] = lxc_seccomp_arch_mipsel;
|
|
ctx.contexts[0] = get_new_ctx(lxc_seccomp_arch_mipsel,
|
|
- default_policy_action,
|
|
- &ctx.needs_merge[0]);
|
|
+ default_policy_action);
|
|
if (!ctx.contexts[0])
|
|
goto bad;
|
|
|
|
ctx.architectures[1] = SCMP_ARCH_MIPSEL64N32;
|
|
+ ctx.lxc_arch[1] = lxc_seccomp_arch_mipsel64n32;
|
|
ctx.contexts[1] = get_new_ctx(lxc_seccomp_arch_mipsel64n32,
|
|
- default_policy_action,
|
|
- &ctx.needs_merge[1]);
|
|
+ default_policy_action);
|
|
if (!ctx.contexts[1])
|
|
goto bad;
|
|
|
|
ctx.architectures[2] = SCMP_ARCH_MIPSEL64;
|
|
+ ctx.lxc_arch[2] = lxc_seccomp_arch_mipsel64;
|
|
ctx.contexts[2] = get_new_ctx(lxc_seccomp_arch_mipsel64,
|
|
- default_policy_action,
|
|
- &ctx.needs_merge[2]);
|
|
+ default_policy_action);
|
|
if (!ctx.contexts[2])
|
|
goto bad;
|
|
#endif
|
|
@@ -928,97 +942,113 @@ static int parse_config_v2(FILE *f, char *line, size_t *line_bufsz, struct lxc_c
|
|
goto bad_rule;
|
|
}
|
|
|
|
- if (!do_resolve_add_rule(SCMP_ARCH_NATIVE, line,
|
|
- conf->seccomp_ctx, &rule))
|
|
- goto bad_rule;
|
|
+ if (cur_rule_arch == native_arch) {
|
|
+ if (!do_resolve_add_rule(SCMP_ARCH_NATIVE, line,
|
|
+ conf->seccomp_ctx, &rule))
|
|
+ goto bad_rule;
|
|
+
|
|
+ INFO("Added native rule for arch %d for %s action %d(%s)",
|
|
+ SCMP_ARCH_NATIVE, line, rule.action,
|
|
+ get_action_name(rule.action));
|
|
+ } else if (cur_rule_arch != lxc_seccomp_arch_all) {
|
|
+ int arch_index = get_arch_index(cur_rule_arch, &ctx);
|
|
+ if (arch_index < 0)
|
|
+ goto bad_arch;
|
|
|
|
- INFO("Added native rule for arch %d for %s action %d(%s)",
|
|
- SCMP_ARCH_NATIVE, line, rule.action,
|
|
- get_action_name(rule.action));
|
|
+ if (!do_resolve_add_rule(ctx.architectures[arch_index], line,
|
|
+ ctx.contexts[arch_index], &rule))
|
|
+ goto bad_rule;
|
|
|
|
- if (cur_rule_arch == lxc_seccomp_arch_all) {
|
|
+ INFO("Added compat rule for arch %d for %s action %d(%s)",
|
|
+ ctx.architectures[arch_index], line, rule.action,
|
|
+ get_action_name(rule.action));
|
|
+ ctx.needs_merge[arch_index] = true;
|
|
+ } else {
|
|
if (ctx.architectures[0] != SCMP_ARCH_NATIVE) {
|
|
if (!do_resolve_add_rule(ctx.architectures[0], line,
|
|
- ctx.contexts[0], &rule))
|
|
+ ctx.contexts[0], &rule))
|
|
goto bad_rule;
|
|
|
|
- INFO("Added compat rule for arch %d for %s action %d(%s)",
|
|
- ctx.architectures[0], line, rule.action,
|
|
- get_action_name(rule.action));
|
|
+ INFO("Added compat rule for arch %d for %s action %d(%s)",
|
|
+ ctx.architectures[0], line, rule.action,
|
|
+ get_action_name(rule.action));
|
|
+ ctx.needs_merge[0] = true;
|
|
}
|
|
|
|
if (ctx.architectures[1] != SCMP_ARCH_NATIVE) {
|
|
if (!do_resolve_add_rule(ctx.architectures[1], line,
|
|
- ctx.contexts[1], &rule))
|
|
+ ctx.contexts[1], &rule))
|
|
goto bad_rule;
|
|
|
|
INFO("Added compat rule for arch %d for %s action %d(%s)",
|
|
- ctx.architectures[1], line, rule.action,
|
|
- get_action_name(rule.action));
|
|
+ ctx.architectures[1], line, rule.action,
|
|
+ get_action_name(rule.action));
|
|
+ ctx.needs_merge[1] = true;
|
|
}
|
|
|
|
if (ctx.architectures[2] != SCMP_ARCH_NATIVE) {
|
|
if (!do_resolve_add_rule(ctx.architectures[2], line,
|
|
- ctx.contexts[2], &rule))
|
|
+ ctx.contexts[2], &rule))
|
|
goto bad_rule;
|
|
|
|
INFO("Added native rule for arch %d for %s action %d(%s)",
|
|
- ctx.architectures[2], line, rule.action,
|
|
- get_action_name(rule.action));
|
|
+ ctx.architectures[2], line, rule.action,
|
|
+ get_action_name(rule.action));
|
|
+ ctx.needs_merge[2] = true;
|
|
}
|
|
}
|
|
- }
|
|
|
|
- if (cur_rule_arch == lxc_seccomp_arch_all) {
|
|
- INFO("Merging compat seccomp contexts into main context");
|
|
- if (ctx.contexts[0]) {
|
|
- if (ctx.needs_merge[0]) {
|
|
- ret = seccomp_merge(conf->seccomp_ctx, ctx.contexts[0]);
|
|
- if (ret < 0) {
|
|
- ERROR("Failed to merge first compat seccomp "
|
|
- "context into main context");
|
|
- goto bad;
|
|
- }
|
|
+ }
|
|
|
|
- TRACE("Merged first compat seccomp context into main context");
|
|
- } else {
|
|
- seccomp_release(ctx.contexts[0]);
|
|
- ctx.contexts[0] = NULL;
|
|
+ INFO("Merging compat seccomp contexts into main context");
|
|
+ if (ctx.contexts[0]) {
|
|
+ if (ctx.needs_merge[0]) {
|
|
+ ret = seccomp_merge(conf->seccomp_ctx, ctx.contexts[0]);
|
|
+ if (ret < 0) {
|
|
+ ERROR("%s - Failed to merge first compat seccomp "
|
|
+ "context into main context", strerror(-ret));
|
|
+ goto bad;
|
|
}
|
|
- }
|
|
|
|
- if (ctx.contexts[1]) {
|
|
- if (ctx.needs_merge[1]) {
|
|
- ret = seccomp_merge(conf->seccomp_ctx, ctx.contexts[1]);
|
|
- if (ret < 0) {
|
|
- ERROR("Failed to merge first compat seccomp "
|
|
- "context into main context");
|
|
- goto bad;
|
|
- }
|
|
+ TRACE("Merged first compat seccomp context into main context");
|
|
+ } else {
|
|
+ seccomp_release(ctx.contexts[0]);
|
|
+ ctx.contexts[0] = NULL;
|
|
+ }
|
|
+ }
|
|
|
|
- TRACE("Merged second compat seccomp context into main context");
|
|
- } else {
|
|
- seccomp_release(ctx.contexts[1]);
|
|
- ctx.contexts[1] = NULL;
|
|
+ if (ctx.contexts[1]) {
|
|
+ if (ctx.needs_merge[1]) {
|
|
+ ret = seccomp_merge(conf->seccomp_ctx, ctx.contexts[1]);
|
|
+ if (ret < 0) {
|
|
+ ERROR("%s - Failed to merge second compat seccomp "
|
|
+ "context into main context", strerror(-ret));
|
|
+ goto bad;
|
|
}
|
|
- }
|
|
|
|
- if (ctx.contexts[2]) {
|
|
- if (ctx.needs_merge[2]) {
|
|
- ret = seccomp_merge(conf->seccomp_ctx, ctx.contexts[2]);
|
|
- if (ret < 0) {
|
|
- ERROR("Failed to merge third compat seccomp "
|
|
- "context into main context");
|
|
- goto bad;
|
|
- }
|
|
+ TRACE("Merged second compat seccomp context into main context");
|
|
+ } else {
|
|
+ seccomp_release(ctx.contexts[1]);
|
|
+ ctx.contexts[1] = NULL;
|
|
+ }
|
|
+ }
|
|
|
|
- TRACE("Merged third compat seccomp context into main context");
|
|
- } else {
|
|
- seccomp_release(ctx.contexts[2]);
|
|
- ctx.contexts[2] = NULL;
|
|
+ if (ctx.contexts[2]) {
|
|
+ if (ctx.needs_merge[2]) {
|
|
+ ret = seccomp_merge(conf->seccomp_ctx, ctx.contexts[2]);
|
|
+ if (ret < 0) {
|
|
+ ERROR("%s - Failed to merge third compat seccomp "
|
|
+ "context into main context", strerror(-ret));
|
|
+ goto bad;
|
|
}
|
|
+
|
|
+ TRACE("Merged third compat seccomp context into main context");
|
|
+ } else {
|
|
+ seccomp_release(ctx.contexts[2]);
|
|
+ ctx.contexts[2] = NULL;
|
|
}
|
|
}
|
|
+
|
|
free(line);
|
|
return 0;
|
|
|
|
--
|
|
1.8.3.1
|
|
|