If use of virtlogd is enabled, then use it for backing the character device log files too. This avoids the possibility of a guest denial of service by writing too much data to the log file. --- src/qemu/qemu_command.c | 128 ++++++++++++++++++++++++++++++++++++++--------- src/qemu/qemu_command.h | 9 +++- src/qemu/qemu_domain.c | 6 +++ src/qemu/qemu_domain.h | 3 ++ src/qemu/qemu_driver.c | 2 +- src/qemu/qemu_process.c | 4 +- tests/qemuxml2argvtest.c | 2 +- 7 files changed, 124 insertions(+), 30 deletions(-) diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index 490e991..e04e55e 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -60,6 +60,7 @@ #if defined(__linux__) # include <linux/capability.h> #endif +#include "logging/log_manager.h" #include <sys/stat.h> #include <fcntl.h> @@ -3900,10 +3901,62 @@ qemuBuildSCSIHostdevDevStr(virDomainDefPtr def, return NULL; } +static int +qemuBuildChrChardevFileStr(virLogManagerPtr logManager, + virCommandPtr cmd, + virDomainDefPtr def, + virBufferPtr buf, + const char *filearg, const char *fileval, + const char *appendarg, int appendval) +{ + if (logManager) { + char *fdset, *fdpath; + int flags = 0; + int logfd; + + if (appendval == VIR_TRISTATE_SWITCH_OFF) + flags |= VIR_LOG_MANAGER_PROTOCOL_DOMAIN_OPEN_LOG_FILE_TRUNCATE; + + if ((logfd = virLogManagerDomainOpenLogFile(logManager, + "qemu", + def->uuid, + def->name, + fileval, + flags, + NULL, NULL)) < 0) + return -1; + + virCommandPassFD(cmd, logfd, VIR_COMMAND_PASS_FD_CLOSE_PARENT); + if (!(fdset = qemuVirCommandGetFDSet(cmd, logfd))) + return -1; + + virCommandAddArg(cmd, "-add-fd"); + virCommandAddArg(cmd, fdset); + VIR_FREE(fdset); + + if (!(fdpath = qemuVirCommandGetDevSet(cmd, logfd))) + return -1; + + virBufferAsprintf(buf, ",%s=%s,%s=on", filearg, fdpath, appendarg); + VIR_FREE(fdpath); + } else { + virBufferAsprintf(buf, ",%s=%s", filearg, fileval); + if (appendval != VIR_TRISTATE_SWITCH_ABSENT) { + virBufferAsprintf(buf, ",%s=%s", appendarg, + virTristateSwitchTypeToString(appendval)); + } + } + + return 0; +} + /* This function outputs a -chardev command line option which describes only the * host side of the character device */ static char * -qemuBuildChrChardevStr(const virDomainChrSourceDef *dev, +qemuBuildChrChardevStr(virLogManagerPtr logManager, + virCommandPtr cmd, + virDomainDefPtr def, + const virDomainChrSourceDef *dev, const char *alias, virQEMUCapsPtr qemuCaps) { @@ -4026,11 +4079,10 @@ qemuBuildChrChardevStr(const virDomainChrSourceDef *dev, _("logfile not supported in this QEMU binary")); goto error; } - virBufferAsprintf(&buf, ",logfile=%s", dev->logfile); - if (dev->logappend != VIR_TRISTATE_SWITCH_ABSENT) { - virBufferAsprintf(&buf, ",logappend=%s", - virTristateSwitchTypeToString(dev->logappend)); - } + if (qemuBuildChrChardevFileStr(logManager, cmd, def, &buf, + "logfile", dev->logfile, + "logappend", dev->logappend) < 0) + goto error; } if (virBufferCheckError(&buf) < 0) @@ -4146,7 +4198,9 @@ qemuBuildChrArgStr(const virDomainChrSourceDef *dev, static int -qemuBuildMonitorCommandLine(virCommandPtr cmd, +qemuBuildMonitorCommandLine(virLogManagerPtr logManager, + virCommandPtr cmd, + virDomainDefPtr def, virQEMUCapsPtr qemuCaps, const virDomainChrSourceDef *monitor_chr, bool monitor_json) @@ -4159,7 +4213,8 @@ qemuBuildMonitorCommandLine(virCommandPtr cmd, /* Use -chardev if it's available */ if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_CHARDEV)) { - if (!(chrdev = qemuBuildChrChardevStr(monitor_chr, "monitor", + if (!(chrdev = qemuBuildChrChardevStr(logManager, cmd, def, + monitor_chr, "monitor", qemuCaps))) return -1; virCommandAddArg(cmd, "-chardev"); @@ -4301,7 +4356,10 @@ qemuBuildSclpDevStr(virDomainChrDefPtr dev) static int -qemuBuildRNGBackendChrdevStr(virDomainRNGDefPtr rng, +qemuBuildRNGBackendChrdevStr(virLogManagerPtr logManager, + virCommandPtr cmd, + virDomainDefPtr def, + virDomainRNGDefPtr rng, virQEMUCapsPtr qemuCaps, char **chr) { @@ -4314,7 +4372,8 @@ qemuBuildRNGBackendChrdevStr(virDomainRNGDefPtr rng, return 0; case VIR_DOMAIN_RNG_BACKEND_EGD: - if (!(*chr = qemuBuildChrChardevStr(rng->source.chardev, + if (!(*chr = qemuBuildChrChardevStr(logManager, cmd, def, + rng->source.chardev, rng->info.alias, qemuCaps))) return -1; } @@ -6620,7 +6679,10 @@ qemuBuildShmemDevStr(virDomainDefPtr def, } char * -qemuBuildShmemBackendStr(virDomainShmemDefPtr shmem, +qemuBuildShmemBackendStr(virLogManagerPtr logManager, + virCommandPtr cmd, + virDomainDefPtr def, + virDomainShmemDefPtr shmem, virQEMUCapsPtr qemuCaps) { char *devstr = NULL; @@ -6631,13 +6693,16 @@ qemuBuildShmemBackendStr(virDomainShmemDefPtr shmem, shmem->name) < 0) return NULL; - devstr = qemuBuildChrChardevStr(&shmem->server.chr, shmem->info.alias, qemuCaps); + devstr = qemuBuildChrChardevStr(logManager, cmd, def, + &shmem->server.chr, + shmem->info.alias, qemuCaps); return devstr; } static int -qemuBuildShmemCommandLine(virCommandPtr cmd, +qemuBuildShmemCommandLine(virLogManagerPtr logManager, + virCommandPtr cmd, virDomainDefPtr def, virDomainShmemDefPtr shmem, virQEMUCapsPtr qemuCaps) @@ -6650,7 +6715,8 @@ qemuBuildShmemCommandLine(virCommandPtr cmd, VIR_FREE(devstr); if (shmem->server.enabled) { - if (!(devstr = qemuBuildShmemBackendStr(shmem, qemuCaps))) + if (!(devstr = qemuBuildShmemBackendStr(logManager, cmd, def, + shmem, qemuCaps))) return -1; virCommandAddArgList(cmd, "-chardev", devstr, NULL); @@ -7020,6 +7086,7 @@ qemuBuildCommandLineCallbacks buildCommandLineCallbacks = { virCommandPtr qemuBuildCommandLine(virConnectPtr conn, virQEMUDriverPtr driver, + virLogManagerPtr logManager, virDomainDefPtr def, virDomainChrSourceDefPtr monitor_chr, bool monitor_json, @@ -7170,7 +7237,8 @@ qemuBuildCommandLine(virConnectPtr conn, if (qemuBuildSgaCommandLine(cmd, def, qemuCaps) < 0) goto error; - if (qemuBuildMonitorCommandLine(cmd, qemuCaps, monitor_chr, + if (qemuBuildMonitorCommandLine(logManager, cmd, def, + qemuCaps, monitor_chr, monitor_json) < 0) goto error; @@ -7932,7 +8000,8 @@ qemuBuildCommandLine(virConnectPtr conn, goto error; } - if (!(devstr = qemuBuildChrChardevStr(&smartcard->data.passthru, + if (!(devstr = qemuBuildChrChardevStr(logManager, cmd, def, + &smartcard->data.passthru, smartcard->info.alias, qemuCaps))) { virBufferFreeAndReset(&opt); @@ -7976,7 +8045,8 @@ qemuBuildCommandLine(virConnectPtr conn, /* Use -chardev with -device if they are available */ if (virQEMUCapsSupportsChardev(def, qemuCaps, serial)) { - if (!(devstr = qemuBuildChrChardevStr(&serial->source, + if (!(devstr = qemuBuildChrChardevStr(logManager, cmd, def, + &serial->source, serial->info.alias, qemuCaps))) goto error; @@ -8012,7 +8082,8 @@ qemuBuildCommandLine(virConnectPtr conn, /* Use -chardev with -device if they are available */ if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_CHARDEV) && virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE)) { - if (!(devstr = qemuBuildChrChardevStr(¶llel->source, + if (!(devstr = qemuBuildChrChardevStr(logManager, cmd, def, + ¶llel->source, parallel->info.alias, qemuCaps))) goto error; @@ -8045,7 +8116,8 @@ qemuBuildCommandLine(virConnectPtr conn, goto error; } - if (!(devstr = qemuBuildChrChardevStr(&channel->source, + if (!(devstr = qemuBuildChrChardevStr(logManager, cmd, def, + &channel->source, channel->info.alias, qemuCaps))) goto error; @@ -8090,7 +8162,8 @@ qemuBuildCommandLine(virConnectPtr conn, * the newer -chardev interface. */ ; } else { - if (!(devstr = qemuBuildChrChardevStr(&channel->source, + if (!(devstr = qemuBuildChrChardevStr(logManager, cmd, def, + &channel->source, channel->info.alias, qemuCaps))) goto error; @@ -8124,7 +8197,8 @@ qemuBuildCommandLine(virConnectPtr conn, goto error; } - if (!(devstr = qemuBuildChrChardevStr(&console->source, + if (!(devstr = qemuBuildChrChardevStr(logManager, cmd, def, + &console->source, console->info.alias, qemuCaps))) goto error; @@ -8143,7 +8217,8 @@ qemuBuildCommandLine(virConnectPtr conn, goto error; } - if (!(devstr = qemuBuildChrChardevStr(&console->source, + if (!(devstr = qemuBuildChrChardevStr(logManager, cmd, def, + &console->source, console->info.alias, qemuCaps))) goto error; @@ -8487,7 +8562,8 @@ qemuBuildCommandLine(virConnectPtr conn, virDomainRedirdevDefPtr redirdev = def->redirdevs[i]; char *devstr; - if (!(devstr = qemuBuildChrChardevStr(&redirdev->source.chr, + if (!(devstr = qemuBuildChrChardevStr(logManager, cmd, def, + &redirdev->source.chr, redirdev->info.alias, qemuCaps))) { goto error; @@ -8713,7 +8789,8 @@ qemuBuildCommandLine(virConnectPtr conn, } /* possibly add character device for backend */ - if (qemuBuildRNGBackendChrdevStr(rng, qemuCaps, &tmp) < 0) + if (qemuBuildRNGBackendChrdevStr(logManager, cmd, def, + rng, qemuCaps, &tmp) < 0) goto error; if (tmp) { @@ -8858,7 +8935,8 @@ qemuBuildCommandLine(virConnectPtr conn, } for (i = 0; i < def->nshmems; i++) { - if (qemuBuildShmemCommandLine(cmd, def, def->shmems[i], qemuCaps)) + if (qemuBuildShmemCommandLine(logManager, cmd, + def, def->shmems[i], qemuCaps)) goto error; } diff --git a/src/qemu/qemu_command.h b/src/qemu/qemu_command.h index fb684d0..160425e 100644 --- a/src/qemu/qemu_command.h +++ b/src/qemu/qemu_command.h @@ -32,6 +32,7 @@ # include "qemu_domain.h" # include "qemu_domain_address.h" # include "qemu_capabilities.h" +# include "logging/log_manager.h" /* Config type for XML import/export conversions */ # define QEMU_CONFIG_FORMAT_ARGV "qemu-argv" @@ -59,6 +60,7 @@ char *qemuBuildObjectCommandlineFromJSON(const char *type, virCommandPtr qemuBuildCommandLine(virConnectPtr conn, virQEMUDriverPtr driver, + virLogManagerPtr logManager, virDomainDefPtr def, virDomainChrSourceDefPtr monitor_chr, bool monitor_json, @@ -72,7 +74,7 @@ virCommandPtr qemuBuildCommandLine(virConnectPtr conn, virBitmapPtr nodeset, size_t *nnicindexes, int **nicindexes) - ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(10); + ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(11); /* Generate '-device' string for chardev device */ int @@ -180,7 +182,10 @@ int qemuBuildRNGBackendProps(virDomainRNGDefPtr rng, char *qemuBuildShmemDevStr(virDomainDefPtr def, virDomainShmemDefPtr shmem, virQEMUCapsPtr qemuCaps); -char *qemuBuildShmemBackendStr(virDomainShmemDefPtr shmem, +char *qemuBuildShmemBackendStr(virLogManagerPtr logManager, + virCommandPtr cmd, + virDomainDefPtr def, + virDomainShmemDefPtr shmem, virQEMUCapsPtr qemuCaps); diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c index 3fc1513..3d045cc 100644 --- a/src/qemu/qemu_domain.c +++ b/src/qemu/qemu_domain.c @@ -2609,6 +2609,12 @@ void qemuDomainLogContextRef(qemuDomainLogContextPtr ctxt) } +virLogManagerPtr qemuDomainLogContextGetManager(qemuDomainLogContextPtr ctxt) +{ + return ctxt->manager; +} + + void qemuDomainLogContextFree(qemuDomainLogContextPtr ctxt) { bool lastRef; diff --git a/src/qemu/qemu_domain.h b/src/qemu/qemu_domain.h index 8359b1a..f6ce19c 100644 --- a/src/qemu/qemu_domain.h +++ b/src/qemu/qemu_domain.h @@ -35,6 +35,7 @@ # include "qemu_capabilities.h" # include "virchrdev.h" # include "virobject.h" +# include "logging/log_manager.h" # define QEMU_DOMAIN_FORMAT_LIVE_FLAGS \ (VIR_DOMAIN_XML_SECURE | \ @@ -377,6 +378,8 @@ void qemuDomainLogContextMarkPosition(qemuDomainLogContextPtr ctxt); void qemuDomainLogContextRef(qemuDomainLogContextPtr ctxt); void qemuDomainLogContextFree(qemuDomainLogContextPtr ctxt); +virLogManagerPtr qemuDomainLogContextGetManager(qemuDomainLogContextPtr ctxt); + const char *qemuFindQemuImgBinary(virQEMUDriverPtr driver); int qemuDomainSnapshotWriteMetadata(virDomainObjPtr vm, diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 45ff3c0..1afafd6 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -7159,7 +7159,7 @@ static char *qemuConnectDomainXMLToNative(virConnectPtr conn, } } - if (!(cmd = qemuBuildCommandLine(conn, driver, def, + if (!(cmd = qemuBuildCommandLine(conn, driver, NULL, def, &monConfig, monitor_json, qemuCaps, NULL, NULL, VIR_NETDEV_VPORT_PROFILE_OP_NO_OP, diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c index e760182..03b7418 100644 --- a/src/qemu/qemu_process.c +++ b/src/qemu/qemu_process.c @@ -4993,7 +4993,9 @@ qemuProcessLaunch(virConnectPtr conn, } VIR_DEBUG("Building emulator command line"); - if (!(cmd = qemuBuildCommandLine(conn, driver, vm->def, priv->monConfig, + if (!(cmd = qemuBuildCommandLine(conn, driver, + qemuDomainLogContextGetManager(logCtxt), + vm->def, priv->monConfig, priv->monJSON, priv->qemuCaps, incoming ? incoming->launchURI : NULL, snapshot, vmop, diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c index ff93329..4c760ee 100644 --- a/tests/qemuxml2argvtest.c +++ b/tests/qemuxml2argvtest.c @@ -347,7 +347,7 @@ static int testCompareXMLToArgvFiles(const char *xml, testFailed = true; if (!testFailed && - !(cmd = qemuBuildCommandLine(conn, &driver, vmdef, &monitor_chr, + !(cmd = qemuBuildCommandLine(conn, &driver, NULL, vmdef, &monitor_chr, (flags & FLAG_JSON), extraFlags, migrateURI, NULL, VIR_NETDEV_VPORT_PROFILE_OP_NO_OP, -- 2.5.0 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list