Blame 0001-qemu-seccomp-dont-kill-process-for-resource-contro.patch

Adam Williamson 151543
From: Daniel P. Berrangé <berrange@redhat.com>
Adam Williamson 151543
Date: Wed, 13 Mar 2019 09:49:03 +0000
Adam Williamson 151543
Subject: [PATCH RFC] seccomp: don't kill process for resource control syscalls
Adam Williamson 151543
Adam Williamson 151543
The Mesa library tries to set process affinity on some of its threads in
Adam Williamson 151543
order to optimize its performance. Currently this results in QEMU being
Adam Williamson 151543
immediately terminated when seccomp is enabled.
Adam Williamson 151543
Adam Williamson 151543
Mesa doesn't consider failure of the process affinity settings to be
Adam Williamson 151543
fatal to its operation, but our seccomp policy gives it no choice in
Adam Williamson 151543
gracefully handling this denial.
Adam Williamson 151543
Adam Williamson 151543
It is reasonable to consider that malicious code using the resource
Adam Williamson 151543
control syscalls to be a less serious attack than if they were trying
Adam Williamson 151543
to spawn processes or change UIDs and other such things. Generally
Adam Williamson 151543
speaking changing the resource control setting will "merely" affect
Adam Williamson 151543
quality of service of processes on the host. With this in mind, rather
Adam Williamson 151543
than kill the process, we can relax the policy for these syscalls to
Adam Williamson 151543
return the EPERM errno value. This allows callers to detect that QEMU
Adam Williamson 151543
does not want them to change resource allocations, and apply some
Adam Williamson 151543
reasonable fallback logic.
Adam Williamson 151543
Adam Williamson 151543
The main downside to this is for code which uses these syscalls but does
Adam Williamson 151543
not check the return value, blindly assuming they will always
Adam Williamson 151543
succeeed. Returning an errno could result in sub-optimal behaviour.
Adam Williamson 151543
Arguably though such code is already broken & needs fixing regardless.
Adam Williamson 151543
Adam Williamson 151543
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
Adam Williamson 151543
---
Adam Williamson 151543
 qemu-seccomp.c | 32 +++++++++++++++++++++++++-------
Adam Williamson 151543
 1 file changed, 25 insertions(+), 7 deletions(-)
Adam Williamson 151543
Adam Williamson 151543
diff --git a/qemu-seccomp.c b/qemu-seccomp.c
Adam Williamson 151543
index 36d5829831..9776c9ef40 100644
Adam Williamson 151543
--- a/qemu-seccomp.c
Adam Williamson 151543
+++ b/qemu-seccomp.c
Adam Williamson 151543
@@ -121,20 +121,37 @@ qemu_seccomp(unsigned int operation, unsigned int flags, void *args)
Adam Williamson 151543
 #endif
Adam Williamson 151543
 }
Adam Williamson 151543
 
Adam Williamson 151543
-static uint32_t qemu_seccomp_get_kill_action(void)
Adam Williamson 151543
+static uint32_t qemu_seccomp_get_kill_action(int set)
Adam Williamson 151543
 {
Adam Williamson 151543
+    switch (set) {
Adam Williamson 151543
+    case QEMU_SECCOMP_SET_DEFAULT:
Adam Williamson 151543
+    case QEMU_SECCOMP_SET_OBSOLETE:
Adam Williamson 151543
+    case QEMU_SECCOMP_SET_PRIVILEGED:
Adam Williamson 151543
+    case QEMU_SECCOMP_SET_SPAWN: {
Adam Williamson 151543
 #if defined(SECCOMP_GET_ACTION_AVAIL) && defined(SCMP_ACT_KILL_PROCESS) && \
Adam Williamson 151543
     defined(SECCOMP_RET_KILL_PROCESS)
Adam Williamson 151543
-    {
Adam Williamson 151543
-        uint32_t action = SECCOMP_RET_KILL_PROCESS;
Adam Williamson 151543
+        static int kill_process = -1;
Adam Williamson 151543
+        if (kill_process == -1) {
Adam Williamson 151543
+            uint32_t action = SECCOMP_RET_KILL_PROCESS;
Adam Williamson 151543
 
Adam Williamson 151543
-        if (qemu_seccomp(SECCOMP_GET_ACTION_AVAIL, 0, &action) == 0) {
Adam Williamson 151543
+            if (qemu_seccomp(SECCOMP_GET_ACTION_AVAIL, 0, &action) == 0) {
Adam Williamson 151543
+                kill_process = 1;
Adam Williamson 151543
+            }
Adam Williamson 151543
+            kill_process = 0;
Adam Williamson 151543
+        }
Adam Williamson 151543
+        if (kill_process == 1) {
Adam Williamson 151543
             return SCMP_ACT_KILL_PROCESS;
Adam Williamson 151543
         }
Adam Williamson 151543
-    }
Adam Williamson 151543
 #endif
Adam Williamson 151543
+        return SCMP_ACT_TRAP;
Adam Williamson 151543
+    }
Adam Williamson 151543
+
Adam Williamson 151543
+    case QEMU_SECCOMP_SET_RESOURCECTL:
Adam Williamson 151543
+        return SCMP_ACT_ERRNO(EPERM);
Adam Williamson 151543
 
Adam Williamson 151543
-    return SCMP_ACT_TRAP;
Adam Williamson 151543
+    default:
Adam Williamson 151543
+        g_assert_not_reached();
Adam Williamson 151543
+    }
Adam Williamson 151543
 }
Adam Williamson 151543
 
Adam Williamson 151543
 
Adam Williamson 151543
@@ -143,7 +160,6 @@ static int seccomp_start(uint32_t seccomp_opts)
Adam Williamson 151543
     int rc = 0;
Adam Williamson 151543
     unsigned int i = 0;
Adam Williamson 151543
     scmp_filter_ctx ctx;
Adam Williamson 151543
-    uint32_t action = qemu_seccomp_get_kill_action();
Adam Williamson 151543
 
Adam Williamson 151543
     ctx = seccomp_init(SCMP_ACT_ALLOW);
Adam Williamson 151543
     if (ctx == NULL) {
Adam Williamson 151543
@@ -157,10 +173,12 @@ static int seccomp_start(uint32_t seccomp_opts)
Adam Williamson 151543
     }
Adam Williamson 151543
 
Adam Williamson 151543
     for (i = 0; i < ARRAY_SIZE(blacklist); i++) {
Adam Williamson 151543
+        uint32_t action;
Adam Williamson 151543
         if (!(seccomp_opts & blacklist[i].set)) {
Adam Williamson 151543
             continue;
Adam Williamson 151543
         }
Adam Williamson 151543
 
Adam Williamson 151543
+        action = qemu_seccomp_get_kill_action(blacklist[i].set);
Adam Williamson 151543
         rc = seccomp_rule_add_array(ctx, action, blacklist[i].num,
Adam Williamson 151543
                                     blacklist[i].narg, blacklist[i].arg_cmp);
Adam Williamson 151543
         if (rc < 0) {
Adam Williamson 151543
-- 
Adam Williamson 151543
2.20.1