render / rpms / libvirt

Forked from rpms/libvirt 9 months ago
Clone
03cc27
From 1abebbf11f518fcd8a70133245be7b8ea4b094ea Mon Sep 17 00:00:00 2001
03cc27
Message-Id: <1abebbf11f518fcd8a70133245be7b8ea4b094ea@dist-git>
03cc27
From: Jonathon Jongsma <jjongsma@redhat.com>
03cc27
Date: Fri, 1 May 2020 16:53:39 -0500
03cc27
Subject: [PATCH] qemu: don't hold monitor and agent job when setting time
03cc27
03cc27
We have to assume that the guest agent may be malicious so we don't want
03cc27
to allow any agent queries to block any other libvirt API. By holding
03cc27
a monitor job while we're querying the agent, we open ourselves up to a
03cc27
DoS.
03cc27
03cc27
Split the function so that the portion issuing the agent command only
03cc27
holds an agent job and the portion issuing the monitor command holds
03cc27
only a monitor job.
03cc27
03cc27
Signed-off-by: Jonathon Jongsma <jjongsma@redhat.com>
03cc27
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
03cc27
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
03cc27
(cherry picked from commit e005c95f56fee9ed780be7f8db103d690bd34cbd)
03cc27
03cc27
CVE-2019-20485
03cc27
03cc27
Signed-off-by: Jonathon Jongsma <jjongsma@redhat.com>
03cc27
Message-Id: <20200501215341.27683-4-jjongsma@redhat.com>
03cc27
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
03cc27
---
03cc27
 src/qemu/qemu_driver.c | 54 +++++++++++++++++++++++++++---------------
03cc27
 1 file changed, 35 insertions(+), 19 deletions(-)
03cc27
03cc27
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
03cc27
index 888c586a79..0f6641702d 100644
03cc27
--- a/src/qemu/qemu_driver.c
03cc27
+++ b/src/qemu/qemu_driver.c
03cc27
@@ -19455,6 +19455,35 @@ qemuDomainGetTime(virDomainPtr dom,
03cc27
     return ret;
03cc27
 }
03cc27
 
03cc27
+static int
03cc27
+qemuDomainSetTimeAgent(virQEMUDriverPtr driver,
03cc27
+                       virDomainObjPtr vm,
03cc27
+                       long long seconds,
03cc27
+                       unsigned int nseconds,
03cc27
+                       bool rtcSync)
03cc27
+{
03cc27
+    qemuAgentPtr agent;
03cc27
+    int ret = -1;
03cc27
+
03cc27
+    if (qemuDomainObjBeginAgentJob(driver, vm, QEMU_AGENT_JOB_MODIFY) < 0)
03cc27
+        return -1;
03cc27
+
03cc27
+    if (virDomainObjCheckActive(vm) < 0)
03cc27
+        goto endjob;
03cc27
+
03cc27
+    if (!qemuDomainAgentAvailable(vm, true))
03cc27
+        goto endjob;
03cc27
+
03cc27
+    agent = qemuDomainObjEnterAgent(vm);
03cc27
+    ret = qemuAgentSetTime(agent, seconds, nseconds, rtcSync);
03cc27
+    qemuDomainObjExitAgent(vm, agent);
03cc27
+
03cc27
+ endjob:
03cc27
+    qemuDomainObjEndJob(driver, vm);
03cc27
+    return ret;
03cc27
+}
03cc27
+
03cc27
+
03cc27
 static int
03cc27
 qemuDomainSetTime(virDomainPtr dom,
03cc27
                   long long seconds,
03cc27
@@ -19464,7 +19493,6 @@ qemuDomainSetTime(virDomainPtr dom,
03cc27
     virQEMUDriverPtr driver = dom->conn->privateData;
03cc27
     qemuDomainObjPrivatePtr priv;
03cc27
     virDomainObjPtr vm;
03cc27
-    qemuAgentPtr agent;
03cc27
     bool rtcSync = flags & VIR_DOMAIN_TIME_SYNC;
03cc27
     int ret = -1;
03cc27
     int rv;
03cc27
@@ -19479,14 +19507,6 @@ qemuDomainSetTime(virDomainPtr dom,
03cc27
 
03cc27
     priv = vm->privateData;
03cc27
 
03cc27
-    if (qemuDomainObjBeginJobWithAgent(driver, vm,
03cc27
-                                       QEMU_JOB_MODIFY,
03cc27
-                                       QEMU_AGENT_JOB_MODIFY) < 0)
03cc27
-        goto cleanup;
03cc27
-
03cc27
-    if (virDomainObjCheckActive(vm) < 0)
03cc27
-        goto endjob;
03cc27
-
03cc27
     /* On x86, the rtc-reset-reinjection QMP command must be called after
03cc27
      * setting the time to avoid trouble down the line. If the command is
03cc27
      * not available, don't set the time at all and report an error */
03cc27
@@ -19496,18 +19516,14 @@ qemuDomainSetTime(virDomainPtr dom,
03cc27
         virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
03cc27
                        _("cannot set time: qemu doesn't support "
03cc27
                          "rtc-reset-reinjection command"));
03cc27
-        goto endjob;
03cc27
+        goto cleanup;
03cc27
     }
03cc27
 
03cc27
-    if (!qemuDomainAgentAvailable(vm, true))
03cc27
-        goto endjob;
03cc27
-
03cc27
-    agent = qemuDomainObjEnterAgent(vm);
03cc27
-    rv = qemuAgentSetTime(agent, seconds, nseconds, rtcSync);
03cc27
-    qemuDomainObjExitAgent(vm, agent);
03cc27
+    if (qemuDomainSetTimeAgent(driver, vm, seconds, nseconds, rtcSync) < 0)
03cc27
+        goto cleanup;
03cc27
 
03cc27
-    if (rv < 0)
03cc27
-        goto endjob;
03cc27
+    if (qemuDomainObjBeginJob(driver, vm, QEMU_JOB_MODIFY) < 0)
03cc27
+        goto cleanup;
03cc27
 
03cc27
     if (virDomainObjCheckActive(vm) < 0)
03cc27
         goto endjob;
03cc27
@@ -19526,7 +19542,7 @@ qemuDomainSetTime(virDomainPtr dom,
03cc27
     ret = 0;
03cc27
 
03cc27
  endjob:
03cc27
-    qemuDomainObjEndJobWithAgent(driver, vm);
03cc27
+    qemuDomainObjEndJob(driver, vm);
03cc27
 
03cc27
  cleanup:
03cc27
     virDomainObjEndAPI(&vm;;
03cc27
-- 
03cc27
2.26.2
03cc27