From c86afc85ee0d1ec6d76c2d254ba0730427360280 Mon Sep 17 00:00:00 2001 From: "Daniel P. Berrange" Date: Tue, 17 Mar 2009 11:35:40 +0000 Subject: [PATCH] Fix labelling of shared/readonly devices (Dan Walsh) --- ChangeLog | 8 ++++++ src/qemu_driver.c | 4 +-- src/security.h | 5 ++-- src/security_selinux.c | 62 +++++++++++++++++++++++++++--------------- 4 files changed, 52 insertions(+), 27 deletions(-) diff --git a/ChangeLog b/ChangeLog index ffa6b0cd7a..f8223c5322 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +Tue Mar 17 11:35:58 GMT 2009 Daniel P. Berrange + + Fix labelling of shared/readonly devices (Dan Walsh) + * src/qemu_driver.c, src/security.h: Disk label commands + take virDomainDiskDefPtr instead of virDomainDefPtr + * src/security_selinux.c: Do not relabel shared or readonly + disk images with MCS label. + Tue Mar 17 11:58:58 CET 2009 Daniel Veillard * src/remote_internal.c: remove file descriptors leak diff --git a/src/qemu_driver.c b/src/qemu_driver.c index fb04834f87..afec99c666 100644 --- a/src/qemu_driver.c +++ b/src/qemu_driver.c @@ -3766,7 +3766,7 @@ static int qemudDomainAttachDevice(virDomainPtr dom, goto cleanup; } if (driver->securityDriver) - driver->securityDriver->domainSetSecurityImageLabel(dom->conn, vm, dev); + driver->securityDriver->domainSetSecurityImageLabel(dom->conn, vm, dev->data.disk); break; default: @@ -3902,7 +3902,7 @@ static int qemudDomainDetachDevice(virDomainPtr dom, dev->data.disk->bus == VIR_DOMAIN_DISK_BUS_VIRTIO)) { ret = qemudDomainDetachPciDiskDevice(dom->conn, vm, dev); if (driver->securityDriver) - driver->securityDriver->domainRestoreSecurityImageLabel(dom->conn, vm, dev); + driver->securityDriver->domainRestoreSecurityImageLabel(dom->conn, dev->data.disk); } else qemudReportError(dom->conn, dom, NULL, VIR_ERR_NO_SUPPORT, diff --git a/src/security.h b/src/security.h index ac8d690dcc..8cc2c17fe9 100644 --- a/src/security.h +++ b/src/security.h @@ -32,11 +32,10 @@ typedef virSecurityDriverStatus (*virSecurityDriverProbe) (void); typedef int (*virSecurityDriverOpen) (virConnectPtr conn, virSecurityDriverPtr drv); typedef int (*virSecurityDomainRestoreImageLabel) (virConnectPtr conn, - virDomainObjPtr vm, - virDomainDeviceDefPtr dev); + virDomainDiskDefPtr disk); typedef int (*virSecurityDomainSetImageLabel) (virConnectPtr conn, virDomainObjPtr vm, - virDomainDeviceDefPtr dev); + virDomainDiskDefPtr disk); typedef int (*virSecurityDomainGenLabel) (virConnectPtr conn, virDomainObjPtr sec); typedef int (*virSecurityDomainGetLabel) (virConnectPtr conn, diff --git a/src/security_selinux.c b/src/security_selinux.c index 9e6a442482..1708d55082 100644 --- a/src/security_selinux.c +++ b/src/security_selinux.c @@ -269,7 +269,7 @@ SELinuxGetSecurityLabel(virConnectPtr conn, } static int -SELinuxSetFilecon(virConnectPtr conn, char *path, char *tcon) +SELinuxSetFilecon(virConnectPtr conn, const char *path, char *tcon) { char ebuf[1024]; @@ -288,28 +288,51 @@ SELinuxSetFilecon(virConnectPtr conn, char *path, char *tcon) static int SELinuxRestoreSecurityImageLabel(virConnectPtr conn, - virDomainObjPtr vm, - virDomainDeviceDefPtr dev) + virDomainDiskDefPtr disk) { - const virSecurityLabelDefPtr secdef = &vm->def->seclabel; + struct stat buf; + security_context_t fcon = NULL; + int rc = -1; + char *newpath = NULL; + const char *path = disk->src; - if (secdef->imagelabel) { - return SELinuxSetFilecon(conn, dev->data.disk->src, default_image_context); + if (disk->readonly || disk->shared) + return 0; + + if (lstat(path, &buf) != 0) + return -1; + + if (S_ISLNK(buf.st_mode)) { + if (VIR_ALLOC_N(newpath, buf.st_size + 1) < 0) + return -1; + + if (readlink(path, newpath, buf.st_size) < 0) + goto err; + path = newpath; + if (stat(path, &buf) != 0) + goto err; } - return 0; + + if (matchpathcon(path, buf.st_mode, &fcon) == 0) { + rc = SELinuxSetFilecon(conn, path, fcon); + } +err: + VIR_FREE(fcon); + VIR_FREE(newpath); + return rc; } static int SELinuxSetSecurityImageLabel(virConnectPtr conn, virDomainObjPtr vm, - virDomainDeviceDefPtr dev) + virDomainDiskDefPtr disk) { const virSecurityLabelDefPtr secdef = &vm->def->seclabel; - if (secdef->imagelabel) { - return SELinuxSetFilecon(conn, dev->data.disk->src, secdef->imagelabel); - } + if (secdef->imagelabel) + return SELinuxSetFilecon(conn, disk->src, secdef->imagelabel); + return 0; } @@ -322,7 +345,7 @@ SELinuxRestoreSecurityLabel(virConnectPtr conn, int rc = 0; if (secdef->imagelabel) { for (i = 0 ; i < vm->def->ndisks ; i++) { - if (SELinuxSetFilecon(conn, vm->def->disks[i]->src, default_image_context) < 0) + if (SELinuxRestoreSecurityImageLabel(conn, vm->def->disks[i]) < 0) rc = -1; } VIR_FREE(secdef->model); @@ -368,16 +391,11 @@ SELinuxSetSecurityLabel(virConnectPtr conn, if (secdef->imagelabel) { for (i = 0 ; i < vm->def->ndisks ; i++) { - if(setfilecon(vm->def->disks[i]->src, secdef->imagelabel) < 0) { - virSecurityReportError(conn, VIR_ERR_ERROR, - _("%s: unable to set security context " - "'\%s\' on %s: %s."), __func__, - secdef->imagelabel, - vm->def->disks[i]->src, - virStrerror(errno, ebuf, sizeof ebuf)); - if (security_getenforce() == 1) - return -1; - } + if (vm->def->disks[i]->readonly || + vm->def->disks[i]->shared) continue; + + if (SELinuxSetSecurityImageLabel(conn, vm, vm->def->disks[i]) < 0) + return -1; } } -- GitLab