[libvirt] [PATCH 5/5] qemu: support use of virtlogd with file based chardevs

Daniel P. Berrange berrange at redhat.com
Tue Feb 23 16:41:53 UTC 2016


Currently the file based character devices let QEMU write
directly to a file on disk. This allows a malicious QEMU
to inflict a denial of service by consuming all free space.

Switch QEMU to use a pipe to virtlogd, which will enforce
file rollover.

Signed-off-by: Daniel P. Berrange <berrange at redhat.com>
---
 src/qemu/qemu_command.c | 50 ++++++++++++++++++++++++++++++++++++++++---------
 1 file changed, 41 insertions(+), 9 deletions(-)

diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index 8378470..9ed1b97 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -3934,17 +3934,49 @@ qemuBuildChrChardevStr(virLogManagerPtr logManager,
         break;
 
     case VIR_DOMAIN_CHR_TYPE_FILE:
-        virBufferAsprintf(&buf, "file,id=char%s,path=%s", alias,
-                          dev->data.file.path);
-        if (dev->data.file.append != VIR_TRISTATE_SWITCH_ABSENT) {
-            if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_CHARDEV_FILE_APPEND)) {
-                virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
-                               _("append not supported in this QEMU binary"));
+        if (logManager && virQEMUCapsGet(qemuCaps, QEMU_CAPS_CHARDEV_FILE_APPEND)) {
+            char *fdset, *fdpath;
+            int flags = 0;
+            int logfd;
+
+            if (dev->data.file.append == VIR_TRISTATE_SWITCH_OFF)
+                flags |= VIR_LOG_MANAGER_PROTOCOL_DOMAIN_OPEN_LOG_FILE_TRUNCATE;
+
+            if ((logfd = virLogManagerDomainOpenLogFile(logManager,
+                                                        "qemu",
+                                                        def->uuid,
+                                                        def->name,
+                                                        dev->data.file.path,
+                                                        flags,
+                                                        NULL, NULL)) < 0)
                 goto error;
-            }
 
-            virBufferAsprintf(&buf, ",append=%s",
-                              virTristateSwitchTypeToString(dev->data.file.append));
+            virCommandPassFD(cmd, logfd, VIR_COMMAND_PASS_FD_CLOSE_PARENT);
+            if (!(fdset = qemuVirCommandGetFDSet(cmd, logfd)))
+                goto error;
+
+            virCommandAddArg(cmd, "-add-fd");
+            virCommandAddArg(cmd, fdset);
+            VIR_FREE(fdset);
+
+            if (!(fdpath = qemuVirCommandGetDevSet(cmd, logfd)))
+                goto error;
+
+            virBufferAsprintf(&buf, "file,id=char%s,path=%s,append=on", alias, fdpath);
+            VIR_FREE(fdpath);
+        } else {
+            virBufferAsprintf(&buf, "file,id=char%s,path=%s", alias,
+                              dev->data.file.path);
+            if (dev->data.file.append != VIR_TRISTATE_SWITCH_ABSENT) {
+                if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_CHARDEV_FILE_APPEND)) {
+                    virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+                                   _("append not supported in this QEMU binary"));
+                    goto error;
+                }
+
+                virBufferAsprintf(&buf, ",append=%s",
+                                  virTristateSwitchTypeToString(dev->data.file.append));
+            }
         }
         break;
 
-- 
2.5.0




More information about the libvir-list mailing list