Beispiel #1
0
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);
}
Beispiel #3
0
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;
}
Beispiel #4
0
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);
}
Beispiel #8
0
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;
}
Beispiel #9
0
/*
 * 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
}