[libvirt] [PATCH] virsh: Fix job status indicator for 0 length block jobs
by Peter Krempa
Although 0 length block jobs aren't entirely useful, the output of virsh
blockjob is empty due to the condition that suppresses the output for
migration jobs that did not start. Add a flag for virshPrintJobProgress
that specifies that the job was started so that the function can be used
both in migration where the job starts delayed and for block jobs where
we already know that the job was started.
Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1196711
---
tools/virsh-domain.c | 24 +++++++++++++++++-------
1 file changed, 17 insertions(+), 7 deletions(-)
diff --git a/tools/virsh-domain.c b/tools/virsh-domain.c
index b029b65..7837974 100644
--- a/tools/virsh-domain.c
+++ b/tools/virsh-domain.c
@@ -1683,13 +1683,23 @@ cmdBlkiotune(vshControl * ctl, const vshCmd * cmd)
}
+/**
+ * virshPrintJobProgress:
+ * @label: name of the block job
+ * @remaining: amount of remaining work
+ * @total: amount of total work
+ * @started: The block job was started already
+ *
+ * Prints a human friendly percentage string decribing the state of the given
+ * job. The output is omitted if the job was not started.
+ */
static void
virshPrintJobProgress(const char *label, unsigned long long remaining,
- unsigned long long total)
+ unsigned long long total, bool started)
{
int progress;
- if (total == 0)
+ if (total == 0 && !started)
/* migration has not been started */
return;
@@ -1921,7 +1931,7 @@ virshBlockJobWait(virshBlockJobWaitDataPtr data)
if (data->verbose)
virshPrintJobProgress(data->job_name, info.end - info.cur,
- info.end);
+ info.end, true);
if (data->timeout && virTimeMillisNow(&curr) < 0) {
vshSaveLibvirtError();
@@ -1949,7 +1959,7 @@ virshBlockJobWait(virshBlockJobWaitDataPtr data)
if (data->verbose &&
(ret == VIR_DOMAIN_BLOCK_JOB_COMPLETED ||
ret == VIR_DOMAIN_BLOCK_JOB_READY))
- virshPrintJobProgress(data->job_name, 0, 1);
+ virshPrintJobProgress(data->job_name, 0, 1, true);
sigaction(SIGINT, &old_sig_action, NULL);
return ret;
@@ -2621,7 +2631,7 @@ virshBlockJobInfo(vshControl *ctl,
info.bandwidth, info.cur, info.end);
} else {
virshPrintJobProgress(virshDomainBlockJobToString(info.type),
- info.end - info.cur, info.end);
+ info.end - info.cur, info.end, true);
if (speed) {
const char *unit;
double val = vshPrettyCapacity(speed, &unit);
@@ -4356,7 +4366,7 @@ virshWatchJob(vshControl *ctl,
retchar == '0') {
if (verbose) {
/* print [100 %] */
- virshPrintJobProgress(label, 0, 1);
+ virshPrintJobProgress(label, 0, 1, true);
}
break;
}
@@ -4392,7 +4402,7 @@ virshWatchJob(vshControl *ctl,
if (ret == 0) {
if (verbose)
virshPrintJobProgress(label, jobinfo.dataRemaining,
- jobinfo.dataTotal);
+ jobinfo.dataTotal, false);
if (!jobStarted &&
(jobinfo.type == VIR_DOMAIN_JOB_BOUNDED ||
--
2.4.5
9 years, 2 months
[libvirt] [PATCH 0/2] Fix permissions for per-VM and qemu directories
by Martin Kletzander
This is basically v2 of:
https://www.redhat.com/archives/libvir-list/2015-September/msg00295.html
with some changes:
- permissions for per-VM dirs are fixed as well
- permissions for the /var/lib/libvirt/qemu directory are fixed in
the install phase of Makefile.am in addition to the spec file
We could also fix the permissions in qemuStateInitialize, but I chose
to do it this way. Bear in mind, that both approaches have their pros
and cons, of course.
Martin Kletzander (2):
qemu: Do not allow others into per-VM subdirectories
qemu: Allow others to browse /var/lib/libvirt/qemu
libvirt.spec.in | 4 ++--
src/Makefile.am | 2 +-
src/qemu/qemu_process.c | 4 ++--
3 files changed, 5 insertions(+), 5 deletions(-)
--
2.5.2
9 years, 2 months
[libvirt] [PATCH] qemu: hotplug: Properly clean up drive backend if frontend hotplug fails
by Peter Krempa
Commit 8125113c added code that should remove the disk backend if the
fronted hotplug failed for any reason. The code had a bug though as it
used the disk string for unplug rather than the backend alias. Fix the
code by pre-creating an alias string and using it instead of the disk
string. In cases where qemu does not support QEMU_CAPS_DEVICE, we ignore
the unplug of the backend since we can't really create an alias in that
case.
Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1262399
---
src/qemu/qemu_hotplug.c | 9 ++++++++-
1 file changed, 8 insertions(+), 1 deletion(-)
diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c
index 63fafa6..c956e8c 100644
--- a/src/qemu/qemu_hotplug.c
+++ b/src/qemu/qemu_hotplug.c
@@ -321,6 +321,7 @@ qemuDomainAttachVirtioDiskDevice(virConnectPtr conn,
qemuDomainObjPrivatePtr priv = vm->privateData;
char *devstr = NULL;
char *drivestr = NULL;
+ char *drivealias = NULL;
bool releaseaddr = false;
virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
const char *src = virDomainDiskGetSource(disk);
@@ -365,6 +366,10 @@ qemuDomainAttachVirtioDiskDevice(virConnectPtr conn,
if (!(drivestr = qemuBuildDriveStr(conn, disk, false, priv->qemuCaps)))
goto error;
+ if (virAsprintf(&drivealias, "%s%s", QEMU_DRIVE_HOST_PREFIX,
+ disk->info.alias) < 0)
+ goto error;
+
if (!(devstr = qemuBuildDriveDevStr(vm->def, disk, 0, priv->qemuCaps)))
goto error;
}
@@ -379,7 +384,8 @@ qemuDomainAttachVirtioDiskDevice(virConnectPtr conn,
ret = qemuMonitorAddDevice(priv->mon, devstr);
if (ret < 0) {
virErrorPtr orig_err = virSaveLastError();
- if (qemuMonitorDriveDel(priv->mon, drivestr) < 0) {
+ if (!drivealias ||
+ qemuMonitorDriveDel(priv->mon, drivealias) < 0) {
VIR_WARN("Unable to remove drive %s (%s) after failed "
"qemuMonitorAddDevice",
drivestr, devstr);
@@ -415,6 +421,7 @@ qemuDomainAttachVirtioDiskDevice(virConnectPtr conn,
cleanup:
VIR_FREE(devstr);
VIR_FREE(drivestr);
+ VIR_FREE(drivealias);
virObjectUnref(cfg);
return ret;
--
2.4.5
9 years, 2 months
[libvirt] LSN-2015-0003: CVE-2015-5247 denial of service through root-squash NFS storage pools
by Eric Blake
Libvirt Security Notice: LSN-2015-0003
======================================
Summary: denial of service through root-squash NFS storage
pools
Reported on: 20150814
Published on: 20150903
Fixed on: 20150903
Reported by: Han Han <hhan(a)redhat.com>
Patched by: John Ferlan <jferlan(a)redhat.com>
See also: CVE-2015-5247
Description
-----------
The virStorageVolCreateXML API had a bug where it could create a
volume on a root-squash NFS mount, but then fail to remove that
volume if later steps during the API encountered problems. This was
further compounded by code which used a wrong conditional on whether
the new volume needed to have permissions changed, making it more
likely to trigger the failed unlink attempt. Poor error handling
after a failed unlink left libvirt with an inconsistent view of the
storage volume that could then result in a libvirtd crash. While the
libvirtd crash might be delayed until by subsequent actions from a
read-only connection, the conditions that set up the crash can only
be triggered by a client with a read-write connection.
Impact
------
When using fine-grained Access Control Lists (ACL), the
virStorageVolCreateXML API only requires the storage_vol:create
permission. A client with this privilege but lacking the
more-powerful domain:write permission could exploit the API bugs to
cause a denial-of-service attack by taking down libvirtd through a
crash. It can also be argued that the ability to cause libvirt to
create files which it cannot delete can be used as a
denial-of-service attack on storage resources.
Workaround
----------
The problems with libvirt creating a file which it does not then
clean up on error is specific to root-squash NFS, so one mitigation
is avoiding the use of the root-squash option when exporting NFS
volumes for use by libvirt storage pools. Note that in general, the
use of root-squash NFS does not add any real security (it makes
certain tasks harder for a root user, but the root user can
trivially change ids to another user to still perform those tasks).
Furthermore, it is possible to prevent the denial of service attacks
by stopping the use of the fine grained access control mechanism
(while this does not prevent a crash, such a crash is no longer a
security problem as there is no longer a privilege boundary between
a user creating a volume and a user with full system access).
Affected product
----------------
Name: libvirt
Repository: git://libvirt.org/git/libvirt.git
http://libvirt.org/git/?p=libvirt.git
Branch: master
Broken in: v1.2.14
Broken in: v1.2.15
Broken in: v1.2.16
Broken in: v1.2.17
Broken in: v1.2.18
Broken in: v1.2.19
Broken by: 155ca616eb231181f6978efc9e3a1eb0eb60af8a
Broken by: 7c2d65dde2595c07d56aad1e043f7b1836592d89
Fixed by: db9277a39bc364806e8d3e08a08fc128d59b7094
Fixed by: 691dd388aee99f8b06177540303b690586d5f5b3
Fixed by: 35847860f65f92e444db9730e00cdaef45198e0c
Branch: v1.2.14-maint
Broken by: 155ca616eb231181f6978efc9e3a1eb0eb60af8a
Fixed by: 605b12068392d29beb44a8ab7d6ec176d6b05237
Fixed by: 454cb7c40dbcff84192094963d71369ac7d94546
Branch: v1.2.15-maint
Broken by: 155ca616eb231181f6978efc9e3a1eb0eb60af8a
Fixed by: 3c41b3ea5e68f391b8ff901082608bda5f7f3fbc
Fixed by: fe2cf73800e3be87d1d4d811facb3f2be48126e5
Branch: v1.2.16-maint
Broken by: 155ca616eb231181f6978efc9e3a1eb0eb60af8a
Broken by: 7c2d65dde2595c07d56aad1e043f7b1836592d89
Fixed by: 9e48400f4606bac16b7e4db195f610928c3d5a04
Fixed by: 2f4b41861c1729ff4b754986782d7428ccdca455
Fixed by: 7f0505705c70f7eb1e435a2e7732d1a74abfadfd
Branch: v1.2.17-maint
Broken by: 155ca616eb231181f6978efc9e3a1eb0eb60af8a
Broken by: 7c2d65dde2595c07d56aad1e043f7b1836592d89
Fixed by: d055989083df4bf68eb1388d327ebffb3501bb83
Fixed by: 98242f94cd181f0257535479369054f07f951b21
Fixed by: a3ee6885d95a2ce6fb7e58bb0737cfb1612e0fb7
Branch: v1.2.18-maint
Broken by: 155ca616eb231181f6978efc9e3a1eb0eb60af8a
Broken by: 7c2d65dde2595c07d56aad1e043f7b1836592d89
Fixed by: e63b32e22dafd99547f82f5383fdbf58b5f651a1
Fixed by: 075eb526c9817d9d8e3a759e3fbe180d8d326dcf
Fixed by: 966cc922221be2b8cc6a9842ed0dc4cf1568a7b3
Branch: v1.2.19-maint
Broken by: 155ca616eb231181f6978efc9e3a1eb0eb60af8a
Broken by: 7c2d65dde2595c07d56aad1e043f7b1836592d89
Fixed by: e0025d2967bbe3f283937216c9e2c12b6e9d1010
Fixed by: 8b1d84e640f1a6e6ebb47caf23a664e2f651b32d
Fixed by: 3468542f06f6f5dc94defa1603c6a6adea3e2da8
--
Eric Blake eblake redhat com +1-919-301-3266
Libvirt virtualization library http://libvirt.org
9 years, 2 months
[libvirt] [PATCH] qemu: command: Report stderr from qemu-bridge-helper
by Cole Robinson
There's a couple reports of things failing in this area (bug 1259070),
but it's tough to tell what's going wrong without stderr from
qemu-bridge-helper. So let's report stderr in the error message
Couple new examples:
virbr0 is inactive:
internal error: /usr/libexec/qemu-bridge-helper --use-vnet --br=virbr0 --fd=21: failed to retrieve file descriptor: Transport endpoint is not connected
stderr=failed to get mtu of bridge `virbr0': No such device
bridge isn't on the ACL:
internal error: /usr/libexec/qemu-bridge-helper --use-vnet --br=br0 --fd=21: failed to retrieve file descriptor: Transport endpoint is not connected
stderr=access denied by acl file
---
src/qemu/qemu_command.c | 24 ++++++++++++++++++++++--
1 file changed, 22 insertions(+), 2 deletions(-)
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index ec5e3d4..fc22f36 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -285,6 +285,7 @@ static int qemuCreateInBridgePortWithHelper(virQEMUDriverConfigPtr cfg,
unsigned int flags)
{
virCommandPtr cmd;
+ char *errbuf = NULL, *cmdstr = NULL;
int pair[2] = { -1, -1 };
if ((flags & ~VIR_NETDEV_TAP_CREATE_VNET_HDR) != VIR_NETDEV_TAP_CREATE_IFUP)
@@ -306,6 +307,8 @@ static int qemuCreateInBridgePortWithHelper(virQEMUDriverConfigPtr cfg,
virCommandAddArgFormat(cmd, "--use-vnet");
virCommandAddArgFormat(cmd, "--br=%s", brname);
virCommandAddArgFormat(cmd, "--fd=%d", pair[1]);
+ virCommandSetErrorBuffer(cmd, &errbuf);
+ virCommandDoAsyncIO(cmd);
virCommandPassFD(cmd, pair[1],
VIR_COMMAND_PASS_FD_CLOSE_PARENT);
virCommandClearCaps(cmd);
@@ -320,9 +323,24 @@ static int qemuCreateInBridgePortWithHelper(virQEMUDriverConfigPtr cfg,
do {
*tapfd = recvfd(pair[0], 0);
} while (*tapfd < 0 && errno == EINTR);
+
if (*tapfd < 0) {
- virReportSystemError(errno, "%s",
- _("failed to retrieve file descriptor for interface"));
+ char ebuf[1024];
+ char *errstr = NULL;
+
+ if (!(cmdstr = virCommandToString(cmd)))
+ goto cleanup;
+ virCommandAbort(cmd);
+
+ if (errbuf && *errbuf &&
+ virAsprintf(&errstr, "\nstderr=%s", errbuf) < 0)
+ goto cleanup;
+
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ _("%s: failed to retrieve file descriptor: %s%s"),
+ cmdstr, virStrerror(errno, ebuf, sizeof(ebuf)),
+ errstr ? errstr : "");
+ VIR_FREE(errstr);
goto cleanup;
}
@@ -333,6 +351,8 @@ static int qemuCreateInBridgePortWithHelper(virQEMUDriverConfigPtr cfg,
}
cleanup:
+ VIR_FREE(cmdstr);
+ VIR_FREE(errbuf);
virCommandFree(cmd);
VIR_FORCE_CLOSE(pair[0]);
return *tapfd < 0 ? -1 : 0;
--
2.5.0
9 years, 2 months
[libvirt] [PATCH LIBVIRT] libxl: don't end job for ephemeal domain on start failure
by Ian Campbell
commit 4b53d0d4ac9c "libxl: don't remove persistent domain on start
failure" cleans up the vm object and sets it to NULL if the vm is not
persistent, however at end job vm (now NULL) is dereferenced via the call to
libxlDomainObjEndJob. Avoid this by skipping "endjob" and going
straight to "cleanup" in this case.
Signed-off-by: Ian Campbell <ian.campbell(a)citrix.com>
---
src/libxl/libxl_driver.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/src/libxl/libxl_driver.c b/src/libxl/libxl_driver.c
index 5f69b49..e2797d5 100644
--- a/src/libxl/libxl_driver.c
+++ b/src/libxl/libxl_driver.c
@@ -992,6 +992,7 @@ libxlDomainCreateXML(virConnectPtr conn, const char *xml,
if (!vm->persistent) {
virDomainObjListRemove(driver->domains, vm);
vm = NULL;
+ goto cleanup;
}
goto endjob;
}
--
2.1.4
9 years, 2 months
[libvirt] [PATCH] xen: fix race in refresh of config cache
by Daniel P. Berrange
The xenXMConfigCacheRefresh method scans /etc/xen and loads
all config files it finds. It then scans its internal hash
table and purges any (previously) loaded config files whose
refresh timestamp does not match the timestamp recorded at
the start of xenXMConfigCacheRefresh(). There is unfortunately
a subtle flaw in this, because if loading the config files
takes longer than 1 second, some of the config files will
have a refresh timestamp that is 1 or more seconds different
(newer) than is checked for. So we immediately purge a bunch
of valid config files we just loaded.
To avoid this flaw, we must pass the timestamp we record at
the start of xenXMConfigCacheRefresh() into the
xenXMConfigCacheAddFile() method, instead of letting the
latter call time(NULL) again.
Signed-off-by: Daniel P. Berrange <berrange(a)redhat.com>
---
src/xen/xen_inotify.c | 10 ++++++----
src/xen/xm_internal.c | 7 +++----
src/xen/xm_internal.h | 2 +-
3 files changed, 10 insertions(+), 9 deletions(-)
diff --git a/src/xen/xen_inotify.c b/src/xen/xen_inotify.c
index cd1e2df..d81a35d 100644
--- a/src/xen/xen_inotify.c
+++ b/src/xen/xen_inotify.c
@@ -217,11 +217,11 @@ xenInotifyRemoveDomainConfigInfo(virConnectPtr conn, const char *fname)
}
static int
-xenInotifyAddDomainConfigInfo(virConnectPtr conn, const char *fname)
+xenInotifyAddDomainConfigInfo(virConnectPtr conn, const char *fname, time_t now)
{
xenUnifiedPrivatePtr priv = conn->privateData;
return priv->useXenConfigCache ?
- xenXMConfigCacheAddFile(conn, fname) :
+ xenXMConfigCacheAddFile(conn, fname, now) :
xenInotifyXendDomainsDirAddEntry(conn, fname);
}
@@ -238,6 +238,7 @@ xenInotifyEvent(int watch ATTRIBUTE_UNUSED,
char *tmp, *name;
virConnectPtr conn = data;
xenUnifiedPrivatePtr priv = NULL;
+ time_t now = time(NULL);
VIR_DEBUG("got inotify event");
@@ -300,7 +301,7 @@ xenInotifyEvent(int watch ATTRIBUTE_UNUSED,
}
} else if (e->mask & (IN_CREATE | IN_CLOSE_WRITE | IN_MOVED_TO)) {
virObjectEventPtr event;
- if (xenInotifyAddDomainConfigInfo(conn, fname) < 0) {
+ if (xenInotifyAddDomainConfigInfo(conn, fname, now) < 0) {
virReportError(VIR_ERR_INTERNAL_ERROR,
"%s", _("Error adding file to config cache"));
goto cleanup;
@@ -344,6 +345,7 @@ xenInotifyOpen(virConnectPtr conn,
char *path;
xenUnifiedPrivatePtr priv = conn->privateData;
int direrr;
+ time_t now = time(NULL);
virCheckFlags(VIR_CONNECT_RO, -1);
@@ -374,7 +376,7 @@ xenInotifyOpen(virConnectPtr conn,
return -1;
}
- if (xenInotifyAddDomainConfigInfo(conn, path) < 0) {
+ if (xenInotifyAddDomainConfigInfo(conn, path, now) < 0) {
virReportError(VIR_ERR_INTERNAL_ERROR,
"%s", _("Error adding file to config list"));
closedir(dh);
diff --git a/src/xen/xm_internal.c b/src/xen/xm_internal.c
index 59b1cd4..07b9eb4 100644
--- a/src/xen/xm_internal.c
+++ b/src/xen/xm_internal.c
@@ -191,15 +191,14 @@ xenXMConfigCacheRemoveFile(virConnectPtr conn, const char *filename)
* calling this function
*/
int
-xenXMConfigCacheAddFile(virConnectPtr conn, const char *filename)
+xenXMConfigCacheAddFile(virConnectPtr conn, const char *filename, time_t now)
{
xenUnifiedPrivatePtr priv = conn->privateData;
xenXMConfCachePtr entry;
struct stat st;
int newborn = 0;
- time_t now = time(NULL);
- VIR_DEBUG("Adding file %s", filename);
+ VIR_DEBUG("Adding file %s %lld", filename, (long long)now);
/* Get modified time */
if ((stat(filename, &st) < 0)) {
@@ -373,7 +372,7 @@ xenXMConfigCacheRefresh(virConnectPtr conn)
/* If we already have a matching entry and it is not
modified, then carry on to next one*/
- if (xenXMConfigCacheAddFile(conn, path) < 0) {
+ if (xenXMConfigCacheAddFile(conn, path, now) < 0) {
/* Ignoring errors, since a lot of stuff goes wrong in /etc/xen */
}
diff --git a/src/xen/xm_internal.h b/src/xen/xm_internal.h
index 25b4fd5..0246895 100644
--- a/src/xen/xm_internal.h
+++ b/src/xen/xm_internal.h
@@ -31,7 +31,7 @@
# include "domain_conf.h"
int xenXMConfigCacheRefresh (virConnectPtr conn);
-int xenXMConfigCacheAddFile(virConnectPtr conn, const char *filename);
+int xenXMConfigCacheAddFile(virConnectPtr conn, const char *filename, time_t now);
int xenXMConfigCacheRemoveFile(virConnectPtr conn, const char *filename);
int xenXMOpen(virConnectPtr conn, virConnectAuthPtr auth, unsigned int flags);
--
2.4.3
9 years, 2 months
[libvirt] [PATCH] tests: Don't use testutils in mock libraries
by Martin Kletzander
Mock libraries are not built with testutils.c, but there's one which
uses VIR_TEST_DEBUG. But because that debug should be an error, if we
change it, then it will not only be more semantically correct, but mingw
compiler will be happier as well.
It also follows suit with all other mock libraries.
For few other things, used in this file, need libvirt.la to be added
into LIBADD for mingw as well.
Signed-off-by: Martin Kletzander <mkletzan(a)redhat.com>
---
tests/Makefile.am | 1 +
tests/virportallocatortest.c | 2 +-
2 files changed, 2 insertions(+), 1 deletion(-)
diff --git a/tests/Makefile.am b/tests/Makefile.am
index bde7f5baf1fe..4af38fe9c14b 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -1020,6 +1020,7 @@ libvirportallocatormock_la_SOURCES = \
virportallocatortest.c
libvirportallocatormock_la_CFLAGS = $(AM_CFLAGS) -DMOCK_HELPER=1
libvirportallocatormock_la_LDFLAGS = $(MOCKLIBS_LDFLAGS)
+libvirportallocatormock_la_LIBADD = ../src/libvirt.la
vircgrouptest_SOURCES = \
vircgrouptest.c testutils.h testutils.c
diff --git a/tests/virportallocatortest.c b/tests/virportallocatortest.c
index 1125b0aeedda..58b2155994f9 100644
--- a/tests/virportallocatortest.c
+++ b/tests/virportallocatortest.c
@@ -49,7 +49,7 @@ static void init_syms(void)
realsocket = dlsym(RTLD_NEXT, "socket");
if (!realsocket) {
- VIR_TEST_DEBUG("Unable to find 'socket' symbol\n");
+ fprintf(stderr, "Unable to find 'socket' symbol\n");
abort();
}
--
2.5.1
9 years, 2 months
[libvirt] (no subject)
by Wido den Hollander
The current code of libvirt-java does not build with Java 7.
This patch updates the build.properties and INSTALL that we
require Java 8 to build libvirt-java.
9 years, 2 months