The inspiration for this patch comes from a question on the list
asking if there's a way to not label some disks. Well, in DAC driver
there's not. Even if user have requested norelabel:
<disk type='file' device='disk'>
<driver name='qemu' type='raw'/>
<source file='/some/dummy/path/test.bin'>
<seclabel model='dac' relabel='no'/>
</source>
<target dev='vdb' bus='virtio'/>
<readonly/>
<address type='pci' domain='0x0000' bus='0x00'
slot='0x07' function='0x0'/>
</disk>
the DAC driver ignores this completely.
Signed-off-by: Michal Privoznik <mprivozn(a)redhat.com>
---
src/security/security_dac.c | 92 +++++++++++++++++++++++++++++++++++----------
1 file changed, 73 insertions(+), 19 deletions(-)
diff --git a/src/security/security_dac.c b/src/security/security_dac.c
index 8835d49..f15a0e9 100644
--- a/src/security/security_dac.c
+++ b/src/security/security_dac.c
@@ -286,7 +286,7 @@ virSecurityDACRestoreSecurityFileLabel(const char *path)
static int
-virSecurityDACSetSecurityFileLabel(virDomainDiskDefPtr disk ATTRIBUTE_UNUSED,
+virSecurityDACSetSecurityFileLabel(virDomainDiskDefPtr disk,
const char *path,
size_t depth ATTRIBUTE_UNUSED,
void *opaque)
@@ -295,11 +295,23 @@ virSecurityDACSetSecurityFileLabel(virDomainDiskDefPtr disk
ATTRIBUTE_UNUSED,
virSecurityManagerPtr mgr = cbdata->manager;
virSecurityLabelDefPtr secdef = cbdata->secdef;
virSecurityDACDataPtr priv = virSecurityManagerGetPrivateData(mgr);
+ virSecurityDeviceLabelDefPtr disk_seclabel;
uid_t user;
gid_t group;
- if (virSecurityDACGetImageIds(secdef, priv, &user, &group) < 0)
- return -1;
+ disk_seclabel = virDomainDiskDefGetSecurityLabelDef(disk,
+ SECURITY_DAC_NAME);
+
+ if (disk_seclabel && disk_seclabel->norelabel)
+ return 0;
+
+ if (disk_seclabel && disk_seclabel->label) {
+ if (virParseOwnershipIds(disk_seclabel->label, &user, &group) < 0)
+ return -1;
+ } else {
+ if (virSecurityDACGetImageIds(secdef, priv, &user, &group))
+ return -1;
+ }
return virSecurityDACSetOwnership(path, user, group);
}
@@ -323,6 +335,9 @@ virSecurityDACSetSecurityImageLabel(virSecurityManagerPtr mgr,
secdef = virDomainDefGetSecurityLabelDef(def, SECURITY_DAC_NAME);
+ if (secdef && secdef->norelabel)
+ return 0;
+
cbdata.manager = mgr;
cbdata.secdef = secdef;
return virDomainDiskDefForeachPath(disk,
@@ -339,6 +354,8 @@ virSecurityDACRestoreSecurityImageLabelInt(virSecurityManagerPtr mgr,
int migrated)
{
virSecurityDACDataPtr priv = virSecurityManagerGetPrivateData(mgr);
+ virSecurityLabelDefPtr secdef;
+ virSecurityDeviceLabelDefPtr disk_seclabel;
const char *src = virDomainDiskGetSource(disk);
if (!priv->dynamicOwnership)
@@ -347,6 +364,17 @@ virSecurityDACRestoreSecurityImageLabelInt(virSecurityManagerPtr
mgr,
if (virDomainDiskGetType(disk) == VIR_STORAGE_TYPE_NETWORK)
return 0;
+ secdef = virDomainDefGetSecurityLabelDef(def, SECURITY_DAC_NAME);
+
+ if (secdef && secdef->norelabel)
+ return 0;
+
+ disk_seclabel = virDomainDiskDefGetSecurityLabelDef(disk,
+ SECURITY_DAC_NAME);
+
+ if (disk_seclabel && disk_seclabel->norelabel)
+ return 0;
+
/* Don't restore labels on readoly/shared disks, because
* other VMs may still be accessing these
* Alternatively we could iterate over all running
@@ -454,6 +482,9 @@ virSecurityDACSetSecurityHostdevLabel(virSecurityManagerPtr mgr,
cbdata.manager = mgr;
cbdata.secdef = virDomainDefGetSecurityLabelDef(def, SECURITY_DAC_NAME);
+ if (cbdata.secdef && cbdata.secdef->norelabel)
+ return 0;
+
switch ((enum virDomainHostdevSubsysType) dev->source.subsys.type) {
case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB: {
virUSBDevicePtr usb;
@@ -564,15 +595,18 @@ virSecurityDACRestoreSecuritySCSILabel(virSCSIDevicePtr dev
ATTRIBUTE_UNUSED,
static int
virSecurityDACRestoreSecurityHostdevLabel(virSecurityManagerPtr mgr,
- virDomainDefPtr def ATTRIBUTE_UNUSED,
+ virDomainDefPtr def,
virDomainHostdevDefPtr dev,
const char *vroot)
{
virSecurityDACDataPtr priv = virSecurityManagerGetPrivateData(mgr);
+ virSecurityLabelDefPtr secdef;
int ret = -1;
- if (!priv->dynamicOwnership)
+ secdef = virDomainDefGetSecurityLabelDef(def, SECURITY_DAC_NAME);
+
+ if (!priv->dynamicOwnership || (secdef && secdef->norelabel))
return 0;
if (dev->mode != VIR_DOMAIN_HOSTDEV_MODE_SUBSYS)
@@ -674,6 +708,9 @@ virSecurityDACSetChardevLabel(virSecurityManagerPtr mgr,
chr_seclabel = virDomainChrDefGetSecurityLabelDef(dev,
SECURITY_DAC_NAME);
+ if (seclabel->norelabel || (chr_seclabel && chr_seclabel->norelabel))
+ return 0;
+
if (chr_seclabel && chr_seclabel->label) {
if (virParseOwnershipIds(chr_seclabel->label, &user, &group) < 0)
return -1;
@@ -727,27 +764,40 @@ virSecurityDACSetChardevLabel(virSecurityManagerPtr mgr,
static int
virSecurityDACRestoreChardevLabel(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
- virDomainChrSourceDefPtr dev)
+ virDomainDefPtr def,
+ virDomainChrDefPtr dev,
+ virDomainChrSourceDefPtr dev_source)
{
+ virSecurityLabelDefPtr seclabel;
+ virSecurityDeviceLabelDefPtr chr_seclabel = NULL;
char *in = NULL, *out = NULL;
int ret = -1;
- switch ((enum virDomainChrType) dev->type) {
+ seclabel = virDomainDefGetSecurityLabelDef(def, SECURITY_DAC_NAME);
+
+ if (dev)
+ chr_seclabel = virDomainChrDefGetSecurityLabelDef(dev,
+ SECURITY_DAC_NAME);
+
+ if (seclabel->norelabel || (chr_seclabel && chr_seclabel->norelabel))
+ return 0;
+
+ switch ((enum virDomainChrType) dev_source->type) {
case VIR_DOMAIN_CHR_TYPE_DEV:
case VIR_DOMAIN_CHR_TYPE_FILE:
- ret = virSecurityDACRestoreSecurityFileLabel(dev->data.file.path);
+ ret = virSecurityDACRestoreSecurityFileLabel(dev_source->data.file.path);
break;
case VIR_DOMAIN_CHR_TYPE_PIPE:
- if ((virAsprintf(&out, "%s.out", dev->data.file.path) < 0)
||
- (virAsprintf(&in, "%s.in", dev->data.file.path) < 0))
+ if ((virAsprintf(&out, "%s.out", dev_source->data.file.path)
< 0) ||
+ (virAsprintf(&in, "%s.in", dev_source->data.file.path) <
0))
goto done;
if (virFileExists(in) && virFileExists(out)) {
if ((virSecurityDACRestoreSecurityFileLabel(out) < 0) ||
(virSecurityDACRestoreSecurityFileLabel(in) < 0)) {
goto done;
}
- } else if (virSecurityDACRestoreSecurityFileLabel(dev->data.file.path) < 0)
{
+ } else if (virSecurityDACRestoreSecurityFileLabel(dev_source->data.file.path)
< 0) {
goto done;
}
ret = 0;
@@ -775,13 +825,13 @@ virSecurityDACRestoreChardevLabel(virSecurityManagerPtr mgr
ATTRIBUTE_UNUSED,
static int
-virSecurityDACRestoreChardevCallback(virDomainDefPtr def ATTRIBUTE_UNUSED,
+virSecurityDACRestoreChardevCallback(virDomainDefPtr def,
virDomainChrDefPtr dev,
void *opaque)
{
virSecurityManagerPtr mgr = opaque;
- return virSecurityDACRestoreChardevLabel(mgr, &dev->source);
+ return virSecurityDACRestoreChardevLabel(mgr, def, dev, &dev->source);
}
@@ -807,13 +857,14 @@ virSecurityDACSetSecurityTPMFileLabel(virSecurityManagerPtr mgr,
static int
virSecurityDACRestoreSecurityTPMFileLabel(virSecurityManagerPtr mgr,
+ virDomainDefPtr def,
virDomainTPMDefPtr tpm)
{
int ret = 0;
switch ((enum virDomainTPMBackendType) tpm->type) {
case VIR_DOMAIN_TPM_TYPE_PASSTHROUGH:
- ret = virSecurityDACRestoreChardevLabel(mgr,
+ ret = virSecurityDACRestoreChardevLabel(mgr, def, NULL,
&tpm->data.passthrough.source);
break;
case VIR_DOMAIN_TPM_TYPE_LAST:
@@ -830,12 +881,14 @@ virSecurityDACRestoreSecurityAllLabel(virSecurityManagerPtr mgr,
int migrated)
{
virSecurityDACDataPtr priv = virSecurityManagerGetPrivateData(mgr);
+ virSecurityLabelDefPtr secdef;
size_t i;
int rc = 0;
- if (!priv->dynamicOwnership)
- return 0;
+ secdef = virDomainDefGetSecurityLabelDef(def, SECURITY_DAC_NAME);
+ if (!priv->dynamicOwnership || (secdef && secdef->norelabel))
+ return 0;
VIR_DEBUG("Restoring security label on %s migrated=%d",
def->name, migrated);
@@ -863,6 +916,7 @@ virSecurityDACRestoreSecurityAllLabel(virSecurityManagerPtr mgr,
if (def->tpm) {
if (virSecurityDACRestoreSecurityTPMFileLabel(mgr,
+ def,
def->tpm) < 0)
rc = -1;
}
@@ -905,11 +959,11 @@ virSecurityDACSetSecurityAllLabel(virSecurityManagerPtr mgr,
uid_t user;
gid_t group;
- if (!priv->dynamicOwnership)
- return 0;
-
secdef = virDomainDefGetSecurityLabelDef(def, SECURITY_DAC_NAME);
+ if (!priv->dynamicOwnership || (secdef && secdef->norelabel))
+ return 0;
+
for (i = 0; i < def->ndisks; i++) {
/* XXX fixme - we need to recursively label the entire tree :-( */
if (virDomainDiskGetType(def->disks[i]) == VIR_STORAGE_TYPE_DIR)
--
1.9.0