mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-02-02 09:55:18 +00:00
Fix security driver calls in hotplug cleanup paths
The hotplug code was not correctly invoking the security driver in error paths. If a hotplug attempt failed, the device would be left with VM permissions applied, rather than restored to the original permissions. Also, a CDROM media that is ejected was not restored to original permissions. Finally there was a bogus call to set hostdev permissions in the hostdev unplug code * qemu/qemu_driver.c: Fix security driver usage in hotplug/unplug
This commit is contained in:
parent
b2a2ba71b4
commit
2df1657686
@ -5125,6 +5125,11 @@ static int qemudDomainChangeEjectableMedia(virConnectPtr conn,
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (driver->securityDriver &&
|
||||||
|
driver->securityDriver->domainSetSecurityImageLabel &&
|
||||||
|
driver->securityDriver->domainSetSecurityImageLabel(conn, vm, newdisk) < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
qemuDomainObjPrivatePtr priv = vm->privateData;
|
qemuDomainObjPrivatePtr priv = vm->privateData;
|
||||||
qemuDomainObjEnterMonitorWithDriver(driver, vm);
|
qemuDomainObjEnterMonitorWithDriver(driver, vm);
|
||||||
if (newdisk->src) {
|
if (newdisk->src) {
|
||||||
@ -5143,14 +5148,27 @@ static int qemudDomainChangeEjectableMedia(virConnectPtr conn,
|
|||||||
}
|
}
|
||||||
qemuDomainObjExitMonitorWithDriver(driver, vm);
|
qemuDomainObjExitMonitorWithDriver(driver, vm);
|
||||||
|
|
||||||
if (ret == 0) {
|
if (ret < 0)
|
||||||
VIR_FREE(origdisk->src);
|
goto error;
|
||||||
origdisk->src = newdisk->src;
|
|
||||||
newdisk->src = NULL;
|
if (driver->securityDriver &&
|
||||||
origdisk->type = newdisk->type;
|
driver->securityDriver->domainRestoreSecurityImageLabel &&
|
||||||
}
|
driver->securityDriver->domainRestoreSecurityImageLabel(conn, vm, origdisk) < 0)
|
||||||
|
VIR_WARN("Unable to restore security label on ejected image %s", origdisk->src);
|
||||||
|
|
||||||
|
VIR_FREE(origdisk->src);
|
||||||
|
origdisk->src = newdisk->src;
|
||||||
|
newdisk->src = NULL;
|
||||||
|
origdisk->type = newdisk->type;
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
|
error:
|
||||||
|
if (driver->securityDriver &&
|
||||||
|
driver->securityDriver->domainRestoreSecurityImageLabel &&
|
||||||
|
driver->securityDriver->domainRestoreSecurityImageLabel(conn, vm, newdisk) < 0)
|
||||||
|
VIR_WARN("Unable to restore security label on new media %s", newdisk->src);
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -5172,9 +5190,14 @@ static int qemudDomainAttachPciDiskDevice(virConnectPtr conn,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (driver->securityDriver &&
|
||||||
|
driver->securityDriver->domainSetSecurityImageLabel &&
|
||||||
|
driver->securityDriver->domainSetSecurityImageLabel(conn, vm, dev->data.disk) < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
if (VIR_REALLOC_N(vm->def->disks, vm->def->ndisks+1) < 0) {
|
if (VIR_REALLOC_N(vm->def->disks, vm->def->ndisks+1) < 0) {
|
||||||
virReportOOMError(conn);
|
virReportOOMError(conn);
|
||||||
return -1;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
qemuDomainObjEnterMonitorWithDriver(driver, vm);
|
qemuDomainObjEnterMonitorWithDriver(driver, vm);
|
||||||
@ -5184,13 +5207,22 @@ static int qemudDomainAttachPciDiskDevice(virConnectPtr conn,
|
|||||||
&guestAddr);
|
&guestAddr);
|
||||||
qemuDomainObjExitMonitorWithDriver(driver, vm);
|
qemuDomainObjExitMonitorWithDriver(driver, vm);
|
||||||
|
|
||||||
if (ret == 0) {
|
if (ret < 0)
|
||||||
dev->data.disk->info.type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI;
|
goto error;
|
||||||
memcpy(&dev->data.disk->info.addr.pci, &guestAddr, sizeof(guestAddr));
|
|
||||||
virDomainDiskInsertPreAlloced(vm->def, dev->data.disk);
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
dev->data.disk->info.type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI;
|
||||||
|
memcpy(&dev->data.disk->info.addr.pci, &guestAddr, sizeof(guestAddr));
|
||||||
|
virDomainDiskInsertPreAlloced(vm->def, dev->data.disk);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
error:
|
||||||
|
if (driver->securityDriver &&
|
||||||
|
driver->securityDriver->domainRestoreSecurityImageLabel &&
|
||||||
|
driver->securityDriver->domainRestoreSecurityImageLabel(conn, vm, dev->data.disk) < 0)
|
||||||
|
VIR_WARN("Unable to restore security label on %s", dev->data.disk->src);
|
||||||
|
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int qemudDomainAttachPciControllerDevice(virConnectPtr conn,
|
static int qemudDomainAttachPciControllerDevice(virConnectPtr conn,
|
||||||
@ -5284,15 +5316,21 @@ static int qemudDomainAttachSCSIDisk(virConnectPtr conn,
|
|||||||
if (STREQ(vm->def->disks[i]->dst, dev->dst)) {
|
if (STREQ(vm->def->disks[i]->dst, dev->dst)) {
|
||||||
qemudReportError(conn, dom, NULL, VIR_ERR_OPERATION_FAILED,
|
qemudReportError(conn, dom, NULL, VIR_ERR_OPERATION_FAILED,
|
||||||
_("target %s already exists"), dev->dst);
|
_("target %s already exists"), dev->dst);
|
||||||
goto cleanup;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (driver->securityDriver &&
|
||||||
|
driver->securityDriver->domainSetSecurityImageLabel &&
|
||||||
|
driver->securityDriver->domainSetSecurityImageLabel(conn, vm, dev) < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
/* This func allocates the bus/unit IDs so must be before
|
/* This func allocates the bus/unit IDs so must be before
|
||||||
* we search for controller
|
* we search for controller
|
||||||
*/
|
*/
|
||||||
if (!(drivestr = qemuBuildDriveStr(dev, 0, qemuCmdFlags)))
|
if (!(drivestr = qemuBuildDriveStr(dev, 0, qemuCmdFlags)))
|
||||||
goto cleanup;
|
goto error;
|
||||||
|
|
||||||
|
|
||||||
/* We should have an adddress now, so make sure */
|
/* We should have an adddress now, so make sure */
|
||||||
@ -5300,24 +5338,24 @@ static int qemudDomainAttachSCSIDisk(virConnectPtr conn,
|
|||||||
qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
|
qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
|
||||||
_("unexpected disk address type %s"),
|
_("unexpected disk address type %s"),
|
||||||
virDomainDeviceAddressTypeToString(dev->info.type));
|
virDomainDeviceAddressTypeToString(dev->info.type));
|
||||||
goto cleanup;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0 ; i < dev->info.addr.drive.controller ; i++) {
|
for (i = 0 ; i < dev->info.addr.drive.controller ; i++) {
|
||||||
cont = qemuDomainFindOrCreateSCSIDiskController(conn, driver, vm, i);
|
cont = qemuDomainFindOrCreateSCSIDiskController(conn, driver, vm, i);
|
||||||
if (!cont)
|
if (!cont)
|
||||||
goto cleanup;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cont->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI) {
|
if (cont->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI) {
|
||||||
qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
|
qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
|
||||||
_("SCSI controller %d was missing its PCI address"), cont->idx);
|
_("SCSI controller %d was missing its PCI address"), cont->idx);
|
||||||
goto cleanup;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (VIR_REALLOC_N(vm->def->disks, vm->def->ndisks+1) < 0) {
|
if (VIR_REALLOC_N(vm->def->disks, vm->def->ndisks+1) < 0) {
|
||||||
virReportOOMError(conn);
|
virReportOOMError(conn);
|
||||||
goto cleanup;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
qemuDomainObjEnterMonitorWithDriver(driver, vm);
|
qemuDomainObjEnterMonitorWithDriver(driver, vm);
|
||||||
@ -5325,20 +5363,28 @@ static int qemudDomainAttachSCSIDisk(virConnectPtr conn,
|
|||||||
drivestr,
|
drivestr,
|
||||||
&cont->info.addr.pci,
|
&cont->info.addr.pci,
|
||||||
&driveAddr);
|
&driveAddr);
|
||||||
|
|
||||||
qemuDomainObjExitMonitorWithDriver(driver, vm);
|
qemuDomainObjExitMonitorWithDriver(driver, vm);
|
||||||
|
|
||||||
if (ret == 0) {
|
if (ret < 0)
|
||||||
/* XXX we should probably validate that the addr matches
|
goto error;
|
||||||
* our existing defined addr instead of overwriting */
|
|
||||||
dev->info.type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_DRIVE;
|
|
||||||
memcpy(&dev->info.addr.drive, &driveAddr, sizeof(driveAddr));
|
|
||||||
virDomainDiskInsertPreAlloced(vm->def, dev);
|
|
||||||
}
|
|
||||||
|
|
||||||
cleanup:
|
/* XXX we should probably validate that the addr matches
|
||||||
|
* our existing defined addr instead of overwriting */
|
||||||
|
dev->info.type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_DRIVE;
|
||||||
|
memcpy(&dev->info.addr.drive, &driveAddr, sizeof(driveAddr));
|
||||||
|
virDomainDiskInsertPreAlloced(vm->def, dev);
|
||||||
VIR_FREE(drivestr);
|
VIR_FREE(drivestr);
|
||||||
return ret;
|
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
error:
|
||||||
|
VIR_FREE(drivestr);
|
||||||
|
if (driver->securityDriver &&
|
||||||
|
driver->securityDriver->domainRestoreSecurityImageLabel &&
|
||||||
|
driver->securityDriver->domainRestoreSecurityImageLabel(conn, vm, dev) < 0)
|
||||||
|
VIR_WARN("Unable to restore security label on %s", dev->src);
|
||||||
|
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -5358,27 +5404,43 @@ static int qemudDomainAttachUsbMassstorageDevice(virConnectPtr conn,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (driver->securityDriver &&
|
||||||
|
driver->securityDriver->domainSetSecurityImageLabel &&
|
||||||
|
driver->securityDriver->domainSetSecurityImageLabel(conn, vm, dev->data.disk) < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
if (!dev->data.disk->src) {
|
if (!dev->data.disk->src) {
|
||||||
qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
|
qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
|
||||||
"%s", _("disk source path is missing"));
|
"%s", _("disk source path is missing"));
|
||||||
return -1;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (VIR_REALLOC_N(vm->def->disks, vm->def->ndisks+1) < 0) {
|
if (VIR_REALLOC_N(vm->def->disks, vm->def->ndisks+1) < 0) {
|
||||||
virReportOOMError(conn);
|
virReportOOMError(conn);
|
||||||
return -1;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
qemuDomainObjEnterMonitorWithDriver(driver, vm);
|
qemuDomainObjEnterMonitorWithDriver(driver, vm);
|
||||||
ret = qemuMonitorAddUSBDisk(priv->mon, dev->data.disk->src);
|
ret = qemuMonitorAddUSBDisk(priv->mon, dev->data.disk->src);
|
||||||
qemuDomainObjExitMonitorWithDriver(driver, vm);
|
qemuDomainObjExitMonitorWithDriver(driver, vm);
|
||||||
|
|
||||||
if (ret == 0)
|
if (ret < 0)
|
||||||
virDomainDiskInsertPreAlloced(vm->def, dev->data.disk);
|
goto error;
|
||||||
|
|
||||||
return ret;
|
virDomainDiskInsertPreAlloced(vm->def, dev->data.disk);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
error:
|
||||||
|
if (driver->securityDriver &&
|
||||||
|
driver->securityDriver->domainRestoreSecurityImageLabel &&
|
||||||
|
driver->securityDriver->domainRestoreSecurityImageLabel(conn, vm, dev->data.disk) < 0)
|
||||||
|
VIR_WARN("Unable to restore security label on %s", dev->data.disk->src);
|
||||||
|
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int qemudDomainAttachNetDevice(virConnectPtr conn,
|
static int qemudDomainAttachNetDevice(virConnectPtr conn,
|
||||||
struct qemud_driver *driver,
|
struct qemud_driver *driver,
|
||||||
virDomainObjPtr vm,
|
virDomainObjPtr vm,
|
||||||
@ -5617,15 +5679,31 @@ static int qemudDomainAttachHostDevice(virConnectPtr conn,
|
|||||||
|
|
||||||
switch (hostdev->source.subsys.type) {
|
switch (hostdev->source.subsys.type) {
|
||||||
case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI:
|
case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI:
|
||||||
return qemudDomainAttachHostPciDevice(conn, driver, vm, dev);
|
if (qemudDomainAttachHostPciDevice(conn, driver, vm, dev) < 0)
|
||||||
|
goto error;
|
||||||
|
break;
|
||||||
|
|
||||||
case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB:
|
case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB:
|
||||||
return qemudDomainAttachHostUsbDevice(conn, driver, vm, dev);
|
if (qemudDomainAttachHostUsbDevice(conn, driver, vm, dev) < 0)
|
||||||
|
goto error;
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
qemudReportError(conn, dom, NULL, VIR_ERR_NO_SUPPORT,
|
qemudReportError(conn, dom, NULL, VIR_ERR_NO_SUPPORT,
|
||||||
_("hostdev subsys type '%s' not supported"),
|
_("hostdev subsys type '%s' not supported"),
|
||||||
virDomainHostdevSubsysTypeToString(hostdev->source.subsys.type));
|
virDomainHostdevSubsysTypeToString(hostdev->source.subsys.type));
|
||||||
return -1;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
error:
|
||||||
|
if (driver->securityDriver &&
|
||||||
|
driver->securityDriver->domainRestoreSecurityHostdevLabel &&
|
||||||
|
driver->securityDriver->domainRestoreSecurityHostdevLabel(conn, vm, dev->data.hostdev) < 0)
|
||||||
|
VIR_WARN0("Unable to restore host device labelling on hotplug fail");
|
||||||
|
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int qemudDomainAttachDevice(virDomainPtr dom,
|
static int qemudDomainAttachDevice(virDomainPtr dom,
|
||||||
@ -5688,18 +5766,10 @@ static int qemudDomainAttachDevice(virDomainPtr dom,
|
|||||||
switch (dev->data.disk->device) {
|
switch (dev->data.disk->device) {
|
||||||
case VIR_DOMAIN_DISK_DEVICE_CDROM:
|
case VIR_DOMAIN_DISK_DEVICE_CDROM:
|
||||||
case VIR_DOMAIN_DISK_DEVICE_FLOPPY:
|
case VIR_DOMAIN_DISK_DEVICE_FLOPPY:
|
||||||
if (driver->securityDriver &&
|
|
||||||
driver->securityDriver->domainSetSecurityImageLabel)
|
|
||||||
driver->securityDriver->domainSetSecurityImageLabel(dom->conn, vm, dev->data.disk);
|
|
||||||
|
|
||||||
ret = qemudDomainChangeEjectableMedia(dom->conn, driver, vm, dev);
|
ret = qemudDomainChangeEjectableMedia(dom->conn, driver, vm, dev);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case VIR_DOMAIN_DISK_DEVICE_DISK:
|
case VIR_DOMAIN_DISK_DEVICE_DISK:
|
||||||
if (driver->securityDriver &&
|
|
||||||
driver->securityDriver->domainSetSecurityImageLabel)
|
|
||||||
driver->securityDriver->domainSetSecurityImageLabel(dom->conn, vm, dev->data.disk);
|
|
||||||
|
|
||||||
if (dev->data.disk->bus == VIR_DOMAIN_DISK_BUS_USB) {
|
if (dev->data.disk->bus == VIR_DOMAIN_DISK_BUS_USB) {
|
||||||
ret = qemudDomainAttachUsbMassstorageDevice(dom->conn, driver, vm, dev);
|
ret = qemudDomainAttachUsbMassstorageDevice(dom->conn, driver, vm, dev);
|
||||||
} else if (dev->data.disk->bus == VIR_DOMAIN_DISK_BUS_VIRTIO) {
|
} else if (dev->data.disk->bus == VIR_DOMAIN_DISK_BUS_VIRTIO) {
|
||||||
@ -5815,6 +5885,11 @@ static int qemudDomainDetachPciDiskDevice(virConnectPtr conn,
|
|||||||
}
|
}
|
||||||
virDomainDiskDefFree(detach);
|
virDomainDiskDefFree(detach);
|
||||||
|
|
||||||
|
if (driver->securityDriver &&
|
||||||
|
driver->securityDriver->domainRestoreSecurityImageLabel &&
|
||||||
|
driver->securityDriver->domainRestoreSecurityImageLabel(conn, vm, dev->data.disk) < 0)
|
||||||
|
VIR_WARN("Unable to restore security label on %s", dev->data.disk->src);
|
||||||
|
|
||||||
ret = 0;
|
ret = 0;
|
||||||
|
|
||||||
cleanup:
|
cleanup:
|
||||||
@ -6081,9 +6156,9 @@ static int qemudDomainDetachHostDevice(virConnectPtr conn,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (driver->securityDriver &&
|
if (driver->securityDriver &&
|
||||||
driver->securityDriver->domainSetSecurityHostdevLabel &&
|
driver->securityDriver->domainRestoreSecurityHostdevLabel &&
|
||||||
driver->securityDriver->domainSetSecurityHostdevLabel(conn, vm, dev->data.hostdev) < 0)
|
driver->securityDriver->domainRestoreSecurityHostdevLabel(conn, vm, dev->data.hostdev) < 0)
|
||||||
VIR_WARN0("Failed to restore device labelling");
|
VIR_WARN0("Failed to restore host device labelling");
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@ -6124,9 +6199,6 @@ static int qemudDomainDetachDevice(virDomainPtr dom,
|
|||||||
dev->data.disk->device == VIR_DOMAIN_DISK_DEVICE_DISK &&
|
dev->data.disk->device == VIR_DOMAIN_DISK_DEVICE_DISK &&
|
||||||
dev->data.disk->bus == VIR_DOMAIN_DISK_BUS_VIRTIO) {
|
dev->data.disk->bus == VIR_DOMAIN_DISK_BUS_VIRTIO) {
|
||||||
ret = qemudDomainDetachPciDiskDevice(dom->conn, driver, vm, dev);
|
ret = qemudDomainDetachPciDiskDevice(dom->conn, driver, vm, dev);
|
||||||
if (driver->securityDriver &&
|
|
||||||
driver->securityDriver->domainRestoreSecurityImageLabel)
|
|
||||||
driver->securityDriver->domainRestoreSecurityImageLabel(dom->conn, vm, dev->data.disk);
|
|
||||||
} else if (dev->type == VIR_DOMAIN_DEVICE_NET) {
|
} else if (dev->type == VIR_DOMAIN_DEVICE_NET) {
|
||||||
ret = qemudDomainDetachNetDevice(dom->conn, driver, vm, dev);
|
ret = qemudDomainDetachNetDevice(dom->conn, driver, vm, dev);
|
||||||
} else if (dev->type == VIR_DOMAIN_DEVICE_CONTROLLER) {
|
} else if (dev->type == VIR_DOMAIN_DEVICE_CONTROLLER) {
|
||||||
@ -6140,9 +6212,6 @@ static int qemudDomainDetachDevice(virDomainPtr dom,
|
|||||||
}
|
}
|
||||||
} else if (dev->type == VIR_DOMAIN_DEVICE_HOSTDEV) {
|
} else if (dev->type == VIR_DOMAIN_DEVICE_HOSTDEV) {
|
||||||
ret = qemudDomainDetachHostDevice(dom->conn, driver, vm, dev);
|
ret = qemudDomainDetachHostDevice(dom->conn, driver, vm, dev);
|
||||||
if (driver->securityDriver &&
|
|
||||||
driver->securityDriver->domainRestoreSecurityHostdevLabel)
|
|
||||||
driver->securityDriver->domainRestoreSecurityHostdevLabel(dom->conn, vm, dev->data.hostdev);
|
|
||||||
} else {
|
} else {
|
||||||
qemudReportError(dom->conn, dom, NULL, VIR_ERR_NO_SUPPORT,
|
qemudReportError(dom->conn, dom, NULL, VIR_ERR_NO_SUPPORT,
|
||||||
"%s", _("This type of device cannot be hot unplugged"));
|
"%s", _("This type of device cannot be hot unplugged"));
|
||||||
|
Loading…
x
Reference in New Issue
Block a user