summaryrefslogtreecommitdiff
path: root/src/core/execute.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/execute.c')
-rw-r--r--src/core/execute.c65
1 files changed, 64 insertions, 1 deletions
diff --git a/src/core/execute.c b/src/core/execute.c
index ae251b2a4c..a20e9ea829 100644
--- a/src/core/execute.c
+++ b/src/core/execute.c
@@ -1422,12 +1422,67 @@ finish:
return r;
}
+static int apply_private_devices(Unit *u, const ExecContext *c) {
+
+ static const int device_syscalls[] = {
+ SCMP_SYS(ioperm),
+ SCMP_SYS(iopl),
+ SCMP_SYS(pciconfig_iobase),
+ SCMP_SYS(pciconfig_read),
+ SCMP_SYS(pciconfig_write),
+#ifdef __NR_s390_pci_mmio_read
+ SCMP_SYS(s390_pci_mmio_read),
+#endif
+#ifdef __NR_s390_pci_mmio_write
+ SCMP_SYS(s390_pci_mmio_write),
+#endif
+ };
+
+ scmp_filter_ctx *seccomp;
+ unsigned i;
+ int r;
+
+ assert(c);
+
+ /* If PrivateDevices= is set, also turn off iopl and friends. */
+
+ if (skip_seccomp_unavailable(u, "PrivateDevices="))
+ return 0;
+
+ seccomp = seccomp_init(SCMP_ACT_ALLOW);
+ if (!seccomp)
+ return -ENOMEM;
+
+ r = seccomp_add_secondary_archs(seccomp);
+ if (r < 0)
+ goto finish;
+
+ for (i = 0; i < ELEMENTSOF(device_syscalls); i++) {
+ r = seccomp_rule_add(
+ seccomp,
+ SCMP_ACT_ERRNO(EPERM),
+ device_syscalls[i],
+ 0);
+ if (r < 0)
+ goto finish;
+ }
+
+ r = seccomp_attr_set(seccomp, SCMP_FLTATR_CTL_NNP, 0);
+ if (r < 0)
+ goto finish;
+
+ r = seccomp_load(seccomp);
+
+finish:
+ seccomp_release(seccomp);
+ return r;
+}
+
#endif
static void do_idle_pipe_dance(int idle_pipe[4]) {
assert(idle_pipe);
-
idle_pipe[1] = safe_close(idle_pipe[1]);
idle_pipe[2] = safe_close(idle_pipe[2]);
@@ -2584,6 +2639,14 @@ static int exec_child(
}
}
+ if (context->private_devices) {
+ r = apply_private_devices(unit, context);
+ if (r < 0) {
+ *exit_status = EXIT_SECCOMP;
+ return r;
+ }
+ }
+
if (context_has_syscall_filters(context)) {
r = apply_seccomp(unit, context);
if (r < 0) {