|
Daniel P. Berrange |
427ed2 |
From 076fffe1514b72ffc9a041f7f68348f5487ee8ba Mon Sep 17 00:00:00 2001
|
|
Daniel P. Berrange |
427ed2 |
From: Daniel P. Berrange <berrange@redhat.com>
|
|
Daniel P. Berrange |
427ed2 |
Date: Wed, 11 Nov 2009 12:07:00 +0000
|
|
Daniel P. Berrange |
427ed2 |
Subject: [PATCH] Fix save and restore with non-privileged guests and SELinux
|
|
Daniel P. Berrange |
427ed2 |
|
|
Daniel P. Berrange |
427ed2 |
When running qemu:///system instance, libvirtd runs as root,
|
|
Daniel P. Berrange |
427ed2 |
but QEMU may optionally be configured to run non-root. When
|
|
Daniel P. Berrange |
427ed2 |
then saving a guest to a state file, the file is initially
|
|
Daniel P. Berrange |
427ed2 |
created as root, and thus QEMU cannot write to it. It is also
|
|
Daniel P. Berrange |
427ed2 |
missing labelling required to allow access via SELinux.
|
|
Daniel P. Berrange |
427ed2 |
|
|
Daniel P. Berrange |
427ed2 |
* src/qemu/qemu_driver.c: Set ownership on save image before
|
|
Daniel P. Berrange |
427ed2 |
running migrate command in virDomainSave impl. Call out to
|
|
Daniel P. Berrange |
427ed2 |
security driver to set save image labelling
|
|
Daniel P. Berrange |
427ed2 |
* src/security/security_driver.h: Add driver APIs for setting
|
|
Daniel P. Berrange |
427ed2 |
and restoring saved state file labelling
|
|
Daniel P. Berrange |
427ed2 |
* src/security/security_selinux.c: Implement saved state file
|
|
Daniel P. Berrange |
427ed2 |
labelling for SELinux
|
|
Daniel P. Berrange |
427ed2 |
|
|
Daniel P. Berrange |
427ed2 |
(cherry picked from commit bc0010b3d149df00406b82c37eb59874d8525af4)
|
|
Daniel P. Berrange |
427ed2 |
|
|
Daniel P. Berrange |
427ed2 |
Fedora-patch: libvirt-qemu-save-restore.patch
|
|
Daniel P. Berrange |
427ed2 |
---
|
|
Daniel P. Berrange |
427ed2 |
src/qemu/qemu_driver.c | 35 ++++++++++++++++++++++++++++++++---
|
|
Daniel P. Berrange |
427ed2 |
src/security/security_driver.h | 7 +++++++
|
|
Daniel P. Berrange |
427ed2 |
src/security/security_selinux.c | 23 +++++++++++++++++++++++
|
|
Daniel P. Berrange |
427ed2 |
3 files changed, 62 insertions(+), 3 deletions(-)
|
|
Daniel P. Berrange |
427ed2 |
|
|
Daniel P. Berrange |
427ed2 |
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
|
|
Daniel P. Berrange |
427ed2 |
index c544c4b..171ac8f 100644
|
|
Daniel P. Berrange |
427ed2 |
--- a/src/qemu/qemu_driver.c
|
|
Daniel P. Berrange |
427ed2 |
+++ b/src/qemu/qemu_driver.c
|
|
Daniel P. Berrange |
427ed2 |
@@ -3146,6 +3146,7 @@ static int qemudDomainSave(virDomainPtr dom,
|
|
Daniel P. Berrange |
427ed2 |
char *xml = NULL;
|
|
Daniel P. Berrange |
427ed2 |
struct qemud_save_header header;
|
|
Daniel P. Berrange |
427ed2 |
int ret = -1;
|
|
Daniel P. Berrange |
427ed2 |
+ int rc;
|
|
Daniel P. Berrange |
427ed2 |
virDomainEventPtr event = NULL;
|
|
Daniel P. Berrange |
427ed2 |
|
|
Daniel P. Berrange |
427ed2 |
memset(&header, 0, sizeof(header));
|
|
Daniel P. Berrange |
427ed2 |
@@ -3226,9 +3227,22 @@ static int qemudDomainSave(virDomainPtr dom,
|
|
Daniel P. Berrange |
427ed2 |
}
|
|
Daniel P. Berrange |
427ed2 |
fd = -1;
|
|
Daniel P. Berrange |
427ed2 |
|
|
Daniel P. Berrange |
427ed2 |
+ if (driver->privileged &&
|
|
Daniel P. Berrange |
427ed2 |
+ chown(path, driver->user, driver->group) < 0) {
|
|
Daniel P. Berrange |
427ed2 |
+ virReportSystemError(NULL, errno,
|
|
Daniel P. Berrange |
427ed2 |
+ _("unable to set ownership of '%s' to user %d:%d"),
|
|
Daniel P. Berrange |
427ed2 |
+ path, driver->user, driver->group);
|
|
Daniel P. Berrange |
427ed2 |
+ goto cleanup;
|
|
Daniel P. Berrange |
427ed2 |
+ }
|
|
Daniel P. Berrange |
427ed2 |
+
|
|
Daniel P. Berrange |
427ed2 |
+ if (driver->securityDriver &&
|
|
Daniel P. Berrange |
427ed2 |
+ driver->securityDriver->domainSetSavedStateLabel &&
|
|
Daniel P. Berrange |
427ed2 |
+ driver->securityDriver->domainSetSavedStateLabel(dom->conn, vm, path) == -1)
|
|
Daniel P. Berrange |
427ed2 |
+ goto cleanup;
|
|
Daniel P. Berrange |
427ed2 |
+
|
|
Daniel P. Berrange |
427ed2 |
if (header.compressed == QEMUD_SAVE_FORMAT_RAW) {
|
|
Daniel P. Berrange |
427ed2 |
const char *args[] = { "cat", NULL };
|
|
Daniel P. Berrange |
427ed2 |
- ret = qemuMonitorMigrateToCommand(vm, 0, args, path);
|
|
Daniel P. Berrange |
427ed2 |
+ rc = qemuMonitorMigrateToCommand(vm, 0, args, path);
|
|
Daniel P. Berrange |
427ed2 |
} else {
|
|
Daniel P. Berrange |
427ed2 |
const char *prog = qemudSaveCompressionTypeToString(header.compressed);
|
|
Daniel P. Berrange |
427ed2 |
const char *args[] = {
|
|
Daniel P. Berrange |
427ed2 |
@@ -3236,12 +3250,27 @@ static int qemudDomainSave(virDomainPtr dom,
|
|
Daniel P. Berrange |
427ed2 |
"-c",
|
|
Daniel P. Berrange |
427ed2 |
NULL
|
|
Daniel P. Berrange |
427ed2 |
};
|
|
Daniel P. Berrange |
427ed2 |
- ret = qemuMonitorMigrateToCommand(vm, 0, args, path);
|
|
Daniel P. Berrange |
427ed2 |
+ rc = qemuMonitorMigrateToCommand(vm, 0, args, path);
|
|
Daniel P. Berrange |
427ed2 |
}
|
|
Daniel P. Berrange |
427ed2 |
|
|
Daniel P. Berrange |
427ed2 |
- if (ret < 0)
|
|
Daniel P. Berrange |
427ed2 |
+ if (rc < 0)
|
|
Daniel P. Berrange |
427ed2 |
goto cleanup;
|
|
Daniel P. Berrange |
427ed2 |
|
|
Daniel P. Berrange |
427ed2 |
+ if (driver->privileged &&
|
|
Daniel P. Berrange |
427ed2 |
+ chown(path, 0, 0) < 0) {
|
|
Daniel P. Berrange |
427ed2 |
+ virReportSystemError(NULL, errno,
|
|
Daniel P. Berrange |
427ed2 |
+ _("unable to set ownership of '%s' to user %d:%d"),
|
|
Daniel P. Berrange |
427ed2 |
+ path, 0, 0);
|
|
Daniel P. Berrange |
427ed2 |
+ goto cleanup;
|
|
Daniel P. Berrange |
427ed2 |
+ }
|
|
Daniel P. Berrange |
427ed2 |
+
|
|
Daniel P. Berrange |
427ed2 |
+ if (driver->securityDriver &&
|
|
Daniel P. Berrange |
427ed2 |
+ driver->securityDriver->domainRestoreSavedStateLabel &&
|
|
Daniel P. Berrange |
427ed2 |
+ driver->securityDriver->domainRestoreSavedStateLabel(dom->conn, path) == -1)
|
|
Daniel P. Berrange |
427ed2 |
+ goto cleanup;
|
|
Daniel P. Berrange |
427ed2 |
+
|
|
Daniel P. Berrange |
427ed2 |
+ ret = 0;
|
|
Daniel P. Berrange |
427ed2 |
+
|
|
Daniel P. Berrange |
427ed2 |
/* Shut it down */
|
|
Daniel P. Berrange |
427ed2 |
qemudShutdownVMDaemon(dom->conn, driver, vm);
|
|
Daniel P. Berrange |
427ed2 |
event = virDomainEventNewFromObj(vm,
|
|
Daniel P. Berrange |
427ed2 |
diff --git a/src/security/security_driver.h b/src/security/security_driver.h
|
|
Daniel P. Berrange |
427ed2 |
index fde2978..5514962 100644
|
|
Daniel P. Berrange |
427ed2 |
--- a/src/security/security_driver.h
|
|
Daniel P. Berrange |
427ed2 |
+++ b/src/security/security_driver.h
|
|
Daniel P. Berrange |
427ed2 |
@@ -42,6 +42,11 @@ typedef int (*virSecurityDomainRestoreHostdevLabel) (virConnectPtr conn,
|
|
Daniel P. Berrange |
427ed2 |
typedef int (*virSecurityDomainSetHostdevLabel) (virConnectPtr conn,
|
|
Daniel P. Berrange |
427ed2 |
virDomainObjPtr vm,
|
|
Daniel P. Berrange |
427ed2 |
virDomainHostdevDefPtr dev);
|
|
Daniel P. Berrange |
427ed2 |
+typedef int (*virSecurityDomainSetSavedStateLabel) (virConnectPtr conn,
|
|
Daniel P. Berrange |
427ed2 |
+ virDomainObjPtr vm,
|
|
Daniel P. Berrange |
427ed2 |
+ const char *savefile);
|
|
Daniel P. Berrange |
427ed2 |
+typedef int (*virSecurityDomainRestoreSavedStateLabel) (virConnectPtr conn,
|
|
Daniel P. Berrange |
427ed2 |
+ const char *savefile);
|
|
Daniel P. Berrange |
427ed2 |
typedef int (*virSecurityDomainGenLabel) (virConnectPtr conn,
|
|
Daniel P. Berrange |
427ed2 |
virDomainObjPtr sec);
|
|
Daniel P. Berrange |
427ed2 |
typedef int (*virSecurityDomainReserveLabel) (virConnectPtr conn,
|
|
Daniel P. Berrange |
427ed2 |
@@ -71,6 +76,8 @@ struct _virSecurityDriver {
|
|
Daniel P. Berrange |
427ed2 |
virSecurityDomainRestoreLabel domainRestoreSecurityLabel;
|
|
Daniel P. Berrange |
427ed2 |
virSecurityDomainRestoreHostdevLabel domainRestoreSecurityHostdevLabel;
|
|
Daniel P. Berrange |
427ed2 |
virSecurityDomainSetHostdevLabel domainSetSecurityHostdevLabel;
|
|
Daniel P. Berrange |
427ed2 |
+ virSecurityDomainSetSavedStateLabel domainSetSavedStateLabel;
|
|
Daniel P. Berrange |
427ed2 |
+ virSecurityDomainRestoreSavedStateLabel domainRestoreSavedStateLabel;
|
|
Daniel P. Berrange |
427ed2 |
|
|
Daniel P. Berrange |
427ed2 |
/*
|
|
Daniel P. Berrange |
427ed2 |
* This is internally managed driver state and should only be accessed
|
|
Daniel P. Berrange |
427ed2 |
diff --git a/src/security/security_selinux.c b/src/security/security_selinux.c
|
|
Daniel P. Berrange |
427ed2 |
index 7e0f71a..4f2d1d3 100644
|
|
Daniel P. Berrange |
427ed2 |
--- a/src/security/security_selinux.c
|
|
Daniel P. Berrange |
427ed2 |
+++ b/src/security/security_selinux.c
|
|
Daniel P. Berrange |
427ed2 |
@@ -525,6 +525,7 @@ done:
|
|
Daniel P. Berrange |
427ed2 |
return ret;
|
|
Daniel P. Berrange |
427ed2 |
}
|
|
Daniel P. Berrange |
427ed2 |
|
|
Daniel P. Berrange |
427ed2 |
+
|
|
Daniel P. Berrange |
427ed2 |
static int
|
|
Daniel P. Berrange |
427ed2 |
SELinuxRestoreSecurityPCILabel(virConnectPtr conn,
|
|
Daniel P. Berrange |
427ed2 |
pciDevice *dev ATTRIBUTE_UNUSED,
|
|
Daniel P. Berrange |
427ed2 |
@@ -625,6 +626,26 @@ SELinuxRestoreSecurityLabel(virConnectPtr conn,
|
|
Daniel P. Berrange |
427ed2 |
return rc;
|
|
Daniel P. Berrange |
427ed2 |
}
|
|
Daniel P. Berrange |
427ed2 |
|
|
Daniel P. Berrange |
427ed2 |
+
|
|
Daniel P. Berrange |
427ed2 |
+static int
|
|
Daniel P. Berrange |
427ed2 |
+SELinuxSetSavedStateLabel(virConnectPtr conn,
|
|
Daniel P. Berrange |
427ed2 |
+ virDomainObjPtr vm,
|
|
Daniel P. Berrange |
427ed2 |
+ const char *savefile)
|
|
Daniel P. Berrange |
427ed2 |
+{
|
|
Daniel P. Berrange |
427ed2 |
+ const virSecurityLabelDefPtr secdef = &vm->def->seclabel;
|
|
Daniel P. Berrange |
427ed2 |
+
|
|
Daniel P. Berrange |
427ed2 |
+ return SELinuxSetFilecon(conn, savefile, secdef->imagelabel);
|
|
Daniel P. Berrange |
427ed2 |
+}
|
|
Daniel P. Berrange |
427ed2 |
+
|
|
Daniel P. Berrange |
427ed2 |
+
|
|
Daniel P. Berrange |
427ed2 |
+static int
|
|
Daniel P. Berrange |
427ed2 |
+SELinuxRestoreSavedStateLabel(virConnectPtr conn,
|
|
Daniel P. Berrange |
427ed2 |
+ const char *savefile)
|
|
Daniel P. Berrange |
427ed2 |
+{
|
|
Daniel P. Berrange |
427ed2 |
+ return SELinuxRestoreSecurityFileLabel(conn, savefile);
|
|
Daniel P. Berrange |
427ed2 |
+}
|
|
Daniel P. Berrange |
427ed2 |
+
|
|
Daniel P. Berrange |
427ed2 |
+
|
|
Daniel P. Berrange |
427ed2 |
static int
|
|
Daniel P. Berrange |
427ed2 |
SELinuxSecurityVerify(virConnectPtr conn, virDomainDefPtr def)
|
|
Daniel P. Berrange |
427ed2 |
{
|
|
Daniel P. Berrange |
427ed2 |
@@ -694,4 +715,6 @@ virSecurityDriver virSELinuxSecurityDriver = {
|
|
Daniel P. Berrange |
427ed2 |
.domainSetSecurityLabel = SELinuxSetSecurityLabel,
|
|
Daniel P. Berrange |
427ed2 |
.domainSetSecurityHostdevLabel = SELinuxSetSecurityHostdevLabel,
|
|
Daniel P. Berrange |
427ed2 |
.domainRestoreSecurityHostdevLabel = SELinuxRestoreSecurityHostdevLabel,
|
|
Daniel P. Berrange |
427ed2 |
+ .domainSetSavedStateLabel = SELinuxSetSavedStateLabel,
|
|
Daniel P. Berrange |
427ed2 |
+ .domainRestoreSavedStateLabel = SELinuxRestoreSavedStateLabel,
|
|
Daniel P. Berrange |
427ed2 |
};
|
|
Daniel P. Berrange |
427ed2 |
--
|
|
Daniel P. Berrange |
427ed2 |
1.6.2.5
|
|
Daniel P. Berrange |
427ed2 |
|