nspawn: return ENOSYS by default, EPERM for "known" calls

This commit is contained in:
Zbigniew Jędrzejewski-Szmek 2020-08-21 17:23:48 +02:00
parent 000c05207d
commit 3573e032f2

View file

@ -21,7 +21,7 @@
#if HAVE_SECCOMP
static int seccomp_add_default_syscall_filter(
static int add_syscall_filters(
scmp_filter_ctx ctx,
uint32_t arch,
uint64_t cap_list_retain,
@ -139,6 +139,7 @@ static int seccomp_add_default_syscall_filter(
*/
};
_cleanup_strv_free_ char **added = NULL;
char **p;
int r;
@ -151,18 +152,25 @@ static int seccomp_add_default_syscall_filter(
SCMP_ACT_ALLOW,
syscall_deny_list,
false,
NULL);
&added);
if (r < 0)
return log_error_errno(r, "Failed to add syscall filter item %s: %m", allow_list[i].name);
}
STRV_FOREACH(p, syscall_allow_list) {
r = seccomp_add_syscall_filter_item(ctx, *p, SCMP_ACT_ALLOW, syscall_deny_list, true, NULL);
r = seccomp_add_syscall_filter_item(ctx, *p, SCMP_ACT_ALLOW, syscall_deny_list, true, &added);
if (r < 0)
log_warning_errno(r, "Failed to add rule for system call %s on %s, ignoring: %m",
*p, seccomp_arch_to_string(arch));
}
/* The default action is ENOSYS. Respond with EPERM to all other "known" but not allow-listed
* syscalls. */
r = seccomp_add_syscall_filter_item(ctx, "@known", SCMP_ACT_ERRNO(EPERM), added, true, NULL);
if (r < 0)
log_warning_errno(r, "Failed to add rule for @known set on %s, ignoring: %m",
seccomp_arch_to_string(arch));
return 0;
}
@ -180,11 +188,13 @@ int setup_seccomp(uint64_t cap_list_retain, char **syscall_allow_list, char **sy
log_debug("Applying allow list on architecture: %s", seccomp_arch_to_string(arch));
r = seccomp_init_for_arch(&seccomp, arch, SCMP_ACT_ERRNO(EPERM));
/* We install ENOSYS as the default action, but it will only apply to syscalls which are not
* in the @known set, see above. */
r = seccomp_init_for_arch(&seccomp, arch, SCMP_ACT_ERRNO(ENOSYS));
if (r < 0)
return log_error_errno(r, "Failed to allocate seccomp object: %m");
r = seccomp_add_default_syscall_filter(seccomp, arch, cap_list_retain, syscall_allow_list, syscall_deny_list);
r = add_syscall_filters(seccomp, arch, cap_list_retain, syscall_allow_list, syscall_deny_list);
if (r < 0)
return r;