* src/security_selinux.c: Use virReportSystemError whereever an
errno is involved
* src/qemu_driver.c: Don't overwrite error message from the
security driver
---
src/qemu_driver.c | 13 +++--
src/security_selinux.c | 121 ++++++++++++++++++++++++++++--------------------
2 files changed, 77 insertions(+), 57 deletions(-)
diff --git a/src/qemu_driver.c b/src/qemu_driver.c
index d75e28e..fad518c 100644
--- a/src/qemu_driver.c
+++ b/src/qemu_driver.c
@@ -1695,6 +1695,8 @@ static int qemuDomainSetHostdevUSBOwnershipActor(virConnectPtr
conn,
{
struct qemuFileOwner *owner = opaque;
+ VIR_DEBUG("Setting ownership on %s to %d:%d", file, owner->uid,
owner->gid);
+
if (chown(file, owner->uid, owner->gid) < 0) {
virReportSystemError(conn, errno, _("cannot set ownership on %s"),
file);
return -1;
@@ -1736,6 +1738,8 @@ static int qemuDomainSetHostdevPCIOwnershipActor(virConnectPtr
conn,
{
struct qemuFileOwner *owner = opaque;
+ VIR_DEBUG("Setting ownership on %s to %d:%d", file, owner->uid,
owner->gid);
+
if (chown(file, owner->uid, owner->gid) < 0) {
virReportSystemError(conn, errno, _("cannot set ownership on %s"),
file);
return -1;
@@ -1900,18 +1904,15 @@ static int qemudSecurityHook(void *data) {
if (qemuAddToCgroup(h->driver, h->vm->def) < 0)
return -1;
- if (qemudDomainSetSecurityLabel(h->conn, h->driver, h->vm) < 0) {
- qemudReportError(h->conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
- "%s", _("Failed to set security label"));
+ if (qemudDomainSetSecurityLabel(h->conn, h->driver, h->vm) < 0)
return -1;
- }
if (h->driver->privileged) {
- DEBUG("Dropping privileges of VM to %d:%d", h->driver->user,
h->driver->group);
-
if (qemuDomainSetAllDeviceOwnership(h->conn, h->driver, h->vm->def,
0) < 0)
return -1;
+ DEBUG("Dropping privileges of VM to %d:%d", h->driver->user,
h->driver->group);
+
if (h->driver->group) {
if (setregid(h->driver->group, h->driver->group) < 0) {
virReportSystemError(NULL, errno,
diff --git a/src/security_selinux.c b/src/security_selinux.c
index 5b7b038..bc295b1 100644
--- a/src/security_selinux.c
+++ b/src/security_selinux.c
@@ -106,24 +106,21 @@ SELinuxInitialize(virConnectPtr conn)
{
char *ptr = NULL;
int fd = 0;
- char ebuf[1024];
virRandomInitialize(time(NULL) ^ getpid());
fd = open(selinux_virtual_domain_context_path(), O_RDONLY);
if (fd < 0) {
- virSecurityReportError(conn, VIR_ERR_ERROR,
- _("%s: cannot open SELinux virtual domain context
file %s: %s"),
- __func__,selinux_virtual_domain_context_path(),
- virStrerror(errno, ebuf, sizeof ebuf));
+ virReportSystemError(conn, errno,
+ _("cannot open SELinux virtual domain context file
'%s'"),
+ selinux_virtual_domain_context_path());
return -1;
}
if (saferead(fd, default_domain_context, sizeof(default_domain_context)) < 0) {
- virSecurityReportError(conn, VIR_ERR_ERROR,
- _("%s: cannot read SELinux virtual domain context
file %s: %s"),
- __func__,selinux_virtual_domain_context_path(),
- virStrerror(errno, ebuf, sizeof ebuf));
+ virReportSystemError(conn, errno,
+ _("cannot read SELinux virtual domain context file
%s"),
+ selinux_virtual_domain_context_path());
close(fd);
return -1;
}
@@ -133,18 +130,16 @@ SELinuxInitialize(virConnectPtr conn)
*ptr = '\0';
if ((fd = open(selinux_virtual_image_context_path(), O_RDONLY)) < 0) {
- virSecurityReportError(conn, VIR_ERR_ERROR,
- _("%s: cannot open SELinux virtual image context file
%s: %s"),
- __func__,selinux_virtual_image_context_path(),
- virStrerror(errno, ebuf, sizeof ebuf));
+ virReportSystemError(conn, errno,
+ _("cannot open SELinux virtual image context file
%s"),
+ selinux_virtual_image_context_path());
return -1;
}
if (saferead(fd, default_image_context, sizeof(default_image_context)) < 0) {
- virSecurityReportError(conn, VIR_ERR_ERROR,
- _("%s: cannot read SELinux virtual image context file
%s: %s"),
- __func__,selinux_virtual_image_context_path(),
- virStrerror(errno, ebuf, sizeof ebuf));
+ virReportSystemError(conn, errno,
+ _("cannot read SELinux virtual image context file
%s"),
+ selinux_virtual_image_context_path());
close(fd);
return -1;
}
@@ -232,10 +227,8 @@ SELinuxReserveSecurityLabel(virConnectPtr conn,
const char *mcs;
if (getpidcon(vm->pid, &pctx) == -1) {
- char ebuf[1024];
- virSecurityReportError(conn, VIR_ERR_ERROR, _("%s: error calling "
- "getpidcon(): %s"), __func__,
- virStrerror(errno, ebuf, sizeof ebuf));
+ virReportSystemError(conn, errno,
+ _("unable to get PID %d security context"),
vm->pid);
return -1;
}
@@ -286,17 +279,16 @@ SELinuxGetSecurityLabel(virConnectPtr conn,
security_context_t ctx;
if (getpidcon(vm->pid, &ctx) == -1) {
- char ebuf[1024];
- virSecurityReportError(conn, VIR_ERR_ERROR, _("%s: error calling "
- "getpidcon(): %s"), __func__,
- virStrerror(errno, ebuf, sizeof ebuf));
+ virReportSystemError(conn, errno,
+ _("unable to get PID %d security context"),
+ vm->pid);
return -1;
}
if (strlen((char *) ctx) >= VIR_SECURITY_LABEL_BUFLEN) {
virSecurityReportError(conn, VIR_ERR_ERROR,
- _("%s: security label exceeds "
- "maximum lenth: %d"), __func__,
+ _("security label exceeds "
+ "maximum lenth: %d"),
VIR_SECURITY_LABEL_BUFLEN - 1);
return -1;
}
@@ -306,10 +298,8 @@ SELinuxGetSecurityLabel(virConnectPtr conn,
sec->enforcing = security_getenforce();
if (sec->enforcing == -1) {
- char ebuf[1024];
- virSecurityReportError(conn, VIR_ERR_ERROR, _("%s: error calling "
- "security_getenforce(): %s"), __func__,
- virStrerror(errno, ebuf, sizeof ebuf));
+ virReportSystemError(conn, errno, "%s",
+ _("error calling security_getenforce()"));
return -1;
}
@@ -319,7 +309,6 @@ SELinuxGetSecurityLabel(virConnectPtr conn,
static int
SELinuxSetFilecon(virConnectPtr conn, const char *path, char *tcon)
{
- char ebuf[1024];
security_context_t econ;
VIR_INFO("Setting SELinux context on '%s' to '%s'", path,
tcon);
@@ -343,14 +332,14 @@ SELinuxSetFilecon(virConnectPtr conn, const char *path, char *tcon)
* virt_use_{nfs,usb,pci} boolean tunables to allow it...
*/
if (setfilecon_errno != EOPNOTSUPP) {
- virSecurityReportError(conn, VIR_ERR_ERROR,
- _("%s: unable to set security context "
- "'\%s\' on %s: %s."), __func__,
- tcon,
- path,
- virStrerror(errno, ebuf, sizeof ebuf));
+ virReportSystemError(conn, setfilecon_errno,
+ _("unable to set security context '%s' on
'%s'"),
+ tcon, path);
if (security_getenforce() == 1)
return -1;
+ } else {
+ VIR_INFO("Setting security context '%s' on '%s' not
supported",
+ tcon, path);
}
}
return 0;
@@ -366,6 +355,8 @@ SELinuxRestoreSecurityFileLabel(virConnectPtr conn,
int err;
char *newpath = NULL;
+ VIR_INFO("Restoring SELinux context on '%s'", path);
+
if ((err = virFileResolveLink(path, &newpath)) < 0) {
virReportSystemError(conn, err,
_("cannot resolve symlink %s"), path);
@@ -440,6 +431,17 @@ SELinuxSetSecurityPCILabel(virConnectPtr conn,
}
static int
+SELinuxSetSecurityUSBLabel(virConnectPtr conn,
+ usbDevice *dev ATTRIBUTE_UNUSED,
+ const char *file, void *opaque)
+{
+ virDomainObjPtr vm = opaque;
+ const virSecurityLabelDefPtr secdef = &vm->def->seclabel;
+
+ return SELinuxSetFilecon(conn, file, secdef->imagelabel);
+}
+
+static int
SELinuxSetSecurityHostdevLabel(virConnectPtr conn,
virDomainObjPtr vm,
virDomainHostdevDefPtr dev)
@@ -451,8 +453,24 @@ SELinuxSetSecurityHostdevLabel(virConnectPtr conn,
return 0;
switch (dev->source.subsys.type) {
- case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB:
- break;
+ case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB: {
+ if (dev->source.subsys.u.usb.bus &&
dev->source.subsys.u.usb.device) {
+ usbDevice *usb = usbGetDevice(conn,
+ dev->source.subsys.u.usb.bus,
+ dev->source.subsys.u.usb.device);
+
+ if (!usb)
+ goto done;
+
+ ret = usbDeviceFileIterate(conn, usb, SELinuxSetSecurityUSBLabel, vm);
+ usbFreeDevice(conn, usb);
+
+ break;
+ } else {
+ /* XXX deal with product/vendor better */
+ ret = 0;
+ }
+ }
case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI: {
pciDevice *pci = pciGetDevice(conn,
@@ -554,6 +572,9 @@ SELinuxRestoreSecurityLabel(virConnectPtr conn,
const virSecurityLabelDefPtr secdef = &vm->def->seclabel;
int i;
int rc = 0;
+
+ VIR_DEBUG("Restoring security label on %s", vm->def->name);
+
if (secdef->imagelabel) {
for (i = 0 ; i < vm->def->nhostdevs ; i++) {
if (SELinuxRestoreSecurityHostdevLabel(conn, vm->def->hostdevs[i]) <
0)
@@ -597,25 +618,23 @@ SELinuxSetSecurityLabel(virConnectPtr conn,
/* TODO: verify DOI */
const virSecurityLabelDefPtr secdef = &vm->def->seclabel;
int i;
- char ebuf[1024];
if (!STREQ(drv->name, secdef->model)) {
virSecurityReportError(conn, VIR_ERR_ERROR,
- _("%s: security label driver mismatch: "
- "\'%s\' model configured for domain, but
"
- "hypervisor driver is \'%s\'."),
- __func__, secdef->model, drv->name);
+ _("security label driver mismatch: "
+ "'%s' model configured for domain, but
"
+ "hypervisor driver is '%s'."),
+ secdef->model, drv->name);
if (security_getenforce() == 1)
- return -1;
+ return -1;
}
if (setexeccon(secdef->label) == -1) {
- virSecurityReportError(conn, VIR_ERR_ERROR,
- _("%s: unable to set security context "
- "'\%s\': %s."), __func__,
secdef->label,
- virStrerror(errno, ebuf, sizeof ebuf));
+ virReportSystemError(conn, errno,
+ _("unable to set security context '%s'"),
+ secdef->label);
if (security_getenforce() == 1)
- return -1;
+ return -1;
}
if (secdef->imagelabel) {
--
1.6.2.5