int seccomp_add_secondary_archs(scmp_filter_ctx *c) { #if defined(__i386__) || defined(__x86_64__) int r; /* Add in all possible secondary archs we are aware of that * this kernel might support. */ r = seccomp_arch_add(c, SCMP_ARCH_X86); if (r < 0 && r != -EEXIST) return r; r = seccomp_arch_add(c, SCMP_ARCH_X86_64); if (r < 0 && r != -EEXIST) return r; r = seccomp_arch_add(c, SCMP_ARCH_X32); if (r < 0 && r != -EEXIST) return r; #endif return 0; }
int main(int argc, char *argv[]) { int rc; struct util_options opts; scmp_filter_ctx ctx = NULL; rc = util_getopt(argc, argv, &opts); if (rc < 0) goto out; ctx = seccomp_init(SCMP_ACT_KILL); if (ctx == NULL) return ENOMEM; rc = seccomp_arch_remove(ctx, SCMP_ARCH_NATIVE); if (rc != 0) goto out; rc = seccomp_arch_add(ctx, SCMP_ARCH_X86); if (rc != 0) goto out; rc = seccomp_arch_add(ctx, SCMP_ARCH_X86_64); if (rc != 0) goto out; rc = seccomp_arch_add(ctx, SCMP_ARCH_X32); if (rc != 0) goto out; rc = seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(socket), 0); if (rc != 0) goto out; rc = seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(connect), 0); if (rc != 0) goto out; rc = seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(accept), 0); if (rc != 0) goto out; rc = seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(accept4), 0); if (rc != 0) goto out; rc = seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(shutdown), 0); if (rc != 0) goto out; rc = util_filter_output(&opts, ctx); if (rc) goto out; out: seccomp_release(ctx); return (rc < 0 ? -rc : rc); }
scmp_filter_ctx get_new_ctx(enum lxc_hostarch_t n_arch, uint32_t default_policy_action) { scmp_filter_ctx ctx; int ret; uint32_t arch; switch(n_arch) { case lxc_seccomp_arch_i386: arch = SCMP_ARCH_X86; break; case lxc_seccomp_arch_amd64: arch = SCMP_ARCH_X86_64; break; case lxc_seccomp_arch_arm: arch = SCMP_ARCH_ARM; break; #ifdef SCMP_ARCH_PPC64LE case lxc_seccomp_arch_ppc64le: arch = SCMP_ARCH_PPC64LE; break; #endif #ifdef SCMP_ARCH_PPC64 case lxc_seccomp_arch_ppc64: arch = SCMP_ARCH_PPC64; break; #endif #ifdef SCMP_ARCH_PPC case lxc_seccomp_arch_ppc: arch = SCMP_ARCH_PPC; break; #endif default: return NULL; } if ((ctx = seccomp_init(default_policy_action)) == NULL) { ERROR("Error initializing seccomp context"); return NULL; } if (seccomp_attr_set(ctx, SCMP_FLTATR_CTL_NNP, 0)) { ERROR("failed to turn off n-new-privs"); seccomp_release(ctx); return NULL; } ret = seccomp_arch_add(ctx, arch); if (ret != 0) { ERROR("Seccomp error %d (%s) adding arch: %d", ret, strerror(ret), (int)n_arch); seccomp_release(ctx); return NULL; } if (seccomp_arch_remove(ctx, SCMP_ARCH_NATIVE) != 0) { ERROR("Seccomp error removing native arch"); seccomp_release(ctx); return NULL; } return ctx; }
static void sc_add_seccomp_archs(scmp_filter_ctx * ctx) { uint32_t native_arch = seccomp_arch_native(); // seccomp userspace uint32_t host_arch = get_hostarch(); // kernel uint32_t compat_arch = 0; debug("host arch (kernel) is '%d'", host_arch); debug("native arch (userspace) is '%d'", native_arch); // For architectures that support a compat architecture, when the // kernel and userspace match, add the compat arch, otherwise add // the kernel arch to support the kernel's arch (eg, 64bit kernels with // 32bit userspace). if (host_arch == native_arch) { switch (host_arch) { #if defined (SCMP_ARCH_X86_64) case SCMP_ARCH_X86_64: compat_arch = SCMP_ARCH_X86; break; #endif #if defined(SCMP_ARCH_AARCH64) case SCMP_ARCH_AARCH64: compat_arch = SCMP_ARCH_ARM; break; #endif #if defined (SCMP_ARCH_PPC64) case SCMP_ARCH_PPC64: compat_arch = SCMP_ARCH_PPC; break; #endif default: break; } } else compat_arch = host_arch; if (compat_arch > 0 && seccomp_arch_exist(ctx, compat_arch) == -EEXIST) { debug("adding compat arch '%d'", compat_arch); if (seccomp_arch_add(ctx, compat_arch) < 0) die("seccomp_arch_add(..., compat_arch) failed"); } }
int main(int argc, char *argv[]) { int rc; struct util_options opts; scmp_filter_ctx ctx = NULL; rc = util_getopt(argc, argv, &opts); if (rc < 0) goto out; ctx = seccomp_init(SCMP_ACT_KILL); if (ctx == NULL) return ENOMEM; rc = seccomp_arch_remove(ctx, SCMP_ARCH_NATIVE); if (rc != 0) goto out; rc = seccomp_arch_add(ctx, SCMP_ARCH_X86); if (rc != 0) goto out; rc = seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(tuxcall), 0); if (rc != 0) goto out; rc = seccomp_rule_add_exact(ctx, SCMP_ACT_ALLOW, SCMP_SYS(tuxcall), 0); if (rc != -EDOM) goto out; rc = util_filter_output(&opts, ctx); if (rc) goto out; out: seccomp_release(ctx); return (rc < 0 ? -rc : rc); }
int main(int argc, char *argv[]) { int rc; struct util_options opts; scmp_filter_ctx ctx = NULL; rc = util_getopt(argc, argv, &opts); if (rc < 0) goto out; ctx = seccomp_init(SCMP_ACT_KILL); if (ctx == NULL) return ENOMEM; rc = seccomp_arch_remove(ctx, SCMP_ARCH_NATIVE); if (rc != 0) goto out; rc = seccomp_arch_add(ctx, seccomp_arch_resolve_name("x86")); if (rc != 0) goto out; rc = seccomp_arch_add(ctx, seccomp_arch_resolve_name("x86_64")); if (rc != 0) goto out; rc = seccomp_arch_add(ctx, seccomp_arch_resolve_name("x32")); if (rc != 0) goto out; rc = seccomp_arch_add(ctx, seccomp_arch_resolve_name("arm")); if (rc != 0) goto out; rc = seccomp_arch_add(ctx, seccomp_arch_resolve_name("aarch64")); if (rc != 0) goto out; rc = seccomp_arch_add(ctx, seccomp_arch_resolve_name("mipsel")); if (rc != 0) goto out; rc = seccomp_arch_add(ctx, seccomp_arch_resolve_name("mipsel64")); if (rc != 0) goto out; rc = seccomp_arch_add(ctx, seccomp_arch_resolve_name("mipsel64n32")); if (rc != 0) goto out; rc = seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(read), 1, SCMP_A0(SCMP_CMP_EQ, STDIN_FILENO)); if (rc != 0) goto out; rc = seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(write), 1, SCMP_A0(SCMP_CMP_EQ, STDOUT_FILENO)); if (rc != 0) goto out; rc = seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(write), 1, SCMP_A0(SCMP_CMP_EQ, STDERR_FILENO)); if (rc != 0) goto out; rc = seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(close), 0); if (rc != 0) goto out; rc = seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(rt_sigreturn), 0); if (rc != 0) goto out; rc = util_filter_output(&opts, ctx); if (rc) goto out; out: seccomp_release(ctx); return (rc < 0 ? -rc : rc); }
int main(int argc, char *argv[]) { int rc; struct util_options opts; scmp_filter_ctx ctx = NULL; rc = util_getopt(argc, argv, &opts); if (rc < 0) goto out; ctx = seccomp_init(SCMP_ACT_KILL); if (ctx == NULL) return ENOMEM; rc = seccomp_arch_remove(ctx, SCMP_ARCH_NATIVE); if (rc != 0) goto out; rc = seccomp_arch_add(ctx, SCMP_ARCH_X86); if (rc != 0) goto out; rc = seccomp_arch_add(ctx, SCMP_ARCH_X86_64); if (rc != 0) goto out; rc = seccomp_arch_add(ctx, SCMP_ARCH_X32); if (rc != 0) goto out; rc = seccomp_arch_add(ctx, SCMP_ARCH_ARM); if (rc != 0) goto out; rc = seccomp_arch_add(ctx, SCMP_ARCH_AARCH64); if (rc != 0) goto out; rc = seccomp_arch_add(ctx, SCMP_ARCH_MIPSEL); if (rc != 0) goto out; rc = seccomp_arch_add(ctx, SCMP_ARCH_MIPSEL64); if (rc != 0) goto out; rc = seccomp_arch_add(ctx, SCMP_ARCH_MIPSEL64N32); if (rc != 0) goto out; rc = seccomp_arch_add(ctx, SCMP_ARCH_PPC64LE); if (rc != 0) goto out; rc = seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(read), 1, SCMP_A0(SCMP_CMP_EQ, STDIN_FILENO)); if (rc != 0) goto out; rc = seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(write), 1, SCMP_A0(SCMP_CMP_EQ, STDOUT_FILENO)); if (rc != 0) goto out; rc = seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(write), 1, SCMP_A0(SCMP_CMP_EQ, STDERR_FILENO)); if (rc != 0) goto out; rc = seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(close), 0); if (rc != 0) goto out; rc = seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(socket), 0); if (rc != 0) goto out; rc = seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(connect), 0); if (rc != 0) goto out; rc = seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(shutdown), 0); if (rc != 0) goto out; rc = util_filter_output(&opts, ctx); if (rc) goto out; out: seccomp_release(ctx); return (rc < 0 ? -rc : rc); }
scmp_filter_ctx get_new_ctx(enum lxc_hostarch_t n_arch, uint32_t default_policy_action) { scmp_filter_ctx ctx; int ret; uint32_t arch; switch(n_arch) { case lxc_seccomp_arch_i386: arch = SCMP_ARCH_X86; break; case lxc_seccomp_arch_x32: arch = SCMP_ARCH_X32; break; case lxc_seccomp_arch_amd64: arch = SCMP_ARCH_X86_64; break; case lxc_seccomp_arch_arm: arch = SCMP_ARCH_ARM; break; #ifdef SCMP_ARCH_AARCH64 case lxc_seccomp_arch_arm64: arch = SCMP_ARCH_AARCH64; break; #endif #ifdef SCMP_ARCH_PPC64LE case lxc_seccomp_arch_ppc64le: arch = SCMP_ARCH_PPC64LE; break; #endif #ifdef SCMP_ARCH_PPC64 case lxc_seccomp_arch_ppc64: arch = SCMP_ARCH_PPC64; break; #endif #ifdef SCMP_ARCH_PPC case lxc_seccomp_arch_ppc: arch = SCMP_ARCH_PPC; break; #endif #ifdef SCMP_ARCH_MIPS case lxc_seccomp_arch_mips: arch = SCMP_ARCH_MIPS; break; case lxc_seccomp_arch_mips64: arch = SCMP_ARCH_MIPS64; break; case lxc_seccomp_arch_mips64n32: arch = SCMP_ARCH_MIPS64N32; break; case lxc_seccomp_arch_mipsel: arch = SCMP_ARCH_MIPSEL; break; case lxc_seccomp_arch_mipsel64: arch = SCMP_ARCH_MIPSEL64; break; case lxc_seccomp_arch_mipsel64n32: arch = SCMP_ARCH_MIPSEL64N32; break; #endif #ifdef SCMP_ARCH_S390X case lxc_seccomp_arch_s390x: arch = SCMP_ARCH_S390X; break; #endif default: return NULL; } if ((ctx = seccomp_init(default_policy_action)) == NULL) { ERROR("Error initializing seccomp context."); return NULL; } if (seccomp_attr_set(ctx, SCMP_FLTATR_CTL_NNP, 0)) { ERROR("Failed to turn off n-new-privs."); seccomp_release(ctx); return NULL; } #ifdef SCMP_FLTATR_ATL_TSKIP if (seccomp_attr_set(ctx, SCMP_FLTATR_ATL_TSKIP, 1)) { WARN("Failed to turn on seccomp nop-skip, continuing"); } #endif ret = seccomp_arch_add(ctx, arch); if (ret != 0) { ERROR("Seccomp error %d (%s) adding arch: %d", ret, strerror(-ret), (int)n_arch); seccomp_release(ctx); return NULL; } if (seccomp_arch_remove(ctx, SCMP_ARCH_NATIVE) != 0) { ERROR("Seccomp error removing native arch"); seccomp_release(ctx); return NULL; } return ctx; }
/* * v2 consists of * [x86] * open * read * write * close * # a comment * [x86_64] * open * read * write * close */ static int parse_config_v2(FILE *f, char *line, struct lxc_conf *conf) { #if HAVE_DECL_SECCOMP_SYSCALL_RESOLVE_NAME_ARCH char *p; int ret; scmp_filter_ctx *ctx = NULL; bool blacklist = false; uint32_t default_policy_action = -1, default_rule_action = -1, action; uint32_t arch = SCMP_ARCH_NATIVE; if (strncmp(line, "blacklist", 9) == 0) blacklist = true; else if (strncmp(line, "whitelist", 9) != 0) { ERROR("Bad seccomp policy style: %s", line); return -1; } if ((p = strchr(line, ' '))) { default_policy_action = get_v2_default_action(p+1); if (default_policy_action == -2) return -1; } /* for blacklist, allow any syscall which has no rule */ if (blacklist) { if (default_policy_action == -1) default_policy_action = SCMP_ACT_ALLOW; if (default_rule_action == -1) default_rule_action = SCMP_ACT_KILL; } else { if (default_policy_action == -1) default_policy_action = SCMP_ACT_KILL; if (default_rule_action == -1) default_rule_action = SCMP_ACT_ALLOW; } if (default_policy_action != SCMP_ACT_KILL) { ret = seccomp_reset(conf->seccomp_ctx, default_policy_action); if (ret != 0) { ERROR("Error re-initializing seccomp"); return -1; } if (seccomp_attr_set(conf->seccomp_ctx, SCMP_FLTATR_CTL_NNP, 0)) { ERROR("failed to turn off n-new-privs"); return -1; } } while (fgets(line, 1024, f)) { int nr; if (line[0] == '#') continue; if (strlen(line) == 0) continue; remove_trailing_newlines(line); INFO("processing: .%s.", line); if (line[0] == '[') { // read the architecture for next set of rules if (strcmp(line, "[x86]") == 0 || strcmp(line, "[X86]") == 0) arch = SCMP_ARCH_X86; else if (strcmp(line, "[X86_64]") == 0 || strcmp(line, "[x86_64]") == 0) arch = SCMP_ARCH_X86_64; #ifdef SCMP_ARCH_ARM else if (strcmp(line, "[arm]") == 0 || strcmp(line, "[ARM]") == 0) arch = SCMP_ARCH_ARM; #endif else goto bad_arch; if (ctx) { ERROR("Only two arch sections per policy supported"); goto bad_arch; } if ((ctx = seccomp_init(default_policy_action)) == NULL) { ERROR("Error initializing seccomp context"); return -1; } if (seccomp_attr_set(ctx, SCMP_FLTATR_CTL_NNP, 0)) { ERROR("failed to turn off n-new-privs"); seccomp_release(ctx); return -1; } ret = seccomp_arch_add(ctx, arch); if (ret == -EEXIST) { seccomp_release(ctx); ctx = NULL; continue; } if (ret != 0) { ERROR("Error %d adding arch: %s", ret, line); goto bad_arch; } if (seccomp_arch_remove(ctx, SCMP_ARCH_NATIVE) != 0) { ERROR("Error removing native arch from %s", line); goto bad_arch; } continue; } action = get_and_clear_v2_action(line, default_rule_action); if (action == -1) { ERROR("Failed to interpret action"); goto bad_rule; } nr = seccomp_syscall_resolve_name_arch(arch, line); if (nr < 0) { ERROR("Failed to resolve syscall: %s", line); goto bad_rule; } ret = seccomp_rule_add(ctx ? ctx : conf->seccomp_ctx, action, nr, 0); if (ret < 0) { ERROR("failed (%d) loading rule for %s", ret, line); goto bad_rule; } } if (ctx) { if (seccomp_merge(conf->seccomp_ctx, ctx) != 0) { seccomp_release(ctx); ERROR("Error merging seccomp contexts"); return -1; } } return 0; bad_arch: ERROR("Unsupported arch: %s", line); bad_rule: if (ctx) seccomp_release(ctx); return -1; #else return -1; #endif }