1
0
mirror of https://gitlab.com/libvirt/libvirt.git synced 2025-10-16 23:33:52 +03:00

Compare commits

...

13 Commits

Author SHA1 Message Date
Ján Tomko
415cc5c064 api: disallow virConnect*HypervisorCPU on read-only connections
These APIs can be used to execute arbitrary emulators.
Forbid them on read-only connections.

Fixes: CVE-2019-10168
Signed-off-by: Ján Tomko <jtomko@redhat.com>
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
(cherry picked from commit bf6c2830b6)
Signed-off-by: Ján Tomko <jtomko@redhat.com>
2019-06-24 09:56:23 +02:00
Ján Tomko
fd16bd525a api: disallow virConnectGetDomainCapabilities on read-only connections
This API can be used to execute arbitrary emulators.
Forbid it on read-only connections.

Fixes: CVE-2019-10167
Signed-off-by: Ján Tomko <jtomko@redhat.com>
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
(cherry picked from commit 8afa68bac0)
Signed-off-by: Ján Tomko <jtomko@redhat.com>
2019-06-24 09:56:23 +02:00
Ján Tomko
d025c10d54 api: disallow virDomainManagedSaveDefineXML on read-only connections
The virDomainManagedSaveDefineXML can be used to alter the domain's
config used for managedsave or even execute arbitrary emulator binaries.
Forbid it on read-only connections.

Fixes: CVE-2019-10166
Reported-by: Matthias Gerstner <mgerstner@suse.de>
Signed-off-by: Ján Tomko <jtomko@redhat.com>
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
(cherry picked from commit db0b78457f)
Signed-off-by: Ján Tomko <jtomko@redhat.com>
2019-06-24 09:56:23 +02:00
Ján Tomko
6a028b6e82 api: disallow virDomainSaveImageGetXMLDesc on read-only connections
The virDomainSaveImageGetXMLDesc API is taking a path parameter,
which can point to any path on the system. This file will then be
read and parsed by libvirtd running with root privileges.

Forbid it on read-only connections.

Fixes: CVE-2019-10161
Reported-by: Matthias Gerstner <mgerstner@suse.de>
Signed-off-by: Ján Tomko <jtomko@redhat.com>
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
(cherry picked from commit aed6a032ce)
Signed-off-by: Ján Tomko <jtomko@redhat.com>

Conflicts:
  src/libvirt-domain.c
  src/remote/remote_protocol.x

Upstream commit 12a51f372 which introduced the VIR_DOMAIN_SAVE_IMAGE_XML_SECURE
alias for VIR_DOMAIN_XML_SECURE is not backported.
Just skip the commit since we now disallow the whole API on read-only
connections, regardless of the flag.

Signed-off-by: Ján Tomko <jtomko@redhat.com>
2019-06-24 09:56:23 +02:00
Daniel P. Berrangé
ec58805400 logging: restrict sockets to mode 0600
The virtlogd daemon's only intended client is the libvirtd daemon. As
such it should never allow clients from other user accounts to connect.
The code already enforces this and drops clients from other UIDs, but
we can get earlier (and thus stronger) protection against DoS by setting
the socket permissions to 0600

Fixes CVE-2019-10132

Reviewed-by: Ján Tomko <jtomko@redhat.com>
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
(cherry picked from commit e37bd65f99)
2019-05-21 13:30:02 +01:00
Daniel P. Berrangé
618358632b locking: restrict sockets to mode 0600
The virtlockd daemon's only intended client is the libvirtd daemon. As
such it should never allow clients from other user accounts to connect.
The code already enforces this and drops clients from other UIDs, but
we can get earlier (and thus stronger) protection against DoS by setting
the socket permissions to 0600

Fixes CVE-2019-10132

Reviewed-by: Ján Tomko <jtomko@redhat.com>
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
(cherry picked from commit f111e09468)
2019-05-21 13:30:01 +01:00
Daniel P. Berrangé
d1017aeee9 admin: reject clients unless their UID matches the current UID
The admin protocol RPC messages are only intended for use by the user
running the daemon. As such they should not be allowed for any client
UID that does not match the server UID.

Fixes CVE-2019-10132

Reviewed-by: Ján Tomko <jtomko@redhat.com>
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
(cherry picked from commit 96f41cd765)
2019-05-21 13:30:01 +01:00
Luyao Huang
35176b5c78 virDomainConfNWFilterInstantiate: initialize @xml to avoid random crash
If the code jump to the cleanup before assigning value to @xml
libvirtd may crash when it tries to free an uninitialized pointer.

backtrace:

0  0x00007ffff428d59c in free () from /lib64/libc.so.6
1  0x00007ffff721314a in virFree (ptrptr=ptrptr@entry=0x7fffc67f1b00) at util/viralloc.c:582
2  0x00007ffff7345ac4 in virDomainConfNWFilterInstantiate (vmname=<optimized out>,
   vmuuid=vmuuid@entry=0x7fffc0181ca8 "߉\237\\۔H\262\206z\340\302f\265\233z", net=<optimized out>,
   ignoreExists=ignoreExists@entry=true) at conf/domain_nwfilter.c:122
3  0x00007fffca5a77f6 in qemuProcessFiltersInstantiate (ignoreExists=true, def=0x7fffc0181ca0) at qemu/qemu_process.c:3028
4  qemuProcessReconnect (opaque=<optimized out>) at qemu/qemu_process.c:7653
5  0x00007ffff72c4895 in virThreadHelper (data=<optimized out>) at util/virthread.c:206
6  0x00007ffff45dcdd5 in start_thread () from /lib64/libpthread.so.0
7  0x00007ffff4305ead in clone () from /lib64/libc.so.6

