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(a)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