#include "strv.h"
#if HAVE_SECCOMP
+static void *libseccomp_dl = NULL;
+
+DLSYM_PROTOTYPE(seccomp_api_get) = NULL;
+DLSYM_PROTOTYPE(seccomp_arch_add) = NULL;
+DLSYM_PROTOTYPE(seccomp_arch_exist) = NULL;
+DLSYM_PROTOTYPE(seccomp_arch_native) = NULL;
+DLSYM_PROTOTYPE(seccomp_arch_remove) = NULL;
+DLSYM_PROTOTYPE(seccomp_attr_set) = NULL;
+DLSYM_PROTOTYPE(seccomp_init) = NULL;
+DLSYM_PROTOTYPE(seccomp_load) = NULL;
+DLSYM_PROTOTYPE(seccomp_release) = NULL;
+DLSYM_PROTOTYPE(seccomp_rule_add_array) = NULL;
+DLSYM_PROTOTYPE(seccomp_rule_add_exact) = NULL;
+DLSYM_PROTOTYPE(seccomp_syscall_resolve_name) = NULL;
+DLSYM_PROTOTYPE(seccomp_syscall_resolve_num_arch) = NULL;
+
+int dlopen_libseccomp(void) {
+ ELF_NOTE_DLOPEN("seccomp",
+ "Support for Seccomp Sandboxes",
+ ELF_NOTE_DLOPEN_PRIORITY_RECOMMENDED,
+ "libseccomp.so.2");
+
+ return dlopen_many_sym_or_warn(
+ &libseccomp_dl,
+ "libseccomp.so.2",
+ LOG_DEBUG,
+ DLSYM_ARG(seccomp_api_get),
+ DLSYM_ARG(seccomp_arch_add),
+ DLSYM_ARG(seccomp_arch_exist),
+ DLSYM_ARG(seccomp_arch_native),
+ DLSYM_ARG(seccomp_arch_remove),
+ DLSYM_ARG(seccomp_attr_set),
+ DLSYM_ARG(seccomp_init),
+ DLSYM_ARG(seccomp_load),
+ DLSYM_ARG(seccomp_release),
+ DLSYM_ARG(seccomp_rule_add_array),
+ DLSYM_ARG(seccomp_rule_add_exact),
+ DLSYM_ARG(seccomp_syscall_resolve_name),
+ DLSYM_ARG(seccomp_syscall_resolve_num_arch));
+}
/* This array will be modified at runtime as seccomp_restrict_archs is called. */
uint32_t seccomp_local_archs[] = {
/* Much like seccomp_init(), but initializes the filter for one specific architecture only, without affecting
* any others. Also, turns off the NNP fiddling. */
- seccomp = seccomp_init(default_action);
+ r = dlopen_libseccomp();
+ if (r < 0)
+ return r;
+
+ seccomp = sym_seccomp_init(default_action);
if (!seccomp)
return -ENOMEM;
if (arch != SCMP_ARCH_NATIVE &&
- arch != seccomp_arch_native()) {
+ arch != sym_seccomp_arch_native()) {
- r = seccomp_arch_remove(seccomp, seccomp_arch_native());
+ r = sym_seccomp_arch_remove(seccomp, sym_seccomp_arch_native());
if (r < 0)
return r;
- r = seccomp_arch_add(seccomp, arch);
+ r = sym_seccomp_arch_add(seccomp, arch);
if (r < 0)
return r;
- assert(seccomp_arch_exist(seccomp, arch) >= 0);
- assert(seccomp_arch_exist(seccomp, SCMP_ARCH_NATIVE) == -EEXIST);
- assert(seccomp_arch_exist(seccomp, seccomp_arch_native()) == -EEXIST);
+ assert(sym_seccomp_arch_exist(seccomp, arch) >= 0);
+ assert(sym_seccomp_arch_exist(seccomp, SCMP_ARCH_NATIVE) == -EEXIST);
+ assert(sym_seccomp_arch_exist(seccomp, sym_seccomp_arch_native()) == -EEXIST);
} else {
- assert(seccomp_arch_exist(seccomp, SCMP_ARCH_NATIVE) >= 0);
- assert(seccomp_arch_exist(seccomp, seccomp_arch_native()) >= 0);
+ assert(sym_seccomp_arch_exist(seccomp, SCMP_ARCH_NATIVE) >= 0);
+ assert(sym_seccomp_arch_exist(seccomp, sym_seccomp_arch_native()) >= 0);
}
- r = seccomp_attr_set(seccomp, SCMP_FLTATR_ACT_BADARCH, SCMP_ACT_ALLOW);
+ r = sym_seccomp_attr_set(seccomp, SCMP_FLTATR_ACT_BADARCH, SCMP_ACT_ALLOW);
if (r < 0)
return r;
- r = seccomp_attr_set(seccomp, SCMP_FLTATR_CTL_NNP, 0);
+ r = sym_seccomp_attr_set(seccomp, SCMP_FLTATR_CTL_NNP, 0);
if (r < 0)
return r;
#if SCMP_VER_MAJOR >= 3 || (SCMP_VER_MAJOR == 2 && SCMP_VER_MINOR >= 4)
if (getenv_bool("SYSTEMD_LOG_SECCOMP") > 0) {
- r = seccomp_attr_set(seccomp, SCMP_FLTATR_CTL_LOG, 1);
+ r = sym_seccomp_attr_set(seccomp, SCMP_FLTATR_CTL_LOG, 1);
if (r < 0)
log_debug_errno(r, "Failed to enable seccomp event logging: %m");
}
static int cached_enabled = -1;
if (cached_enabled < 0) {
- int b;
+ if (dlopen_libseccomp() < 0)
+ return (cached_enabled = false);
- b = secure_getenv_bool("SYSTEMD_SECCOMP");
+ int b = secure_getenv_bool("SYSTEMD_SECCOMP");
if (b != 0) {
if (b < 0 && b != -ENXIO) /* ENXIO: env var unset */
log_debug_errno(b, "Failed to parse $SYSTEMD_SECCOMP value, ignoring.");
} else {
int id, r;
- id = seccomp_syscall_resolve_name(name);
+ r = dlopen_libseccomp();
+ if (r < 0)
+ return r;
+
+ id = sym_seccomp_syscall_resolve_name(name);
if (id == __NR_SCMP_ERROR) {
if (log_missing)
log_debug("System call %s is not known, ignoring.", name);
return 0;
}
- r = seccomp_rule_add_exact(seccomp, action, id, 0);
+ r = sym_seccomp_rule_add_exact(seccomp, action, id, 0);
if (r < 0) {
/* If the system call is not known on this architecture, then that's fine, let's ignore it */
bool ignore = r == -EDOM;
/* The one-stop solution: allocate a seccomp object, add the specified filter to it, and apply it. Once for
* each local arch. */
+ r = dlopen_libseccomp();
+ if (r < 0)
+ return r;
+
default_action_override = override_default_action(default_action);
SECCOMP_FOREACH_LOCAL_ARCH(arch) {
NULSTR_FOREACH(name, syscall_filter_sets[SYSCALL_FILTER_SET_KNOWN].value) {
int id;
- id = seccomp_syscall_resolve_name(name);
+ id = sym_seccomp_syscall_resolve_name(name);
if (id < 0)
continue;
if (strv_contains(added, name))
continue;
- r = seccomp_rule_add_exact(seccomp, default_action, id, 0);
+ r = sym_seccomp_rule_add_exact(seccomp, default_action, id, 0);
if (r < 0 && r != -EDOM) /* EDOM means that the syscall is not available for arch */
return log_debug_errno(r, "Failed to add rule for system call %s() / %d: %m",
name, id);
#if (SCMP_VER_MAJOR == 2 && SCMP_VER_MINOR >= 5) || SCMP_VER_MAJOR > 2
/* We have a large filter here, so let's turn on the binary tree mode if possible. */
- r = seccomp_attr_set(seccomp, SCMP_FLTATR_CTL_OPTIMIZE, 2);
+ r = sym_seccomp_attr_set(seccomp, SCMP_FLTATR_CTL_OPTIMIZE, 2);
if (r < 0)
log_warning_errno(r, "Failed to set SCMP_FLTATR_CTL_OPTIMIZE, ignoring: %m");
#endif
- r = seccomp_load(seccomp);
+ r = sym_seccomp_load(seccomp);
if (ERRNO_IS_NEG_SECCOMP_FATAL(r))
return r;
if (r < 0)
if (hashmap_isempty(filter) && default_action == SCMP_ACT_ALLOW)
return 0;
+ r = dlopen_libseccomp();
+ if (r < 0)
+ return r;
+
default_action_override = override_default_action(default_action);
SECCOMP_FOREACH_LOCAL_ARCH(arch) {
else if (error >= 0)
a = SCMP_ACT_ERRNO(error);
- r = seccomp_rule_add_exact(seccomp, a, id, 0);
+ r = sym_seccomp_rule_add_exact(seccomp, a, id, 0);
if (r < 0) {
/* If the system call is not known on this architecture, then that's
* fine, let's ignore it */
_cleanup_free_ char *n = NULL;
bool ignore;
- n = seccomp_syscall_resolve_num_arch(SCMP_ARCH_NATIVE, id);
+ n = sym_seccomp_syscall_resolve_num_arch(SCMP_ARCH_NATIVE, id);
ignore = r == -EDOM;
if (!ignore || log_missing)
log_debug_errno(r, "Failed to add rule for system call %s() / %d%s: %m",
NULSTR_FOREACH(name, syscall_filter_sets[SYSCALL_FILTER_SET_KNOWN].value) {
int id;
- id = seccomp_syscall_resolve_name(name);
+ id = sym_seccomp_syscall_resolve_name(name);
if (id < 0)
continue;
if (hashmap_contains(filter, INT_TO_PTR(id + 1)))
continue;
- r = seccomp_rule_add_exact(seccomp, default_action, id, 0);
+ r = sym_seccomp_rule_add_exact(seccomp, default_action, id, 0);
if (r < 0 && r != -EDOM) /* EDOM means that the syscall is not available for arch */
return log_debug_errno(r, "Failed to add rule for system call %s() / %d: %m",
name, id);
#if (SCMP_VER_MAJOR == 2 && SCMP_VER_MINOR >= 5) || SCMP_VER_MAJOR > 2
/* We have a large filter here, so let's turn on the binary tree mode if possible. */
- r = seccomp_attr_set(seccomp, SCMP_FLTATR_CTL_OPTIMIZE, 2);
+ r = sym_seccomp_attr_set(seccomp, SCMP_FLTATR_CTL_OPTIMIZE, 2);
if (r < 0)
log_warning_errno(r, "Failed to set SCMP_FLTATR_CTL_OPTIMIZE, ignoring: %m");
#endif
- r = seccomp_load(seccomp);
+ r = sym_seccomp_load(seccomp);
if (ERRNO_IS_NEG_SECCOMP_FATAL(r))
return r;
if (r < 0)
} else {
int id;
- id = seccomp_syscall_resolve_name(name);
+ r = dlopen_libseccomp();
+ if (r < 0) {
+ if (!FLAGS_SET(flags, SECCOMP_PARSE_PERMISSIVE))
+ return r;
+
+ log_syntax(unit, FLAGS_SET(flags, SECCOMP_PARSE_LOG) ? LOG_WARNING : LOG_DEBUG, filename, line, r,
+ "System call %s cannot be resolved as libseccomp is not available, ignoring: %m", name);
+ return 0;
+ }
+
+ id = sym_seccomp_syscall_resolve_name(name);
if (id == __NR_SCMP_ERROR) {
if (!FLAGS_SET(flags, SECCOMP_PARSE_PERMISSIVE))
return -EINVAL;
if (FLAGS_SET(retain, NAMESPACE_FLAGS_ALL))
return 0;
+ r = dlopen_libseccomp();
+ if (r < 0)
+ return r;
+
SECCOMP_FOREACH_LOCAL_ARCH(arch) {
_cleanup_(seccomp_releasep) scmp_filter_ctx seccomp = NULL;
* C.f. https://github.com/flatpak/flatpak/commit/a10f52a7565c549612c92b8e736a6698a53db330,
* https://github.com/moby/moby/issues/42680. */
- r = seccomp_rule_add_exact(
+ r = sym_seccomp_rule_add_exact(
seccomp,
SCMP_ACT_ERRNO(ENOSYS),
SCMP_SYS(clone3),
if ((retain & NAMESPACE_FLAGS_ALL) == 0)
/* If every single kind of namespace shall be prohibited, then let's block the whole
* setns() syscall altogether. */
- r = seccomp_rule_add_exact(
+ r = sym_seccomp_rule_add_exact(
seccomp,
SCMP_ACT_ERRNO(EPERM),
SCMP_SYS(setns),
else
/* Otherwise, block only the invocations with the appropriate flags in the loop
* below, but also the special invocation with a zero flags argument, right here. */
- r = seccomp_rule_add_exact(
+ r = sym_seccomp_rule_add_exact(
seccomp,
SCMP_ACT_ERRNO(EPERM),
SCMP_SYS(setns),
log_trace("Blocking %s.", namespace_info[i].proc_name);
- r = seccomp_rule_add_exact(
+ r = sym_seccomp_rule_add_exact(
seccomp,
SCMP_ACT_ERRNO(EPERM),
SCMP_SYS(unshare),
/* On s390/s390x the first two parameters to clone are switched */
if (!IN_SET(arch, SCMP_ARCH_S390, SCMP_ARCH_S390X))
- r = seccomp_rule_add_exact(
+ r = sym_seccomp_rule_add_exact(
seccomp,
SCMP_ACT_ERRNO(EPERM),
SCMP_SYS(clone),
1,
SCMP_A0(SCMP_CMP_MASKED_EQ, f, f));
else
- r = seccomp_rule_add_exact(
+ r = sym_seccomp_rule_add_exact(
seccomp,
SCMP_ACT_ERRNO(EPERM),
SCMP_SYS(clone),
}
if ((retain & NAMESPACE_FLAGS_ALL) != 0) {
- r = seccomp_rule_add_exact(
+ r = sym_seccomp_rule_add_exact(
seccomp,
SCMP_ACT_ERRNO(EPERM),
SCMP_SYS(setns),
if (r < 0)
continue;
- r = seccomp_load(seccomp);
+ r = sym_seccomp_load(seccomp);
if (ERRNO_IS_NEG_SECCOMP_FATAL(r))
return r;
if (r < 0)
uint32_t arch;
int r;
+ r = dlopen_libseccomp();
+ if (r < 0)
+ return r;
+
SECCOMP_FOREACH_LOCAL_ARCH(arch) {
_cleanup_(seccomp_releasep) scmp_filter_ctx seccomp = NULL;
if (r < 0)
return r;
- r = seccomp_rule_add_exact(
+ r = sym_seccomp_rule_add_exact(
seccomp,
SCMP_ACT_ERRNO(EPERM),
SCMP_SYS(_sysctl),
continue;
}
- r = seccomp_load(seccomp);
+ r = sym_seccomp_load(seccomp);
if (ERRNO_IS_NEG_SECCOMP_FATAL(r))
return r;
if (r < 0)
uint32_t arch;
int r;
+ r = dlopen_libseccomp();
+ if (r < 0)
+ return r;
+
SECCOMP_FOREACH_LOCAL_ARCH(arch) {
_cleanup_(seccomp_releasep) scmp_filter_ctx seccomp = NULL;
if (r < 0)
return r;
- r = seccomp_rule_add_exact(
+ r = sym_seccomp_rule_add_exact(
seccomp,
SCMP_ACT_ERRNO(EPERM),
SCMP_SYS(syslog),
continue;
}
- r = seccomp_load(seccomp);
+ r = sym_seccomp_load(seccomp);
if (ERRNO_IS_NEG_SECCOMP_FATAL(r))
return r;
if (r < 0)
uint32_t arch;
int r;
+ r = dlopen_libseccomp();
+ if (r < 0)
+ return r;
+
SECCOMP_FOREACH_LOCAL_ARCH(arch) {
_cleanup_(seccomp_releasep) scmp_filter_ctx seccomp = NULL;
bool supported;
if (first == 0) {
/* No entries in the valid range, block everything */
- r = seccomp_rule_add_exact(
+ r = sym_seccomp_rule_add_exact(
seccomp,
SCMP_ACT_ERRNO(EAFNOSUPPORT),
SCMP_SYS(socket),
} else {
/* Block everything below the first entry */
- r = seccomp_rule_add_exact(
+ r = sym_seccomp_rule_add_exact(
seccomp,
SCMP_ACT_ERRNO(EAFNOSUPPORT),
SCMP_SYS(socket),
}
/* Block everything above the last entry */
- r = seccomp_rule_add_exact(
+ r = sym_seccomp_rule_add_exact(
seccomp,
SCMP_ACT_ERRNO(EAFNOSUPPORT),
SCMP_SYS(socket),
if (set_contains(address_families, INT_TO_PTR(af)))
continue;
- r = seccomp_rule_add_exact(
+ r = sym_seccomp_rule_add_exact(
seccomp,
SCMP_ACT_ERRNO(EAFNOSUPPORT),
SCMP_SYS(socket),
* then combined in OR checks. */
SET_FOREACH(af, address_families) {
- r = seccomp_rule_add_exact(
+ r = sym_seccomp_rule_add_exact(
seccomp,
SCMP_ACT_ERRNO(EAFNOSUPPORT),
SCMP_SYS(socket),
}
}
- r = seccomp_load(seccomp);
+ r = sym_seccomp_load(seccomp);
if (ERRNO_IS_NEG_SECCOMP_FATAL(r))
return r;
if (r < 0)
assert(error_code > 0);
+ r = dlopen_libseccomp();
+ if (r < 0)
+ return r;
+
/* Determine the highest policy constant we want to allow */
FOREACH_ELEMENT(policy, permitted_policies)
if (*policy > max_policy)
continue;
/* Deny this policy */
- r = seccomp_rule_add_exact(
+ r = sym_seccomp_rule_add_exact(
seccomp,
SCMP_ACT_ERRNO(error_code),
SCMP_SYS(sched_setscheduler),
/* Deny-list all other policies, i.e. the ones with higher values. Note that all comparisons
* are unsigned here, hence no need no check for < 0 values. */
- r = seccomp_rule_add_exact(
+ r = sym_seccomp_rule_add_exact(
seccomp,
SCMP_ACT_ERRNO(error_code),
SCMP_SYS(sched_setscheduler),
continue;
}
- r = seccomp_load(seccomp);
+ r = sym_seccomp_load(seccomp);
if (ERRNO_IS_NEG_SECCOMP_FATAL(r))
return r;
if (r < 0)
const struct scmp_arg_cmp arg) {
int r;
- r = seccomp_rule_add_exact(seccomp, SCMP_ACT_ERRNO(EPERM), nr, arg_cnt, arg);
+ r = sym_seccomp_rule_add_exact(seccomp, SCMP_ACT_ERRNO(EPERM), nr, arg_cnt, arg);
if (r < 0) {
_cleanup_free_ char *n = NULL;
- n = seccomp_syscall_resolve_num_arch(arch, nr);
+ n = sym_seccomp_syscall_resolve_num_arch(arch, nr);
log_debug_errno(r, "Failed to add %s() rule for architecture %s, skipping: %m",
strna(n),
seccomp_arch_to_string(arch));
int seccomp_memory_deny_write_execute(void) {
uint32_t arch;
unsigned loaded = 0;
+ int r;
+
+ r = dlopen_libseccomp();
+ if (r < 0)
+ return r;
SECCOMP_FOREACH_LOCAL_ARCH(arch) {
_cleanup_(seccomp_releasep) scmp_filter_ctx seccomp = NULL;
- int filter_syscall = 0, block_syscall = 0, shmat_syscall = 0, r;
+ int filter_syscall = 0, block_syscall = 0, shmat_syscall = 0;
log_trace("Operating on architecture: %s", seccomp_arch_to_string(arch));
continue;
}
- r = seccomp_load(seccomp);
+ r = sym_seccomp_load(seccomp);
if (ERRNO_IS_NEG_SECCOMP_FATAL(r))
return r;
if (r < 0)
int r;
bool blocked_new = false;
+ r = dlopen_libseccomp();
+ if (r < 0)
+ return r;
+
/* This installs a filter with no rules, but that restricts the system call architectures to the specified
* list.
*
/* Note libseccomp includes our "native" (current) architecture in the filter by default.
* We do not remove it. For example, our callers expect to be able to call execve() afterwards
* to run a program with the restrictions applied. */
- seccomp = seccomp_init(SCMP_ACT_ALLOW);
+ seccomp = sym_seccomp_init(SCMP_ACT_ALLOW);
if (!seccomp)
return -ENOMEM;
uint32_t arch = seccomp_local_archs[i];
/* See above comment, our "native" architecture is never blocked. */
- if (arch == seccomp_arch_native())
+ if (arch == sym_seccomp_arch_native())
continue;
/* That architecture might have already been blocked by a previous call to seccomp_restrict_archs. */
* x32 syscalls should basically match x86-64 for everything except the pointer type.
* The important thing is that you can block the old 32-bit x86 syscalls.
* https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=850047 */
- if (block && arch == SCMP_ARCH_X86_64 && seccomp_arch_native() == SCMP_ARCH_X32)
+ if (block && arch == SCMP_ARCH_X86_64 && sym_seccomp_arch_native() == SCMP_ARCH_X32)
block = !set_contains(archs, UINT32_TO_PTR(SCMP_ARCH_X32 + 1));
if (block) {
seccomp_local_archs[i] = SECCOMP_LOCAL_ARCH_BLOCKED;
blocked_new = true;
} else {
- r = seccomp_arch_add(seccomp, arch);
+ r = sym_seccomp_arch_add(seccomp, arch);
if (r < 0 && r != -EEXIST)
return r;
}
if (!blocked_new)
return 0;
- r = seccomp_attr_set(seccomp, SCMP_FLTATR_CTL_NNP, 0);
+ r = sym_seccomp_attr_set(seccomp, SCMP_FLTATR_CTL_NNP, 0);
if (r < 0)
return r;
- r = seccomp_load(seccomp);
+ r = sym_seccomp_load(seccomp);
if (ERRNO_IS_NEG_SECCOMP_FATAL(r))
return r;
if (r < 0)
}
int seccomp_filter_set_add_by_name(Hashmap *filter, bool add, const char *name) {
+ int r;
+
assert(filter);
assert(name);
+ r = dlopen_libseccomp();
+ if (r < 0)
+ return r;
+
if (name[0] == '@') {
const SyscallFilterSet *more;
return seccomp_filter_set_add(filter, add, more);
}
- int id = seccomp_syscall_resolve_name(name);
+ int id = sym_seccomp_syscall_resolve_name(name);
if (id == __NR_SCMP_ERROR) {
log_debug("System call %s is not known, ignoring.", name);
return 0;
if (personality >= PERSONALITY_INVALID)
return -EINVAL;
+ r = dlopen_libseccomp();
+ if (r < 0)
+ return r;
+
SECCOMP_FOREACH_LOCAL_ARCH(arch) {
_cleanup_(seccomp_releasep) scmp_filter_ctx seccomp = NULL;
if (r < 0)
return r;
- r = seccomp_rule_add_exact(
+ r = sym_seccomp_rule_add_exact(
seccomp,
SCMP_ACT_ERRNO(EPERM),
SCMP_SYS(personality),
continue;
}
- r = seccomp_load(seccomp);
+ r = sym_seccomp_load(seccomp);
if (ERRNO_IS_NEG_SECCOMP_FATAL(r))
return r;
if (r < 0)
uint32_t arch;
int r;
+ r = dlopen_libseccomp();
+ if (r < 0)
+ return r;
+
SECCOMP_FOREACH_LOCAL_ARCH(arch) {
_cleanup_(seccomp_releasep) scmp_filter_ctx seccomp = NULL;
if (r < 0)
return r;
- r = seccomp_rule_add_exact(
+ r = sym_seccomp_rule_add_exact(
seccomp,
SCMP_ACT_ERRNO(EPERM),
SCMP_SYS(sethostname),
continue;
}
- r = seccomp_rule_add_exact(
+ r = sym_seccomp_rule_add_exact(
seccomp,
SCMP_ACT_ERRNO(EPERM),
SCMP_SYS(setdomainname),
continue;
}
- r = seccomp_load(seccomp);
+ r = sym_seccomp_load(seccomp);
if (ERRNO_IS_NEG_SECCOMP_FATAL(r))
return r;
if (r < 0)
int r;
bool any = false;
- r = seccomp_rule_add_exact(
+ r = sym_seccomp_rule_add_exact(
seccomp,
SCMP_ACT_ERRNO(EPERM),
SCMP_SYS(chmod),
else
any = true;
- r = seccomp_rule_add_exact(
+ r = sym_seccomp_rule_add_exact(
seccomp,
SCMP_ACT_ERRNO(EPERM),
SCMP_SYS(fchmod),
else
any = true;
- r = seccomp_rule_add_exact(
+ r = sym_seccomp_rule_add_exact(
seccomp,
SCMP_ACT_ERRNO(EPERM),
SCMP_SYS(fchmodat),
any = true;
#if defined(__SNR_fchmodat2)
- r = seccomp_rule_add_exact(
+ r = sym_seccomp_rule_add_exact(
seccomp,
SCMP_ACT_ERRNO(EPERM),
SCMP_SYS(fchmodat2),
/* It looks like this libseccomp does not know about fchmodat2().
* Pretend the fchmodat2() system call is not supported at all,
* regardless of the kernel version. */
- r = seccomp_rule_add_exact(
+ r = sym_seccomp_rule_add_exact(
seccomp,
SCMP_ACT_ERRNO(ENOSYS),
__NR_fchmodat2,
else
any = true;
- r = seccomp_rule_add_exact(
+ r = sym_seccomp_rule_add_exact(
seccomp,
SCMP_ACT_ERRNO(EPERM),
SCMP_SYS(mkdir),
else
any = true;
- r = seccomp_rule_add_exact(
+ r = sym_seccomp_rule_add_exact(
seccomp,
SCMP_ACT_ERRNO(EPERM),
SCMP_SYS(mkdirat),
else
any = true;
- r = seccomp_rule_add_exact(
+ r = sym_seccomp_rule_add_exact(
seccomp,
SCMP_ACT_ERRNO(EPERM),
SCMP_SYS(mknod),
else
any = true;
- r = seccomp_rule_add_exact(
+ r = sym_seccomp_rule_add_exact(
seccomp,
SCMP_ACT_ERRNO(EPERM),
SCMP_SYS(mknodat),
else
any = true;
- r = seccomp_rule_add_exact(
+ r = sym_seccomp_rule_add_exact(
seccomp,
SCMP_ACT_ERRNO(EPERM),
SCMP_SYS(open),
else
any = true;
- r = seccomp_rule_add_exact(
+ r = sym_seccomp_rule_add_exact(
seccomp,
SCMP_ACT_ERRNO(EPERM),
SCMP_SYS(openat),
* compatible with kernels that are not absolutely recent. We would normally return EPERM for a
* policy check, but this isn't strictly a policy check. Instead, we return ENOSYS to force programs
* to call open() or openat() instead. We can properly enforce policy for those functions. */
- r = seccomp_rule_add_exact(
+ r = sym_seccomp_rule_add_exact(
seccomp,
SCMP_ACT_ERRNO(ENOSYS),
SCMP_SYS(openat2),
any = true;
#endif
- r = seccomp_rule_add_exact(
+ r = sym_seccomp_rule_add_exact(
seccomp,
SCMP_ACT_ERRNO(EPERM),
SCMP_SYS(creat),
uint32_t arch;
int r, k;
+ r = dlopen_libseccomp();
+ if (r < 0)
+ return r;
+
SECCOMP_FOREACH_LOCAL_ARCH(arch) {
_cleanup_(seccomp_releasep) scmp_filter_ctx seccomp = NULL;
if (r < 0 && k < 0)
continue;
- r = seccomp_load(seccomp);
+ r = sym_seccomp_load(seccomp);
if (ERRNO_IS_NEG_SECCOMP_FATAL(r))
return r;
if (r < 0)
* for single-threaded apps does the right thing. */
#ifdef SCMP_ACT_KILL_PROCESS
- if (seccomp_api_get() >= 3)
+ if (dlopen_libseccomp() >= 0 && sym_seccomp_api_get() >= 3)
return SCMP_ACT_KILL_PROCESS;
#endif
/* Blocks open() with the specified flag, where flag is O_SYNC or so. This makes these calls return
* EINVAL, in the hope the client code will retry without O_SYNC then. */
- r = seccomp_rule_add_exact(
+ r = sym_seccomp_rule_add_exact(
seccomp,
SCMP_ACT_ERRNO(EINVAL),
SCMP_SYS(open),
else
any = true;
- r = seccomp_rule_add_exact(
+ r = sym_seccomp_rule_add_exact(
seccomp,
SCMP_ACT_ERRNO(EINVAL),
SCMP_SYS(openat),
#if defined(__SNR_openat2)
/* The new openat2() system call can't be filtered sensibly, see above. */
- r = seccomp_rule_add_exact(
+ r = sym_seccomp_rule_add_exact(
seccomp,
SCMP_ACT_ERRNO(ENOSYS),
SCMP_SYS(openat2),
*
* Additionally, O_SYNC/O_DSYNC are masked. */
+ r = dlopen_libseccomp();
+ if (r < 0)
+ return r;
+
SECCOMP_FOREACH_LOCAL_ARCH(arch) {
_cleanup_(seccomp_releasep) scmp_filter_ctx seccomp = NULL;
NULSTR_FOREACH(c, syscall_filter_sets[SYSCALL_FILTER_SET_SYNC].value) {
int id;
- id = seccomp_syscall_resolve_name(c);
+ id = sym_seccomp_syscall_resolve_name(c);
if (id == __NR_SCMP_ERROR) {
log_debug("System call %s is not known, ignoring.", c);
continue;
}
if (STR_IN_SET(c, "fdatasync", "fsync", "sync_file_range", "sync_file_range2", "syncfs"))
- r = seccomp_rule_add_exact(
+ r = sym_seccomp_rule_add_exact(
seccomp,
SCMP_ACT_ERRNO(0), /* success → we want this to be a NOP after all */
id,
* means non-negative fd matches the rule, and the negative
* fd passed to the syscall (then it fails with EBADF). */
else
- r = seccomp_rule_add_exact(
+ r = sym_seccomp_rule_add_exact(
seccomp,
SCMP_ACT_ERRNO(0), /* success → we want this to be a NOP after all */
id,
(void) block_open_flag(seccomp, O_DSYNC);
#endif
- r = seccomp_load(seccomp);
+ r = sym_seccomp_load(seccomp);
if (ERRNO_IS_NEG_SECCOMP_FATAL(r))
return r;
if (r < 0)