Signed-off-by: Luyao Huang <lhuang@redhat.com>
(cherry picked from commit d7557f5f6f)
2018-07-06 14:31:47 +01:00
Daniel P. Berrangé
6aedf9bfad qemu: fix UNIX socket chardevs operating in client mode
When support was adding for passing a pre-opened listener socket to UNIX
chardevs, it accidentally passed the listener socket for client mode
chardevs too with predictable amounts of fail resulting. This affects
libvirt when using QEMU >= 2.12

Expand the unit test coverage to validate that we are only doing FD
passing when operating in server mode.

  https://bugzilla.redhat.com/show_bug.cgi?id=1598440

Tested-by: Richard W.M. Jones <rjones@redhat.com>
Reported-by: Richard W.M. Jones <rjones@redhat.com>
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
(cherry picked from commit 1bc1a7e320)
2018-07-06 14:31:35 +01:00
Daniel P. Berrangé
78920738ca qemu: don't use chardev FD passing for vhostuser backend
QEMU chardevs have a bug which makes the vhostuser backend complain
about lack of support for FD passing when validating the chardev.
While this is ultimately QEMU's responsibility to fix, libvirt needs to
avoid tickling the bug.

Simply disabling chardev FD passing just for vhostuser's chardev is
the most prudent approach, avoiding need for a QEMU version number
check.

Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
(cherry picked from commit ed5aa85f37)
2018-07-06 14:31:29 +01:00
Daniel P. Berrangé
88924317f3 qemu: consolidate parameters of qemuBuildChrChardevStr into flags
There are two boolean parameters passed to qemuBuildChrChardevStr,
and soon there will be a third. It will be clearer to understand
from callers' POV if we use named flags instead.

Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
(cherry picked from commit 0140d4c59b)
2018-07-06 14:31:23 +01:00
Daniel P. Berrangé
941ca31e90 qemu: remove chardevStdioLogd param from vhostuser code path
The vhostuser network backend is only supported with the UNIX domain
socket chardev backend, so passing around chardevStdioLogd is not
required.

Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
(cherry picked from commit 4c76266bac)
2018-07-06 14:31:15 +01:00
Daniel P. Berrangé
3818514602 qemu: don't use chardev FD passing with standalone args
When using domxml-to-native, we must generate CLI args that can be used
in a standalone scenario. This means no FD passing can be used. To
achieve this we must clear the QEMU_CAPS_CHARDEV_FD_PASS capability bit.

Reviewed-by: John Ferlan <jferlan@redhat.com>
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
(cherry picked from commit 7ac08cc929)
2018-07-06 14:30:43 +01:00
18 changed files with 167 additions and 62 deletions

View File

