#endif
#include "async.h"
#include "barrier.h"
+#include "bpf-lsm.h"
#include "cap-list.h"
#include "capability-util.h"
#include "cgroup-setup.h"
return seccomp_restrict_namespaces(c->restrict_namespaces);
}
+#if HAVE_LIBBPF
+static bool skip_lsm_bpf_unsupported(const Unit* u, const char* msg) {
+ if (lsm_bpf_supported())
+ return false;
+
+ log_unit_debug(u, "LSM BPF not supported, skipping %s", msg);
+ return true;
+}
+
+static int apply_restrict_filesystems(Unit *u, const ExecContext *c) {
+ assert(u);
+ assert(c);
+
+ if (!exec_context_restrict_filesystems_set(c))
+ return 0;
+
+ if (skip_lsm_bpf_unsupported(u, "RestrictFileSystems="))
+ return 0;
+
+ return lsm_bpf_unit_restrict_filesystems(u, c->restrict_filesystems, c->restrict_filesystems_allow_list);
+}
+#endif
+
static int apply_lock_personality(const Unit* u, const ExecContext *c) {
unsigned long personality;
int r;
/* In case anything used libc syslog(), close this here, too */
closelog();
- int keep_fds[n_fds + 2];
+ int keep_fds[n_fds + 3];
memcpy_safe(keep_fds, fds, n_fds * sizeof(int));
n_keep_fds = n_fds;
return log_unit_error_errno(unit, r, "Failed to shift fd and set FD_CLOEXEC: %m");
}
+#if HAVE_LIBBPF
+ if (MANAGER_IS_SYSTEM(unit->manager) && lsm_bpf_supported()) {
+ int bpf_map_fd = -1;
+
+ bpf_map_fd = lsm_bpf_map_restrict_fs_fd(unit);
+ if (bpf_map_fd < 0) {
+ *exit_status = EXIT_FDS;
+ return log_unit_error_errno(unit, r, "Failed to get restrict filesystems BPF map fd: %m");
+ }
+
+ r = add_shifted_fd(keep_fds, ELEMENTSOF(keep_fds), &n_keep_fds, bpf_map_fd, &bpf_map_fd);
+ if (r < 0) {
+ *exit_status = EXIT_FDS;
+ return log_unit_error_errno(unit, r, "Failed to shift fd and set FD_CLOEXEC: %m");
+ }
+ }
+#endif
+
r = close_remaining_fds(params, runtime, dcreds, user_lookup_fd, socket_fd, keep_fds, n_keep_fds);
if (r < 0) {
*exit_status = EXIT_FDS;
return log_unit_error_errno(unit, r, "Failed to apply system call filters: %m");
}
#endif
+
+#if HAVE_LIBBPF
+ r = apply_restrict_filesystems(unit, context);
+ if (r < 0) {
+ *exit_status = EXIT_BPF;
+ return log_unit_error_errno(unit, r, "Failed to restrict filesystems: %m");
+ }
+#endif
+
}
if (!strv_isempty(context->unset_environment)) {
c->apparmor_profile = mfree(c->apparmor_profile);
c->smack_process_label = mfree(c->smack_process_label);
+ c->restrict_filesystems = set_free(c->restrict_filesystems);
+
c->syscall_filter = hashmap_free(c->syscall_filter);
c->syscall_archs = set_free(c->syscall_archs);
c->address_families = set_free(c->address_families);
prefix, strna(s));
}
+#if HAVE_LIBBPF
+ if (exec_context_restrict_filesystems_set(c))
+ SET_FOREACH(e, c->restrict_filesystems)
+ fprintf(f, "%sRestrictFileSystems: %s\n", prefix, *e);
+#endif
+
if (c->network_namespace_path)
fprintf(f,
"%sNetworkNamespacePath: %s\n",