@@ -66,6 +66,28 @@ remoteAdmClientNew(virNetServerClientPtr client ATTRIBUTE_UNUSED,
void *opaque) void *opaque)
{ {
struct daemonAdmClientPrivate *priv; struct daemonAdmClientPrivate *priv;
uid_t clientuid;
gid_t clientgid;
pid_t clientpid;
unsigned long long timestamp;
if (virNetServerClientGetUNIXIdentity(client,
&clientuid,
&clientgid,
&clientpid,
&timestamp) < 0)
return NULL;
VIR_DEBUG("New client pid %lld uid %lld",
(long long)clientpid,
(long long)clientuid);
if (geteuid() != clientuid) {
virReportRestrictedError(_("Disallowing client %lld with uid %lld"),
(long long)clientpid,
(long long)clientuid);
return NULL;
}
if (VIR_ALLOC(priv) < 0) if (VIR_ALLOC(priv) < 0)
return NULL; return NULL;

View File

@@ -90,7 +90,7 @@ virDomainConfNWFilterInstantiate(const char *vmname,
virConnectPtr conn = virGetConnectNWFilter(); virConnectPtr conn = virGetConnectNWFilter();
virNWFilterBindingDefPtr def = NULL; virNWFilterBindingDefPtr def = NULL;
virNWFilterBindingPtr binding = NULL; virNWFilterBindingPtr binding = NULL;
char *xml; char *xml = NULL;
int ret = -1; int ret = -1;
VIR_DEBUG("vmname=%s portdev=%s filter=%s ignoreExists=%d", VIR_DEBUG("vmname=%s portdev=%s filter=%s ignoreExists=%d",

View File

@@ -1073,9 +1073,7 @@ virDomainRestoreFlags(virConnectPtr conn, const char *from, const char *dxml,
* previously by virDomainSave() or virDomainSaveFlags(). * previously by virDomainSave() or virDomainSaveFlags().
* *
* No security-sensitive data will be included unless @flags contains * No security-sensitive data will be included unless @flags contains
* VIR_DOMAIN_XML_SECURE; this flag is rejected on read-only * VIR_DOMAIN_XML_SECURE.
* connections. For this API, @flags should not contain either
* VIR_DOMAIN_XML_INACTIVE or VIR_DOMAIN_XML_UPDATE_CPU.
* *
* Returns a 0 terminated UTF-8 encoded XML instance, or NULL in case of * Returns a 0 terminated UTF-8 encoded XML instance, or NULL in case of
* error. The caller must free() the returned value. * error. The caller must free() the returned value.
@@ -1091,12 +1089,7 @@ virDomainSaveImageGetXMLDesc(virConnectPtr conn, const char *file,
virCheckConnectReturn(conn, NULL); virCheckConnectReturn(conn, NULL);
virCheckNonNullArgGoto(file, error); virCheckNonNullArgGoto(file, error);
virCheckReadOnlyGoto(conn->flags, error);
if ((conn->flags & VIR_CONNECT_RO) && (flags & VIR_DOMAIN_XML_SECURE)) {
virReportError(VIR_ERR_OPERATION_DENIED, "%s",
_("virDomainSaveImageGetXMLDesc with secure flag"));
goto error;
}
if (conn->driver->domainSaveImageGetXMLDesc) { if (conn->driver->domainSaveImageGetXMLDesc) {
char *ret; char *ret;
@@ -9484,6 +9477,7 @@ virDomainManagedSaveDefineXML(virDomainPtr domain, const char *dxml,
virCheckDomainReturn(domain, -1); virCheckDomainReturn(domain, -1);
conn = domain->conn; conn = domain->conn;
virCheckReadOnlyGoto(conn->flags, error);
if (conn->driver->domainManagedSaveDefineXML) { if (conn->driver->domainManagedSaveDefineXML) {
int ret; int ret;
@@ -11275,6 +11269,7 @@ virConnectGetDomainCapabilities(virConnectPtr conn,
virResetLastError(); virResetLastError();
virCheckConnectReturn(conn, NULL); virCheckConnectReturn(conn, NULL);
virCheckReadOnlyGoto(conn->flags, error);
if (conn->driver->connectGetDomainCapabilities) { if (conn->driver->connectGetDomainCapabilities) {
char *ret; char *ret;

View File

@@ -1041,6 +1041,7 @@ virConnectCompareHypervisorCPU(virConnectPtr conn,
virCheckConnectReturn(conn, VIR_CPU_COMPARE_ERROR); virCheckConnectReturn(conn, VIR_CPU_COMPARE_ERROR);
virCheckNonNullArgGoto(xmlCPU, error); virCheckNonNullArgGoto(xmlCPU, error);
virCheckReadOnlyGoto(conn->flags, error);
if (conn->driver->connectCompareHypervisorCPU) { if (conn->driver->connectCompareHypervisorCPU) {
int ret; int ret;
@@ -1234,6 +1235,7 @@ virConnectBaselineHypervisorCPU(virConnectPtr conn,
virCheckConnectReturn(conn, NULL); virCheckConnectReturn(conn, NULL);
virCheckNonNullArgGoto(xmlCPUs, error); virCheckNonNullArgGoto(xmlCPUs, error);
virCheckReadOnlyGoto(conn->flags, error);
if (conn->driver->connectBaselineHypervisorCPU) { if (conn->driver->connectBaselineHypervisorCPU) {
char *cpu; char *cpu;

View File

@@ -5,6 +5,7 @@ Before=libvirtd.service
[Socket] [Socket]
ListenStream=@localstatedir@/run/libvirt/virtlockd-admin-sock ListenStream=@localstatedir@/run/libvirt/virtlockd-admin-sock
Service=virtlockd.service Service=virtlockd.service
SocketMode=0600
[Install] [Install]
WantedBy=sockets.target WantedBy=sockets.target

View File

@@ -4,6 +4,7 @@ Before=libvirtd.service
[Socket] [Socket]
ListenStream=@localstatedir@/run/libvirt/virtlockd-sock ListenStream=@localstatedir@/run/libvirt/virtlockd-sock
SocketMode=0600
[Install] [Install]
WantedBy=sockets.target WantedBy=sockets.target

View File

@@ -5,6 +5,7 @@ Before=libvirtd.service
[Socket] [Socket]
ListenStream=@localstatedir@/run/libvirt/virtlogd-admin-sock ListenStream=@localstatedir@/run/libvirt/virtlogd-admin-sock
Service=virtlogd.service Service=virtlogd.service
SocketMode=0600
[Install] [Install]
WantedBy=sockets.target WantedBy=sockets.target

View File

@@ -4,6 +4,7 @@ Before=libvirtd.service
[Socket] [Socket]
ListenStream=@localstatedir@/run/libvirt/virtlogd-sock ListenStream=@localstatedir@/run/libvirt/virtlogd-sock
SocketMode=0600
[Install] [Install]
WantedBy=sockets.target WantedBy=sockets.target

View File

@@ -4934,6 +4934,13 @@ qemuOpenChrChardevUNIXSocket(const virDomainChrSourceDef *dev)
return -1; return -1;
} }
enum {
QEMU_BUILD_CHARDEV_TCP_NOWAIT = (1 << 0),
QEMU_BUILD_CHARDEV_FILE_LOGD = (1 << 1),
QEMU_BUILD_CHARDEV_UNIX_FD_PASS = (1 << 2),
};
/* This function outputs a -chardev command line option which describes only the /* This function outputs a -chardev command line option which describes only the
* host side of the character device */ * host side of the character device */
static char * static char *
@@ -4945,8 +4952,7 @@ qemuBuildChrChardevStr(virLogManagerPtr logManager,
const virDomainChrSourceDef *dev, const virDomainChrSourceDef *dev,
const char *alias, const char *alias,
virQEMUCapsPtr qemuCaps, virQEMUCapsPtr qemuCaps,
bool nowait, unsigned int flags)
bool chardevStdioLogd)
{ {
virBuffer buf = VIR_BUFFER_INITIALIZER; virBuffer buf = VIR_BUFFER_INITIALIZER;
bool telnet; bool telnet;
@@ -4985,7 +4991,8 @@ qemuBuildChrChardevStr(virLogManagerPtr logManager,
_("append not supported in this QEMU binary")); _("append not supported in this QEMU binary"));
goto cleanup; goto cleanup;
} }
if (qemuBuildChrChardevFileStr(chardevStdioLogd ? logManager : NULL, if (qemuBuildChrChardevFileStr(flags & QEMU_BUILD_CHARDEV_FILE_LOGD ?
logManager : NULL,
cmd, def, &buf, cmd, def, &buf,
"path", dev->data.file.path, "path", dev->data.file.path,
"append", dev->data.file.append) < 0) "append", dev->data.file.append) < 0)
@@ -5031,8 +5038,11 @@ qemuBuildChrChardevStr(virLogManagerPtr logManager,
dev->data.tcp.service, dev->data.tcp.service,
telnet ? ",telnet" : ""); telnet ? ",telnet" : "");
if (dev->data.tcp.listen) if (dev->data.tcp.listen) {
virBufferAdd(&buf, nowait ? ",server,nowait" : ",server", -1); virBufferAddLit(&buf, ",server");
if (flags & QEMU_BUILD_CHARDEV_TCP_NOWAIT)
virBufferAddLit(&buf, ",nowait");
}
qemuBuildChrChardevReconnectStr(&buf, &dev->data.tcp.reconnect); qemuBuildChrChardevReconnectStr(&buf, &dev->data.tcp.reconnect);
@@ -5072,7 +5082,9 @@ qemuBuildChrChardevStr(virLogManagerPtr logManager,
break; break;
case VIR_DOMAIN_CHR_TYPE_UNIX: case VIR_DOMAIN_CHR_TYPE_UNIX:
if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_CHARDEV_FD_PASS)) { if (dev->data.nix.listen &&
(flags & QEMU_BUILD_CHARDEV_UNIX_FD_PASS) &&
virQEMUCapsGet(qemuCaps, QEMU_CAPS_CHARDEV_FD_PASS)) {
if (qemuSecuritySetSocketLabel(secManager, (virDomainDefPtr)def) < 0) if (qemuSecuritySetSocketLabel(secManager, (virDomainDefPtr)def) < 0)
goto cleanup; goto cleanup;
int fd = qemuOpenChrChardevUNIXSocket(dev); int fd = qemuOpenChrChardevUNIXSocket(dev);
@@ -5090,8 +5102,11 @@ qemuBuildChrChardevStr(virLogManagerPtr logManager,
virBufferAsprintf(&buf, "socket,id=%s,path=", charAlias); virBufferAsprintf(&buf, "socket,id=%s,path=", charAlias);
virQEMUBuildBufferEscapeComma(&buf, dev->data.nix.path); virQEMUBuildBufferEscapeComma(&buf, dev->data.nix.path);
} }
if (dev->data.nix.listen) if (dev->data.nix.listen) {
virBufferAdd(&buf, nowait ? ",server,nowait" : ",server", -1); virBufferAddLit(&buf, ",server");
if (flags & QEMU_BUILD_CHARDEV_TCP_NOWAIT)
virBufferAddLit(&buf, ",nowait");
}
qemuBuildChrChardevReconnectStr(&buf, &dev->data.nix.reconnect); qemuBuildChrChardevReconnectStr(&buf, &dev->data.nix.reconnect);
break; break;
@@ -5425,6 +5440,10 @@ qemuBuildMonitorCommandLine(virLogManagerPtr logManager,
qemuDomainObjPrivatePtr priv) qemuDomainObjPrivatePtr priv)
{ {
char *chrdev; char *chrdev;
unsigned int cdevflags = QEMU_BUILD_CHARDEV_TCP_NOWAIT |
QEMU_BUILD_CHARDEV_UNIX_FD_PASS;
if (priv->chardevStdioLogd)
cdevflags |= QEMU_BUILD_CHARDEV_FILE_LOGD;
if (!priv->monConfig) if (!priv->monConfig)
return 0; return 0;
@@ -5432,8 +5451,7 @@ qemuBuildMonitorCommandLine(virLogManagerPtr logManager,
if (!(chrdev = qemuBuildChrChardevStr(logManager, secManager, if (!(chrdev = qemuBuildChrChardevStr(logManager, secManager,
cmd, cfg, def, cmd, cfg, def,
priv->monConfig, "monitor", priv->monConfig, "monitor",
priv->qemuCaps, true, priv->qemuCaps, cdevflags)))
priv->chardevStdioLogd)))
return -1; return -1;
virCommandAddArg(cmd, "-chardev"); virCommandAddArg(cmd, "-chardev");
virCommandAddArg(cmd, chrdev); virCommandAddArg(cmd, chrdev);
@@ -5558,6 +5576,10 @@ qemuBuildRNGBackendChrdevStr(virLogManagerPtr logManager,
char **chr, char **chr,
bool chardevStdioLogd) bool chardevStdioLogd)
{ {
unsigned int cdevflags = QEMU_BUILD_CHARDEV_TCP_NOWAIT |
QEMU_BUILD_CHARDEV_UNIX_FD_PASS;
if (chardevStdioLogd)
cdevflags |= QEMU_BUILD_CHARDEV_FILE_LOGD;
*chr = NULL; *chr = NULL;
switch ((virDomainRNGBackend) rng->backend) { switch ((virDomainRNGBackend) rng->backend) {
@@ -5570,8 +5592,8 @@ qemuBuildRNGBackendChrdevStr(virLogManagerPtr logManager,
if (!(*chr = qemuBuildChrChardevStr(logManager, secManager, if (!(*chr = qemuBuildChrChardevStr(logManager, secManager,
cmd, cfg, def, cmd, cfg, def,
rng->source.chardev, rng->source.chardev,
rng->info.alias, qemuCaps, true, rng->info.alias, qemuCaps,
chardevStdioLogd))) cdevflags)))
return -1; return -1;
} }
@@ -8174,8 +8196,7 @@ qemuBuildVhostuserCommandLine(virQEMUDriverPtr driver,
virDomainDefPtr def, virDomainDefPtr def,
virDomainNetDefPtr net, virDomainNetDefPtr net,
virQEMUCapsPtr qemuCaps, virQEMUCapsPtr qemuCaps,
unsigned int bootindex, unsigned int bootindex)
bool chardevStdioLogd)
{ {
virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver); virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
char *chardev = NULL; char *chardev = NULL;
@@ -8195,8 +8216,7 @@ qemuBuildVhostuserCommandLine(virQEMUDriverPtr driver,
if (!(chardev = qemuBuildChrChardevStr(logManager, secManager, if (!(chardev = qemuBuildChrChardevStr(logManager, secManager,
cmd, cfg, def, cmd, cfg, def,
net->data.vhostuser, net->data.vhostuser,
net->info.alias, qemuCaps, false, net->info.alias, qemuCaps, 0)))
chardevStdioLogd)))
goto cleanup; goto cleanup;
break; break;
@@ -8270,8 +8290,7 @@ qemuBuildInterfaceCommandLine(virQEMUDriverPtr driver,
virNetDevVPortProfileOp vmop, virNetDevVPortProfileOp vmop,
bool standalone, bool standalone,
size_t *nnicindexes, size_t *nnicindexes,
int **nicindexes, int **nicindexes)
bool chardevStdioLogd)
{ {
int ret = -1; int ret = -1;
char *nic = NULL, *host = NULL; char *nic = NULL, *host = NULL;
@@ -8394,8 +8413,7 @@ qemuBuildInterfaceCommandLine(virQEMUDriverPtr driver,
case VIR_DOMAIN_NET_TYPE_VHOSTUSER: case VIR_DOMAIN_NET_TYPE_VHOSTUSER:
ret = qemuBuildVhostuserCommandLine(driver, logManager, secManager, cmd, def, ret = qemuBuildVhostuserCommandLine(driver, logManager, secManager, cmd, def,
net, qemuCaps, bootindex, net, qemuCaps, bootindex);
chardevStdioLogd);
goto cleanup; goto cleanup;
break; break;
@@ -8579,8 +8597,7 @@ qemuBuildNetCommandLine(virQEMUDriverPtr driver,
bool standalone, bool standalone,
size_t *nnicindexes, size_t *nnicindexes,
int **nicindexes, int **nicindexes,
unsigned int *bootHostdevNet, unsigned int *bootHostdevNet)
bool chardevStdioLogd)
{ {
size_t i; size_t i;
int last_good_net = -1; int last_good_net = -1;
@@ -8607,8 +8624,7 @@ qemuBuildNetCommandLine(virQEMUDriverPtr driver,
if (qemuBuildInterfaceCommandLine(driver, logManager, secManager, cmd, def, net, if (qemuBuildInterfaceCommandLine(driver, logManager, secManager, cmd, def, net,
qemuCaps, bootNet, vmop, qemuCaps, bootNet, vmop,
standalone, nnicindexes, standalone, nnicindexes,
nicindexes, nicindexes) < 0)
chardevStdioLogd) < 0)
goto error; goto error;
last_good_net = i; last_good_net = i;
@@ -8680,6 +8696,10 @@ qemuBuildSmartcardCommandLine(virLogManagerPtr logManager,
virBuffer opt = VIR_BUFFER_INITIALIZER; virBuffer opt = VIR_BUFFER_INITIALIZER;
const char *database; const char *database;
const char *contAlias = NULL; const char *contAlias = NULL;
unsigned int cdevflags = QEMU_BUILD_CHARDEV_TCP_NOWAIT |
QEMU_BUILD_CHARDEV_UNIX_FD_PASS;
if (chardevStdioLogd)
cdevflags |= QEMU_BUILD_CHARDEV_FILE_LOGD;
if (!def->nsmartcards) if (!def->nsmartcards)
return 0; return 0;
@@ -8745,8 +8765,7 @@ qemuBuildSmartcardCommandLine(virLogManagerPtr logManager,
cmd, cfg, def, cmd, cfg, def,
smartcard->data.passthru, smartcard->data.passthru,
smartcard->info.alias, smartcard->info.alias,
qemuCaps, true, qemuCaps, cdevflags))) {
chardevStdioLogd))) {
virBufferFreeAndReset(&opt); virBufferFreeAndReset(&opt);
return -1; return -1;
} }
@@ -8914,6 +8933,10 @@ qemuBuildShmemCommandLine(virLogManagerPtr logManager,
virBuffer buf = VIR_BUFFER_INITIALIZER; virBuffer buf = VIR_BUFFER_INITIALIZER;
char *devstr = NULL; char *devstr = NULL;
int rc; int rc;
unsigned int cdevflags = QEMU_BUILD_CHARDEV_TCP_NOWAIT |
QEMU_BUILD_CHARDEV_UNIX_FD_PASS;
if (chardevStdioLogd)
cdevflags |= QEMU_BUILD_CHARDEV_FILE_LOGD;
if (shmem->size) { if (shmem->size) {
/* /*
@@ -8977,8 +9000,8 @@ qemuBuildShmemCommandLine(virLogManagerPtr logManager,
devstr = qemuBuildChrChardevStr(logManager, secManager, devstr = qemuBuildChrChardevStr(logManager, secManager,
cmd, cfg, def, cmd, cfg, def,
&shmem->server.chr, &shmem->server.chr,
shmem->info.alias, qemuCaps, true, shmem->info.alias, qemuCaps,
chardevStdioLogd); cdevflags);
if (!devstr) if (!devstr)
return -1; return -1;
@@ -9071,6 +9094,10 @@ qemuBuildSerialCommandLine(virLogManagerPtr logManager,
{ {
size_t i; size_t i;
bool havespice = false; bool havespice = false;
unsigned int cdevflags = QEMU_BUILD_CHARDEV_TCP_NOWAIT |
QEMU_BUILD_CHARDEV_UNIX_FD_PASS;
if (chardevStdioLogd)
cdevflags |= QEMU_BUILD_CHARDEV_FILE_LOGD;
if (def->nserials) { if (def->nserials) {
for (i = 0; i < def->ngraphics && !havespice; i++) { for (i = 0; i < def->ngraphics && !havespice; i++) {
@@ -9090,8 +9117,7 @@ qemuBuildSerialCommandLine(virLogManagerPtr logManager,
cmd, cfg, def, cmd, cfg, def,
serial->source, serial->source,
serial->info.alias, serial->info.alias,
qemuCaps, true, qemuCaps, cdevflags)))
chardevStdioLogd)))
return -1; return -1;
virCommandAddArg(cmd, "-chardev"); virCommandAddArg(cmd, "-chardev");
virCommandAddArg(cmd, devstr); virCommandAddArg(cmd, devstr);
@@ -9132,6 +9158,10 @@ qemuBuildParallelsCommandLine(virLogManagerPtr logManager,
bool chardevStdioLogd) bool chardevStdioLogd)
{ {
size_t i; size_t i;
unsigned int cdevflags = QEMU_BUILD_CHARDEV_TCP_NOWAIT |
QEMU_BUILD_CHARDEV_UNIX_FD_PASS;
if (chardevStdioLogd)
cdevflags |= QEMU_BUILD_CHARDEV_FILE_LOGD;
for (i = 0; i < def->nparallels; i++) { for (i = 0; i < def->nparallels; i++) {
virDomainChrDefPtr parallel = def->parallels[i]; virDomainChrDefPtr parallel = def->parallels[i];
@@ -9141,8 +9171,7 @@ qemuBuildParallelsCommandLine(virLogManagerPtr logManager,
cmd, cfg, def, cmd, cfg, def,
parallel->source, parallel->source,
parallel->info.alias, parallel->info.alias,
qemuCaps, true, qemuCaps, cdevflags)))
chardevStdioLogd)))
return -1; return -1;
virCommandAddArg(cmd, "-chardev"); virCommandAddArg(cmd, "-chardev");
virCommandAddArg(cmd, devstr); virCommandAddArg(cmd, devstr);
@@ -9167,6 +9196,10 @@ qemuBuildChannelsCommandLine(virLogManagerPtr logManager,
bool chardevStdioLogd) bool chardevStdioLogd)
{ {
size_t i; size_t i;
unsigned int cdevflags = QEMU_BUILD_CHARDEV_TCP_NOWAIT |
QEMU_BUILD_CHARDEV_UNIX_FD_PASS;
if (chardevStdioLogd)
cdevflags |= QEMU_BUILD_CHARDEV_FILE_LOGD;
for (i = 0; i < def->nchannels; i++) { for (i = 0; i < def->nchannels; i++) {
virDomainChrDefPtr channel = def->channels[i]; virDomainChrDefPtr channel = def->channels[i];
@@ -9178,8 +9211,7 @@ qemuBuildChannelsCommandLine(virLogManagerPtr logManager,
cmd, cfg, def, cmd, cfg, def,
channel->source, channel->source,
channel->info.alias, channel->info.alias,
qemuCaps, true, qemuCaps, cdevflags)))
chardevStdioLogd)))
return -1; return -1;
virCommandAddArg(cmd, "-chardev"); virCommandAddArg(cmd, "-chardev");
virCommandAddArg(cmd, devstr); virCommandAddArg(cmd, devstr);
@@ -9196,8 +9228,7 @@ qemuBuildChannelsCommandLine(virLogManagerPtr logManager,
cmd, cfg, def, cmd, cfg, def,
channel->source, channel->source,
channel->info.alias, channel->info.alias,
qemuCaps, true, qemuCaps, cdevflags)))
chardevStdioLogd)))
return -1; return -1;
virCommandAddArg(cmd, "-chardev"); virCommandAddArg(cmd, "-chardev");
virCommandAddArg(cmd, devstr); virCommandAddArg(cmd, devstr);
@@ -9223,6 +9254,10 @@ qemuBuildConsoleCommandLine(virLogManagerPtr logManager,
bool chardevStdioLogd) bool chardevStdioLogd)
{ {
size_t i; size_t i;
unsigned int cdevflags = QEMU_BUILD_CHARDEV_TCP_NOWAIT |
QEMU_BUILD_CHARDEV_UNIX_FD_PASS;
if (chardevStdioLogd)
cdevflags |= QEMU_BUILD_CHARDEV_FILE_LOGD;
/* Explicit console devices */ /* Explicit console devices */
for (i = 0; i < def->nconsoles; i++) { for (i = 0; i < def->nconsoles; i++) {
@@ -9241,8 +9276,7 @@ qemuBuildConsoleCommandLine(virLogManagerPtr logManager,
cmd, cfg, def, cmd, cfg, def,
console->source, console->source,
console->info.alias, console->info.alias,
qemuCaps, true, qemuCaps, cdevflags)))
chardevStdioLogd)))
return -1; return -1;
virCommandAddArg(cmd, "-chardev"); virCommandAddArg(cmd, "-chardev");
virCommandAddArg(cmd, devstr); virCommandAddArg(cmd, devstr);
@@ -9263,8 +9297,7 @@ qemuBuildConsoleCommandLine(virLogManagerPtr logManager,
cmd, cfg, def, cmd, cfg, def,
console->source, console->source,
console->info.alias, console->info.alias,
qemuCaps, true, qemuCaps, cdevflags)))
chardevStdioLogd)))
return -1; return -1;
virCommandAddArg(cmd, "-chardev"); virCommandAddArg(cmd, "-chardev");
virCommandAddArg(cmd, devstr); virCommandAddArg(cmd, devstr);
@@ -9279,8 +9312,7 @@ qemuBuildConsoleCommandLine(virLogManagerPtr logManager,
cmd, cfg, def, cmd, cfg, def,
console->source, console->source,
console->info.alias, console->info.alias,
qemuCaps, true, qemuCaps, cdevflags)))
chardevStdioLogd)))
return -1; return -1;
virCommandAddArg(cmd, "-chardev"); virCommandAddArg(cmd, "-chardev");
virCommandAddArg(cmd, devstr); virCommandAddArg(cmd, devstr);
@@ -9403,6 +9435,10 @@ qemuBuildRedirdevCommandLine(virLogManagerPtr logManager,
bool chardevStdioLogd) bool chardevStdioLogd)
{ {
size_t i; size_t i;
unsigned int cdevflags = QEMU_BUILD_CHARDEV_TCP_NOWAIT |
QEMU_BUILD_CHARDEV_UNIX_FD_PASS;
if (chardevStdioLogd)
cdevflags |= QEMU_BUILD_CHARDEV_FILE_LOGD;
for (i = 0; i < def->nredirdevs; i++) { for (i = 0; i < def->nredirdevs; i++) {
virDomainRedirdevDefPtr redirdev = def->redirdevs[i]; virDomainRedirdevDefPtr redirdev = def->redirdevs[i];
@@ -9412,8 +9448,7 @@ qemuBuildRedirdevCommandLine(virLogManagerPtr logManager,
cmd, cfg, def, cmd, cfg, def,
redirdev->source, redirdev->source,
redirdev->info.alias, redirdev->info.alias,
qemuCaps, true, qemuCaps, cdevflags))) {
chardevStdioLogd))) {
return -1; return -1;
} }
@@ -10269,8 +10304,7 @@ qemuBuildCommandLine(virQEMUDriverPtr driver,
if (qemuBuildNetCommandLine(driver, logManager, secManager, cmd, def, if (qemuBuildNetCommandLine(driver, logManager, secManager, cmd, def,
qemuCaps, vmop, standalone, qemuCaps, vmop, standalone,
nnicindexes, nicindexes, &bootHostdevNet, nnicindexes, nicindexes, &bootHostdevNet) < 0)
chardevStdioLogd) < 0)
goto error; goto error;
if (qemuBuildSmartcardCommandLine(logManager, secManager, cmd, cfg, def, qemuCaps, if (qemuBuildSmartcardCommandLine(logManager, secManager, cmd, cfg, def, qemuCaps,

View File

@@ -6792,7 +6792,7 @@ qemuDomainSaveImageGetXMLDesc(virConnectPtr conn, const char *path,
if (fd < 0) if (fd < 0)
goto cleanup; goto cleanup;
if (virDomainSaveImageGetXMLDescEnsureACL(conn, def, flags) < 0) if (virDomainSaveImageGetXMLDescEnsureACL(conn, def) < 0)
goto cleanup; goto cleanup;
ret = qemuDomainDefFormatXML(driver, def, flags); ret = qemuDomainDefFormatXML(driver, def, flags);

View File

@@ -5124,6 +5124,9 @@ qemuProcessInit(virQEMUDriverPtr driver,
vm->def->os.machine))) vm->def->os.machine)))
goto cleanup; goto cleanup;
if (flags & VIR_QEMU_PROCESS_START_STANDALONE)
virQEMUCapsClear(priv->qemuCaps, QEMU_CAPS_CHARDEV_FD_PASS);
if (qemuDomainUpdateCPU(vm, updatedCPU, &origCPU) < 0) if (qemuDomainUpdateCPU(vm, updatedCPU, &origCPU) < 0)
goto cleanup; goto cleanup;
@@ -6632,6 +6635,8 @@ qemuProcessCreatePretendCmd(virQEMUDriverPtr driver,
flags |= VIR_QEMU_PROCESS_START_PRETEND; flags |= VIR_QEMU_PROCESS_START_PRETEND;
flags |= VIR_QEMU_PROCESS_START_NEW; flags |= VIR_QEMU_PROCESS_START_NEW;
if (standalone)
flags |= VIR_QEMU_PROCESS_START_STANDALONE;
if (qemuProcessInit(driver, vm, NULL, QEMU_ASYNC_JOB_NONE, if (qemuProcessInit(driver, vm, NULL, QEMU_ASYNC_JOB_NONE,
!!migrateURI, flags) < 0) !!migrateURI, flags) < 0)

View File

@@ -81,6 +81,8 @@ typedef enum {
VIR_QEMU_PROCESS_START_PRETEND = 1 << 3, VIR_QEMU_PROCESS_START_PRETEND = 1 << 3,
VIR_QEMU_PROCESS_START_NEW = 1 << 4, /* internal, new VM is starting */ VIR_QEMU_PROCESS_START_NEW = 1 << 4, /* internal, new VM is starting */
VIR_QEMU_PROCESS_START_GEN_VMID = 1 << 5, /* Generate a new VMID */ VIR_QEMU_PROCESS_START_GEN_VMID = 1 << 5, /* Generate a new VMID */
VIR_QEMU_PROCESS_START_STANDALONE = 1 << 6, /* Require CLI args to be usable standalone,
ie no FD passing and the like */
} qemuProcessStartFlags; } qemuProcessStartFlags;
int qemuProcessStart(virConnectPtr conn, int qemuProcessStart(virConnectPtr conn,

View File

@@ -5226,8 +5226,7 @@ enum remote_procedure {
/** /**
* @generate: both * @generate: both
* @priority: high * @priority: high
* @acl: domain:read * @acl: domain:write
* @acl: domain:read_secure:VIR_DOMAIN_XML_SECURE
*/ */
REMOTE_PROC_DOMAIN_SAVE_IMAGE_GET_XML_DESC = 235, REMOTE_PROC_DOMAIN_SAVE_IMAGE_GET_XML_DESC = 235,

View File

@@ -14,8 +14,7 @@ QEMU_AUDIO_DRV=none \
-display none \ -display none \
-no-user-config \ -no-user-config \
-nodefaults \ -nodefaults \
-chardev socket,id=charmonitor,path=/tmp/lib/domain--1-QEMUGuest1/monitor.sock,\ -chardev socket,id=charmonitor,fd=1729,server,nowait \
server,nowait \
-mon chardev=charmonitor,id=monitor,mode=control \ -mon chardev=charmonitor,id=monitor,mode=control \
-rtc base=utc \ -rtc base=utc \
-no-shutdown \ -no-shutdown \

View File

@@ -26,4 +26,6 @@ server,nowait \
-device ide-drive,bus=ide.0,unit=0,drive=drive-ide0-0-0,id=ide0-0-0 \ -device ide-drive,bus=ide.0,unit=0,drive=drive-ide0-0-0,id=ide0-0-0 \
-chardev socket,id=charserial0,path=/tmp/serial.sock \ -chardev socket,id=charserial0,path=/tmp/serial.sock \
-device isa-serial,chardev=charserial0,id=serial0 \ -device isa-serial,chardev=charserial0,id=serial0 \
-chardev socket,id=charserial1,path=/tmp/serial-server.sock,server,nowait \
-device isa-serial,chardev=charserial1,id=serial1 \
-device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x3 -device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x3

View File

@@ -0,0 +1,36 @@
LC_ALL=C \
PATH=/bin \
HOME=/home/test \
USER=test \
LOGNAME=test \
QEMU_AUDIO_DRV=none \
/usr/bin/qemu-system-i686 \
-name guest=QEMUGuest1,debug-threads=on \
-S \
-object secret,id=masterKey0,format=raw,\
file=/tmp/lib/domain--1-QEMUGuest1/master-key.aes \
-machine pc,accel=tcg,usb=off,dump-guest-core=off \
-m 214 \
-realtime mlock=off \
-smp 1,sockets=1,cores=1,threads=1 \
-uuid c7a5fdbd-edaf-9455-926a-d65c16db1809 \
-display none \
-no-user-config \
-nodefaults \
-chardev socket,id=charmonitor,fd=1729,server,nowait \
-mon chardev=charmonitor,id=monitor,mode=control \
-rtc base=utc \
-no-shutdown \
-no-acpi \
-boot strict=on \
-device piix3-usb-uhci,id=usb,bus=pci.0,addr=0x1.0x2 \
-drive file=/dev/HostVG/QEMUGuest1,format=raw,if=none,id=drive-ide0-0-0 \
-device ide-hd,bus=ide.0,unit=0,drive=drive-ide0-0-0,id=ide0-0-0,bootindex=1 \
-chardev socket,id=charserial0,path=/tmp/serial.sock \
-device isa-serial,chardev=charserial0,id=serial0 \
-chardev socket,id=charserial1,fd=1729,server,nowait \
-device isa-serial,chardev=charserial1,id=serial1 \
-device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x2 \
-sandbox on,obsolete=deny,elevateprivileges=deny,spawn=deny,\
resourcecontrol=deny \
-msg timestamp=on

View File

@@ -25,6 +25,10 @@
<source mode='connect' path='/tmp/serial.sock'/> <source mode='connect' path='/tmp/serial.sock'/>
<target port='0'/> <target port='0'/>
</serial> </serial>
<serial type='unix'>
<source mode='bind' path='/tmp/serial-server.sock'/>
<target port='1'/>
</serial>
<console type='unix'> <console type='unix'>
<source mode='connect' path='/tmp/serial.sock'/> <source mode='connect' path='/tmp/serial.sock'/>
<target port='0'/> <target port='0'/>

View File

@@ -1266,7 +1266,7 @@ mymain(void)
DO_TEST("misc-no-reboot", NONE); DO_TEST("misc-no-reboot", NONE);
DO_TEST("misc-uuid", NONE); DO_TEST("misc-uuid", NONE);
DO_TEST_PARSE_ERROR("vhost_queues-invalid", NONE); DO_TEST_PARSE_ERROR("vhost_queues-invalid", NONE);
DO_TEST("net-vhostuser", NONE); DO_TEST("net-vhostuser", QEMU_CAPS_CHARDEV_FD_PASS);
DO_TEST("net-vhostuser-multiq", DO_TEST("net-vhostuser-multiq",
QEMU_CAPS_VHOSTUSER_MULTIQUEUE); QEMU_CAPS_VHOSTUSER_MULTIQUEUE);
DO_TEST_FAILURE("net-vhostuser-multiq", NONE); DO_TEST_FAILURE("net-vhostuser-multiq", NONE);
@@ -1335,6 +1335,7 @@ mymain(void)
QEMU_CAPS_CHARDEV_FILE_APPEND); QEMU_CAPS_CHARDEV_FILE_APPEND);
DO_TEST("serial-unix-chardev", DO_TEST("serial-unix-chardev",
QEMU_CAPS_DEVICE_ISA_SERIAL); QEMU_CAPS_DEVICE_ISA_SERIAL);
DO_TEST_CAPS_LATEST("serial-unix-chardev");
DO_TEST("serial-tcp-chardev", DO_TEST("serial-tcp-chardev",
QEMU_CAPS_DEVICE_ISA_SERIAL); QEMU_CAPS_DEVICE_ISA_SERIAL);
DO_TEST("serial-udp-chardev", DO_TEST("serial-udp-chardev",