In the case that virtlogd is used as stdio handler we pass to QEMU
only FD to a PIPE connected to virtlogd instead of the file itself.
Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1430988
Signed-off-by: Pavel Hrdina <phrdina@redhat.com>
---
Notes:
new in v2
src/lxc/lxc_process.c | 6 ++---
src/qemu/qemu_security.c | 9 +++++--
src/security/security_apparmor.c | 7 ++++--
src/security/security_dac.c | 54 +++++++++++++++++++++++++++++++---------
src/security/security_driver.h | 6 +++--
src/security/security_manager.c | 12 ++++++---
src/security/security_manager.h | 6 +++--
src/security/security_nop.c | 6 +++--
src/security/security_selinux.c | 53 ++++++++++++++++++++++++++++++---------
src/security/security_stack.c | 12 ++++++---
tests/securityselinuxlabeltest.c | 2 +-
11 files changed, 127 insertions(+), 46 deletions(-)
diff --git a/src/lxc/lxc_process.c b/src/lxc/lxc_process.c
index d8727c3b43..2658ea61f8 100644
--- a/src/lxc/lxc_process.c
+++ b/src/lxc/lxc_process.c
@@ -852,7 +852,7 @@ int virLXCProcessStop(virLXCDriverPtr driver,
}
virSecurityManagerRestoreAllLabel(driver->securityManager,
- vm->def, false);
+ vm->def, false, false);
virSecurityManagerReleaseLabel(driver->securityManager, vm->def);
/* Clear out dynamically assigned labels */
if (vm->def->nseclabels &&
@@ -1349,7 +1349,7 @@ int virLXCProcessStart(virConnectPtr conn,
VIR_DEBUG("Setting domain security labels");
if (virSecurityManagerSetAllLabel(driver->securityManager,
- vm->def, NULL) < 0)
+ vm->def, NULL, false) < 0)
goto cleanup;
VIR_DEBUG("Setting up consoles");
@@ -1578,7 +1578,7 @@ int virLXCProcessStart(virConnectPtr conn,
virLXCProcessStop(driver, vm, VIR_DOMAIN_SHUTOFF_FAILED);
} else {
virSecurityManagerRestoreAllLabel(driver->securityManager,
- vm->def, false);
+ vm->def, false, false);
virSecurityManagerReleaseLabel(driver->securityManager, vm->def);
/* Clear out dynamically assigned labels */
if (vm->def->nseclabels &&
diff --git a/src/qemu/qemu_security.c b/src/qemu/qemu_security.c
index 61934f9905..6fc3b0bb6e 100644
--- a/src/qemu/qemu_security.c
+++ b/src/qemu/qemu_security.c
@@ -38,6 +38,7 @@ qemuSecuritySetAllLabel(virQEMUDriverPtr driver,
const char *stdin_path)
{
int ret = -1;
+ qemuDomainObjPrivatePtr priv = vm->privateData;
if (qemuDomainNamespaceEnabled(vm, QEMU_DOMAIN_NS_MOUNT) &&
virSecurityManagerTransactionStart(driver->securityManager) < 0)
@@ -45,7 +46,8 @@ qemuSecuritySetAllLabel(virQEMUDriverPtr driver,
if (virSecurityManagerSetAllLabel(driver->securityManager,
vm->def,
- stdin_path) < 0)
+ stdin_path,
+ priv->chardevStdioLogd) < 0)
goto cleanup;
if (qemuDomainNamespaceEnabled(vm, QEMU_DOMAIN_NS_MOUNT) &&
@@ -65,6 +67,8 @@ qemuSecurityRestoreAllLabel(virQEMUDriverPtr driver,
virDomainObjPtr vm,
bool migrated)
{
+ qemuDomainObjPrivatePtr priv = vm->privateData;
+
/* In contrast to qemuSecuritySetAllLabel, do not use
* secdriver transactions here. This function is called from
* qemuProcessStop() which is meant to do cleanup after qemu
@@ -73,7 +77,8 @@ qemuSecurityRestoreAllLabel(virQEMUDriverPtr driver,
* in entering the namespace then. */
virSecurityManagerRestoreAllLabel(driver->securityManager,
vm->def,
- migrated);
+ migrated,
+ priv->chardevStdioLogd);
}
diff --git a/src/security/security_apparmor.c b/src/security/security_apparmor.c
index 62672b0af0..5afe0c5c85 100644
--- a/src/security/security_apparmor.c
+++ b/src/security/security_apparmor.c
@@ -489,7 +489,9 @@ AppArmorGenSecurityLabel(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
static int
AppArmorSetSecurityAllLabel(virSecurityManagerPtr mgr,
- virDomainDefPtr def, const char *stdin_path)
+ virDomainDefPtr def,
+ const char *stdin_path,
+ bool chardevStdioLogd ATTRIBUTE_UNUSED)
{
virSecurityLabelDefPtr secdef = virDomainDefGetSecurityLabelDef(def,
SECURITY_APPARMOR_NAME);
@@ -567,7 +569,8 @@ AppArmorReleaseSecurityLabel(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
static int
AppArmorRestoreSecurityAllLabel(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
virDomainDefPtr def,
- bool migrated ATTRIBUTE_UNUSED)
+ bool migrated ATTRIBUTE_UNUSED,
+ bool chardevStdioLogd ATTRIBUTE_UNUSED)
{
int rc = 0;
virSecurityLabelDefPtr secdef =
diff --git a/src/security/security_dac.c b/src/security/security_dac.c
index fd4d8f5047..79941f480a 100644
--- a/src/security/security_dac.c
+++ b/src/security/security_dac.c
@@ -1159,7 +1159,8 @@ virSecurityDACRestoreHostdevLabel(virSecurityManagerPtr mgr,
static int
virSecurityDACSetChardevLabel(virSecurityManagerPtr mgr,
virDomainDefPtr def,
- virDomainChrSourceDefPtr dev_source)
+ virDomainChrSourceDefPtr dev_source,
+ bool chardevStdioLogd)
{
virSecurityDACDataPtr priv = virSecurityManagerGetPrivateData(mgr);
@@ -1178,6 +1179,9 @@ virSecurityDACSetChardevLabel(virSecurityManagerPtr mgr,
if (chr_seclabel && !chr_seclabel->relabel)
return 0;
+ if (!chr_seclabel && chardevStdioLogd)
+ return 0;
+
if (chr_seclabel && chr_seclabel->label) {
if (virParseOwnershipIds(chr_seclabel->label, &user, &group) < 0)
return -1;
@@ -1243,7 +1247,8 @@ virSecurityDACSetChardevLabel(virSecurityManagerPtr mgr,
static int
virSecurityDACRestoreChardevLabel(virSecurityManagerPtr mgr,
virDomainDefPtr def ATTRIBUTE_UNUSED,
- virDomainChrSourceDefPtr dev_source)
+ virDomainChrSourceDefPtr dev_source,
+ bool chardevStdioLogd)
{
virSecurityDACDataPtr priv = virSecurityManagerGetPrivateData(mgr);
virSecurityDeviceLabelDefPtr chr_seclabel = NULL;
@@ -1256,6 +1261,9 @@ virSecurityDACRestoreChardevLabel(virSecurityManagerPtr mgr,
if (chr_seclabel && !chr_seclabel->relabel)
return 0;
+ if (!chr_seclabel && chardevStdioLogd)
+ return 0;
+
switch ((virDomainChrType) dev_source->type) {
case VIR_DOMAIN_CHR_TYPE_DEV:
case VIR_DOMAIN_CHR_TYPE_FILE:
@@ -1298,14 +1306,21 @@ virSecurityDACRestoreChardevLabel(virSecurityManagerPtr mgr,
}
+struct _virSecuritySELinuxChardevCallbackData {
+ virSecurityManagerPtr mgr;
+ bool chardevStdioLogd;
+};
+
+
static int
virSecurityDACRestoreChardevCallback(virDomainDefPtr def,
virDomainChrDefPtr dev ATTRIBUTE_UNUSED,
void *opaque)
{
- virSecurityManagerPtr mgr = opaque;
+ struct _virSecuritySELinuxChardevCallbackData *data = opaque;
- return virSecurityDACRestoreChardevLabel(mgr, def, dev->source);
+ return virSecurityDACRestoreChardevLabel(data->mgr, def, dev->source,
+ data->chardevStdioLogd);
}
@@ -1319,7 +1334,8 @@ virSecurityDACSetTPMFileLabel(virSecurityManagerPtr mgr,
switch (tpm->type) {
case VIR_DOMAIN_TPM_TYPE_PASSTHROUGH:
ret = virSecurityDACSetChardevLabel(mgr, def,
- &tpm->data.passthrough.source);
+ &tpm->data.passthrough.source,
+ false);
break;
case VIR_DOMAIN_TPM_TYPE_LAST:
break;
@@ -1339,7 +1355,8 @@ virSecurityDACRestoreTPMFileLabel(virSecurityManagerPtr mgr,
switch (tpm->type) {
case VIR_DOMAIN_TPM_TYPE_PASSTHROUGH:
ret = virSecurityDACRestoreChardevLabel(mgr, def,
- &tpm->data.passthrough.source);
+ &tpm->data.passthrough.source,
+ false);
break;
case VIR_DOMAIN_TPM_TYPE_LAST:
break;
@@ -1436,7 +1453,8 @@ virSecurityDACRestoreMemoryLabel(virSecurityManagerPtr mgr,
static int
virSecurityDACRestoreAllLabel(virSecurityManagerPtr mgr,
virDomainDefPtr def,
- bool migrated)
+ bool migrated,
+ bool chardevStdioLogd)
{
virSecurityDACDataPtr priv = virSecurityManagerGetPrivateData(mgr);
virSecurityLabelDefPtr secdef;
@@ -1479,10 +1497,15 @@ virSecurityDACRestoreAllLabel(virSecurityManagerPtr mgr,
rc = -1;
}
+ struct _virSecuritySELinuxChardevCallbackData chardevData = {
+ .mgr = mgr,
+ .chardevStdioLogd = chardevStdioLogd,
+ };
+
if (virDomainChrDefForeach(def,
false,
virSecurityDACRestoreChardevCallback,
- mgr) < 0)
+ &chardevData) < 0)
rc = -1;
if (def->tpm) {
@@ -1505,9 +1528,10 @@ virSecurityDACSetChardevCallback(virDomainDefPtr def,
virDomainChrDefPtr dev ATTRIBUTE_UNUSED,
void *opaque)
{
- virSecurityManagerPtr mgr = opaque;
+ struct _virSecuritySELinuxChardevCallbackData *data = opaque;
- return virSecurityDACSetChardevLabel(mgr, def, dev->source);
+ return virSecurityDACSetChardevLabel(data->mgr, def, dev->source,
+ data->chardevStdioLogd);
}
@@ -1549,7 +1573,8 @@ virSecurityDACSetMemoryLabel(virSecurityManagerPtr mgr,
static int
virSecurityDACSetAllLabel(virSecurityManagerPtr mgr,
virDomainDefPtr def,
- const char *stdin_path ATTRIBUTE_UNUSED)
+ const char *stdin_path ATTRIBUTE_UNUSED,
+ bool chardevStdioLogd)
{
virSecurityDACDataPtr priv = virSecurityManagerGetPrivateData(mgr);
virSecurityLabelDefPtr secdef;
@@ -1592,10 +1617,15 @@ virSecurityDACSetAllLabel(virSecurityManagerPtr mgr,
return -1;
}
+ struct _virSecuritySELinuxChardevCallbackData chardevData = {
+ .mgr = mgr,
+ .chardevStdioLogd = chardevStdioLogd,
+ };
+
if (virDomainChrDefForeach(def,
true,
virSecurityDACSetChardevCallback,
- mgr) < 0)
+ &chardevData) < 0)
return -1;
if (def->tpm) {
diff --git a/src/security/security_driver.h b/src/security/security_driver.h
index 0f5cce5f8d..0b3b452486 100644
--- a/src/security/security_driver.h
+++ b/src/security/security_driver.h
@@ -91,10 +91,12 @@ typedef int (*virSecurityDomainReleaseLabel) (virSecurityManagerPtr mgr,
virDomainDefPtr sec);
typedef int (*virSecurityDomainSetAllLabel) (virSecurityManagerPtr mgr,
virDomainDefPtr sec,
- const char *stdin_path);
+ const char *stdin_path,
+ bool chardevStdioLogd);
typedef int (*virSecurityDomainRestoreAllLabel) (virSecurityManagerPtr mgr,
virDomainDefPtr def,
- bool migrated);
+ bool migrated,
+ bool chardevStdioLogd);
typedef int (*virSecurityDomainGetProcessLabel) (virSecurityManagerPtr mgr,
virDomainDefPtr def,
pid_t pid,
diff --git a/src/security/security_manager.c b/src/security/security_manager.c
index 90d491c1bc..013bbc37ef 100644
--- a/src/security/security_manager.c
+++ b/src/security/security_manager.c
@@ -856,12 +856,14 @@ int virSecurityManagerCheckAllLabel(virSecurityManagerPtr mgr,
int
virSecurityManagerSetAllLabel(virSecurityManagerPtr mgr,
virDomainDefPtr vm,
- const char *stdin_path)
+ const char *stdin_path,
+ bool chardevStdioLogd)
{
if (mgr->drv->domainSetSecurityAllLabel) {
int ret;
virObjectLock(mgr);
- ret = mgr->drv->domainSetSecurityAllLabel(mgr, vm, stdin_path);
+ ret = mgr->drv->domainSetSecurityAllLabel(mgr, vm, stdin_path,
+ chardevStdioLogd);
virObjectUnlock(mgr);
return ret;
}
@@ -874,12 +876,14 @@ virSecurityManagerSetAllLabel(virSecurityManagerPtr mgr,
int
virSecurityManagerRestoreAllLabel(virSecurityManagerPtr mgr,
virDomainDefPtr vm,
- bool migrated)
+ bool migrated,
+ bool chardevStdioLogd)
{
if (mgr->drv->domainRestoreSecurityAllLabel) {
int ret;
virObjectLock(mgr);
- ret = mgr->drv->domainRestoreSecurityAllLabel(mgr, vm, migrated);
+ ret = mgr->drv->domainRestoreSecurityAllLabel(mgr, vm, migrated,
+ chardevStdioLogd);
virObjectUnlock(mgr);
return ret;
}
diff --git a/src/security/security_manager.h b/src/security/security_manager.h
index 238e66cd0b..01296d339e 100644
--- a/src/security/security_manager.h
+++ b/src/security/security_manager.h
@@ -130,10 +130,12 @@ int virSecurityManagerCheckAllLabel(virSecurityManagerPtr mgr,
virDomainDefPtr sec);
int virSecurityManagerSetAllLabel(virSecurityManagerPtr mgr,
virDomainDefPtr sec,
- const char *stdin_path);
+ const char *stdin_path,
+ bool chardevStdioLogd);
int virSecurityManagerRestoreAllLabel(virSecurityManagerPtr mgr,
virDomainDefPtr def,
- bool migrated);
+ bool migrated,
+ bool chardevStdioLogd);
int virSecurityManagerGetProcessLabel(virSecurityManagerPtr mgr,
virDomainDefPtr def,
pid_t pid,
diff --git a/src/security/security_nop.c b/src/security/security_nop.c
index 0a9b515288..527be11e5a 100644
--- a/src/security/security_nop.c
+++ b/src/security/security_nop.c
@@ -151,7 +151,8 @@ virSecurityDomainReleaseLabelNop(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
static int
virSecurityDomainSetAllLabelNop(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
virDomainDefPtr sec ATTRIBUTE_UNUSED,
- const char *stdin_path ATTRIBUTE_UNUSED)
+ const char *stdin_path ATTRIBUTE_UNUSED,
+ bool chardevStdioLogd ATTRIBUTE_UNUSED)
{
return 0;
}
@@ -159,7 +160,8 @@ virSecurityDomainSetAllLabelNop(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
static int
virSecurityDomainRestoreAllLabelNop(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
virDomainDefPtr vm ATTRIBUTE_UNUSED,
- bool migrated ATTRIBUTE_UNUSED)
+ bool migrated ATTRIBUTE_UNUSED,
+ bool chardevStdioLogd ATTRIBUTE_UNUSED)
{
return 0;
}
diff --git a/src/security/security_selinux.c b/src/security/security_selinux.c
index 75f387b3fa..26137f6d8d 100644
--- a/src/security/security_selinux.c
+++ b/src/security/security_selinux.c
@@ -2179,7 +2179,8 @@ virSecuritySELinuxRestoreHostdevLabel(virSecurityManagerPtr mgr,
static int
virSecuritySELinuxSetChardevLabel(virSecurityManagerPtr mgr,
virDomainDefPtr def,
- virDomainChrSourceDefPtr dev_source)
+ virDomainChrSourceDefPtr dev_source,
+ bool chardevStdioLogd)
{
virSecurityLabelDefPtr seclabel;
@@ -2198,6 +2199,9 @@ virSecuritySELinuxSetChardevLabel(virSecurityManagerPtr mgr,
if (chr_seclabel && !chr_seclabel->relabel)
return 0;
+ if (!chr_seclabel && chardevStdioLogd)
+ return 0;
+
if (chr_seclabel)
imagelabel = chr_seclabel->label;
if (!imagelabel)
@@ -2252,7 +2256,8 @@ virSecuritySELinuxSetChardevLabel(virSecurityManagerPtr mgr,
static int
virSecuritySELinuxRestoreChardevLabel(virSecurityManagerPtr mgr,
virDomainDefPtr def,
- virDomainChrSourceDefPtr dev_source)
+ virDomainChrSourceDefPtr dev_source,
+ bool chardevStdioLogd)
{
virSecurityLabelDefPtr seclabel;
@@ -2269,6 +2274,9 @@ virSecuritySELinuxRestoreChardevLabel(virSecurityManagerPtr mgr,
if (chr_seclabel && !chr_seclabel->relabel)
return 0;
+ if (!chr_seclabel && chardevStdioLogd)
+ return 0;
+
switch (dev_source->type) {
case VIR_DOMAIN_CHR_TYPE_DEV:
case VIR_DOMAIN_CHR_TYPE_FILE:
@@ -2312,14 +2320,21 @@ virSecuritySELinuxRestoreChardevLabel(virSecurityManagerPtr mgr,
}
+struct _virSecuritySELinuxChardevCallbackData {
+ virSecurityManagerPtr mgr;
+ bool chardevStdioLogd;
+};
+
+
static int
virSecuritySELinuxRestoreSecurityChardevCallback(virDomainDefPtr def,
virDomainChrDefPtr dev ATTRIBUTE_UNUSED,
void *opaque)
{
- virSecurityManagerPtr mgr = opaque;
+ struct _virSecuritySELinuxChardevCallbackData *data = opaque;
- return virSecuritySELinuxRestoreChardevLabel(mgr, def, dev->source);
+ return virSecuritySELinuxRestoreChardevLabel(data->mgr, def, dev->source,
+ data->chardevStdioLogd);
}
@@ -2342,7 +2357,8 @@ virSecuritySELinuxRestoreSecuritySmartcardCallback(virDomainDefPtr def,
return virSecuritySELinuxRestoreFileLabel(mgr, database);
case VIR_DOMAIN_SMARTCARD_TYPE_PASSTHROUGH:
- return virSecuritySELinuxRestoreChardevLabel(mgr, def, dev->data.passthru);
+ return virSecuritySELinuxRestoreChardevLabel(mgr, def,
+ dev->data.passthru, false);
default:
virReportError(VIR_ERR_INTERNAL_ERROR,
@@ -2369,7 +2385,8 @@ virSecuritySELinuxGetBaseLabel(virSecurityManagerPtr mgr, int virtType)
static int
virSecuritySELinuxRestoreAllLabel(virSecurityManagerPtr mgr,
virDomainDefPtr def,
- bool migrated)
+ bool migrated,
+ bool chardevStdioLogd)
{
virSecurityLabelDefPtr secdef;
virSecuritySELinuxDataPtr data = virSecurityManagerGetPrivateData(mgr);
@@ -2414,10 +2431,15 @@ virSecuritySELinuxRestoreAllLabel(virSecurityManagerPtr mgr,
rc = -1;
}
+ struct _virSecuritySELinuxChardevCallbackData chardevData = {
+ .mgr = mgr,
+ .chardevStdioLogd = chardevStdioLogd
+ };
+
if (virDomainChrDefForeach(def,
false,
virSecuritySELinuxRestoreSecurityChardevCallback,
- mgr) < 0)
+ &chardevData) < 0)
rc = -1;
if (virDomainSmartcardDefForeach(def,
@@ -2706,9 +2728,10 @@ virSecuritySELinuxSetSecurityChardevCallback(virDomainDefPtr def,
virDomainChrDefPtr dev ATTRIBUTE_UNUSED,
void *opaque)
{
- virSecurityManagerPtr mgr = opaque;
+ struct _virSecuritySELinuxChardevCallbackData *data = opaque;
- return virSecuritySELinuxSetChardevLabel(mgr, def, dev->source);
+ return virSecuritySELinuxSetChardevLabel(data->mgr, def, dev->source,
+ data->chardevStdioLogd);
}
@@ -2733,7 +2756,7 @@ virSecuritySELinuxSetSecuritySmartcardCallback(virDomainDefPtr def,
case VIR_DOMAIN_SMARTCARD_TYPE_PASSTHROUGH:
return virSecuritySELinuxSetChardevLabel(mgr, def,
- dev->data.passthru);
+ dev->data.passthru, false);
default:
virReportError(VIR_ERR_INTERNAL_ERROR,
@@ -2749,7 +2772,8 @@ virSecuritySELinuxSetSecuritySmartcardCallback(virDomainDefPtr def,
static int
virSecuritySELinuxSetAllLabel(virSecurityManagerPtr mgr,
virDomainDefPtr def,
- const char *stdin_path)
+ const char *stdin_path,
+ bool chardevStdioLogd)
{
size_t i;
virSecuritySELinuxDataPtr data = virSecurityManagerGetPrivateData(mgr);
@@ -2797,10 +2821,15 @@ virSecuritySELinuxSetAllLabel(virSecurityManagerPtr mgr,
return -1;
}
+ struct _virSecuritySELinuxChardevCallbackData chardevData = {
+ .mgr = mgr,
+ .chardevStdioLogd = chardevStdioLogd
+ };
+
if (virDomainChrDefForeach(def,
true,
virSecuritySELinuxSetSecurityChardevCallback,
- mgr) < 0)
+ &chardevData) < 0)
return -1;
if (virDomainSmartcardDefForeach(def,
diff --git a/src/security/security_stack.c b/src/security/security_stack.c
index 9a1a7b30c5..53eee1692f 100644
--- a/src/security/security_stack.c
+++ b/src/security/security_stack.c
@@ -350,14 +350,16 @@ virSecurityStackRestoreHostdevLabel(virSecurityManagerPtr mgr,
static int
virSecurityStackSetAllLabel(virSecurityManagerPtr mgr,
virDomainDefPtr vm,
- const char *stdin_path)
+ const char *stdin_path,
+ bool chardevStdioLogd)
{
virSecurityStackDataPtr priv = virSecurityManagerGetPrivateData(mgr);
virSecurityStackItemPtr item = priv->itemsHead;
int rc = 0;
for (; item; item = item->next) {
- if (virSecurityManagerSetAllLabel(item->securityManager, vm, stdin_path) < 0)
+ if (virSecurityManagerSetAllLabel(item->securityManager, vm,
+ stdin_path, chardevStdioLogd) < 0)
rc = -1;
}
@@ -368,14 +370,16 @@ virSecurityStackSetAllLabel(virSecurityManagerPtr mgr,
static int
virSecurityStackRestoreAllLabel(virSecurityManagerPtr mgr,
virDomainDefPtr vm,
- bool migrated)
+ bool migrated,
+ bool chardevStdioLogd)
{
virSecurityStackDataPtr priv = virSecurityManagerGetPrivateData(mgr);
virSecurityStackItemPtr item = priv->itemsHead;
int rc = 0;
for (; item; item = item->next) {
- if (virSecurityManagerRestoreAllLabel(item->securityManager, vm, migrated) < 0)
+ if (virSecurityManagerRestoreAllLabel(item->securityManager, vm,
+ migrated, chardevStdioLogd) < 0)
rc = -1;
}
diff --git a/tests/securityselinuxlabeltest.c b/tests/securityselinuxlabeltest.c
index 3e134991f2..ddcc954429 100644
--- a/tests/securityselinuxlabeltest.c
+++ b/tests/securityselinuxlabeltest.c
@@ -313,7 +313,7 @@ testSELinuxLabeling(const void *opaque)
if (!(def = testSELinuxLoadDef(testname)))
goto cleanup;
- if (virSecurityManagerSetAllLabel(mgr, def, NULL) < 0)
+ if (virSecurityManagerSetAllLabel(mgr, def, NULL, false) < 0)
goto cleanup;
if (testSELinuxCheckLabels(files, nfiles) < 0)
--
2.13.0
--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list
On 05/29/2017 10:31 AM, Pavel Hrdina wrote:
> In the case that virtlogd is used as stdio handler we pass to QEMU
> only FD to a PIPE connected to virtlogd instead of the file itself.
>
> Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1430988
>
> Signed-off-by: Pavel Hrdina <phrdina@redhat.com>
> ---
>
> Notes:
> new in v2
>
> src/lxc/lxc_process.c | 6 ++---
> src/qemu/qemu_security.c | 9 +++++--
> src/security/security_apparmor.c | 7 ++++--
> src/security/security_dac.c | 54 +++++++++++++++++++++++++++++++---------
> src/security/security_driver.h | 6 +++--
> src/security/security_manager.c | 12 ++++++---
> src/security/security_manager.h | 6 +++--
> src/security/security_nop.c | 6 +++--
> src/security/security_selinux.c | 53 ++++++++++++++++++++++++++++++---------
> src/security/security_stack.c | 12 ++++++---
> tests/securityselinuxlabeltest.c | 2 +-
> 11 files changed, 127 insertions(+), 46 deletions(-)
>
Why is it a (!chr_seclabel && chardevStdioLogd)? More to the point why
is (!chr_seclabel) even matter?
IIUC, whether or not someone set the label for the chardev, for this
particular issue/config where the chardev has a <log file=$path>, we
don't want to set (or restore) the label. I feel like I'm missing
something subtle. Maybe a bit more explanation of the adjustment would
help me...
Wouldn't these changes end up selecting "any" chardev if
chardevStdioLogd ended up being set regardless of whether they were
actually using the log file?
As an aside, I think there's an "oddity" when it comes to the Restore,
but I'm not sure how to put it into words exactly. If a guest is running
code prior to this set of changes, would it have successfully run a Set?
If so, then after applying this change and restarting, the label
wouldn't be reset, right? What happens at guest shutdown - does the
label not get unset now? Of course this is all "interaction" with
virtlogd restart that really throws a monkey wrench into things.
Also, why is the Smartcard chardev handling not using this
John
> diff --git a/src/lxc/lxc_process.c b/src/lxc/lxc_process.c
> index d8727c3b43..2658ea61f8 100644
> --- a/src/lxc/lxc_process.c
> +++ b/src/lxc/lxc_process.c
> @@ -852,7 +852,7 @@ int virLXCProcessStop(virLXCDriverPtr driver,
> }
>
> virSecurityManagerRestoreAllLabel(driver->securityManager,
> - vm->def, false);
> + vm->def, false, false);
> virSecurityManagerReleaseLabel(driver->securityManager, vm->def);
> /* Clear out dynamically assigned labels */
> if (vm->def->nseclabels &&
> @@ -1349,7 +1349,7 @@ int virLXCProcessStart(virConnectPtr conn,
>
> VIR_DEBUG("Setting domain security labels");
> if (virSecurityManagerSetAllLabel(driver->securityManager,
> - vm->def, NULL) < 0)
> + vm->def, NULL, false) < 0)
> goto cleanup;
>
> VIR_DEBUG("Setting up consoles");
> @@ -1578,7 +1578,7 @@ int virLXCProcessStart(virConnectPtr conn,
> virLXCProcessStop(driver, vm, VIR_DOMAIN_SHUTOFF_FAILED);
> } else {
> virSecurityManagerRestoreAllLabel(driver->securityManager,
> - vm->def, false);
> + vm->def, false, false);
> virSecurityManagerReleaseLabel(driver->securityManager, vm->def);
> /* Clear out dynamically assigned labels */
> if (vm->def->nseclabels &&
> diff --git a/src/qemu/qemu_security.c b/src/qemu/qemu_security.c
> index 61934f9905..6fc3b0bb6e 100644
> --- a/src/qemu/qemu_security.c
> +++ b/src/qemu/qemu_security.c
> @@ -38,6 +38,7 @@ qemuSecuritySetAllLabel(virQEMUDriverPtr driver,
> const char *stdin_path)
> {
> int ret = -1;
> + qemuDomainObjPrivatePtr priv = vm->privateData;
>
> if (qemuDomainNamespaceEnabled(vm, QEMU_DOMAIN_NS_MOUNT) &&
> virSecurityManagerTransactionStart(driver->securityManager) < 0)
> @@ -45,7 +46,8 @@ qemuSecuritySetAllLabel(virQEMUDriverPtr driver,
>
> if (virSecurityManagerSetAllLabel(driver->securityManager,
> vm->def,
> - stdin_path) < 0)
> + stdin_path,
> + priv->chardevStdioLogd) < 0)
> goto cleanup;
>
> if (qemuDomainNamespaceEnabled(vm, QEMU_DOMAIN_NS_MOUNT) &&
> @@ -65,6 +67,8 @@ qemuSecurityRestoreAllLabel(virQEMUDriverPtr driver,
> virDomainObjPtr vm,
> bool migrated)
> {
> + qemuDomainObjPrivatePtr priv = vm->privateData;
> +
> /* In contrast to qemuSecuritySetAllLabel, do not use
> * secdriver transactions here. This function is called from
> * qemuProcessStop() which is meant to do cleanup after qemu
> @@ -73,7 +77,8 @@ qemuSecurityRestoreAllLabel(virQEMUDriverPtr driver,
> * in entering the namespace then. */
> virSecurityManagerRestoreAllLabel(driver->securityManager,
> vm->def,
> - migrated);
> + migrated,
> + priv->chardevStdioLogd);
> }
>
>
> diff --git a/src/security/security_apparmor.c b/src/security/security_apparmor.c
> index 62672b0af0..5afe0c5c85 100644
> --- a/src/security/security_apparmor.c
> +++ b/src/security/security_apparmor.c
> @@ -489,7 +489,9 @@ AppArmorGenSecurityLabel(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
>
> static int
> AppArmorSetSecurityAllLabel(virSecurityManagerPtr mgr,
> - virDomainDefPtr def, const char *stdin_path)
> + virDomainDefPtr def,
> + const char *stdin_path,
> + bool chardevStdioLogd ATTRIBUTE_UNUSED)
> {
> virSecurityLabelDefPtr secdef = virDomainDefGetSecurityLabelDef(def,
> SECURITY_APPARMOR_NAME);
> @@ -567,7 +569,8 @@ AppArmorReleaseSecurityLabel(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
> static int
> AppArmorRestoreSecurityAllLabel(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
> virDomainDefPtr def,
> - bool migrated ATTRIBUTE_UNUSED)
> + bool migrated ATTRIBUTE_UNUSED,
> + bool chardevStdioLogd ATTRIBUTE_UNUSED)
> {
> int rc = 0;
> virSecurityLabelDefPtr secdef =
> diff --git a/src/security/security_dac.c b/src/security/security_dac.c
> index fd4d8f5047..79941f480a 100644
> --- a/src/security/security_dac.c
> +++ b/src/security/security_dac.c
> @@ -1159,7 +1159,8 @@ virSecurityDACRestoreHostdevLabel(virSecurityManagerPtr mgr,
> static int
> virSecurityDACSetChardevLabel(virSecurityManagerPtr mgr,
> virDomainDefPtr def,
> - virDomainChrSourceDefPtr dev_source)
> + virDomainChrSourceDefPtr dev_source,
> + bool chardevStdioLogd)
>
> {
> virSecurityDACDataPtr priv = virSecurityManagerGetPrivateData(mgr);
> @@ -1178,6 +1179,9 @@ virSecurityDACSetChardevLabel(virSecurityManagerPtr mgr,
> if (chr_seclabel && !chr_seclabel->relabel)
> return 0;
>
> + if (!chr_seclabel && chardevStdioLogd)
> + return 0;
> +
> if (chr_seclabel && chr_seclabel->label) {
> if (virParseOwnershipIds(chr_seclabel->label, &user, &group) < 0)
> return -1;
> @@ -1243,7 +1247,8 @@ virSecurityDACSetChardevLabel(virSecurityManagerPtr mgr,
> static int
> virSecurityDACRestoreChardevLabel(virSecurityManagerPtr mgr,
> virDomainDefPtr def ATTRIBUTE_UNUSED,
> - virDomainChrSourceDefPtr dev_source)
> + virDomainChrSourceDefPtr dev_source,
> + bool chardevStdioLogd)
> {
> virSecurityDACDataPtr priv = virSecurityManagerGetPrivateData(mgr);
> virSecurityDeviceLabelDefPtr chr_seclabel = NULL;
> @@ -1256,6 +1261,9 @@ virSecurityDACRestoreChardevLabel(virSecurityManagerPtr mgr,
> if (chr_seclabel && !chr_seclabel->relabel)
> return 0;
>
> + if (!chr_seclabel && chardevStdioLogd)
> + return 0;
> +
> switch ((virDomainChrType) dev_source->type) {
> case VIR_DOMAIN_CHR_TYPE_DEV:
> case VIR_DOMAIN_CHR_TYPE_FILE:
> @@ -1298,14 +1306,21 @@ virSecurityDACRestoreChardevLabel(virSecurityManagerPtr mgr,
> }
>
>
> +struct _virSecuritySELinuxChardevCallbackData {
> + virSecurityManagerPtr mgr;
> + bool chardevStdioLogd;
> +};
> +
> +
> static int
> virSecurityDACRestoreChardevCallback(virDomainDefPtr def,
> virDomainChrDefPtr dev ATTRIBUTE_UNUSED,
> void *opaque)
> {
> - virSecurityManagerPtr mgr = opaque;
> + struct _virSecuritySELinuxChardevCallbackData *data = opaque;
>
> - return virSecurityDACRestoreChardevLabel(mgr, def, dev->source);
> + return virSecurityDACRestoreChardevLabel(data->mgr, def, dev->source,
> + data->chardevStdioLogd);
> }
>
>
> @@ -1319,7 +1334,8 @@ virSecurityDACSetTPMFileLabel(virSecurityManagerPtr mgr,
> switch (tpm->type) {
> case VIR_DOMAIN_TPM_TYPE_PASSTHROUGH:
> ret = virSecurityDACSetChardevLabel(mgr, def,
> - &tpm->data.passthrough.source);
> + &tpm->data.passthrough.source,
> + false);
> break;
> case VIR_DOMAIN_TPM_TYPE_LAST:
> break;
> @@ -1339,7 +1355,8 @@ virSecurityDACRestoreTPMFileLabel(virSecurityManagerPtr mgr,
> switch (tpm->type) {
> case VIR_DOMAIN_TPM_TYPE_PASSTHROUGH:
> ret = virSecurityDACRestoreChardevLabel(mgr, def,
> - &tpm->data.passthrough.source);
> + &tpm->data.passthrough.source,
> + false);
> break;
> case VIR_DOMAIN_TPM_TYPE_LAST:
> break;
> @@ -1436,7 +1453,8 @@ virSecurityDACRestoreMemoryLabel(virSecurityManagerPtr mgr,
> static int
> virSecurityDACRestoreAllLabel(virSecurityManagerPtr mgr,
> virDomainDefPtr def,
> - bool migrated)
> + bool migrated,
> + bool chardevStdioLogd)
> {
> virSecurityDACDataPtr priv = virSecurityManagerGetPrivateData(mgr);
> virSecurityLabelDefPtr secdef;
> @@ -1479,10 +1497,15 @@ virSecurityDACRestoreAllLabel(virSecurityManagerPtr mgr,
> rc = -1;
> }
>
> + struct _virSecuritySELinuxChardevCallbackData chardevData = {
> + .mgr = mgr,
> + .chardevStdioLogd = chardevStdioLogd,
> + };
> +
> if (virDomainChrDefForeach(def,
> false,
> virSecurityDACRestoreChardevCallback,
> - mgr) < 0)
> + &chardevData) < 0)
> rc = -1;
>
> if (def->tpm) {
> @@ -1505,9 +1528,10 @@ virSecurityDACSetChardevCallback(virDomainDefPtr def,
> virDomainChrDefPtr dev ATTRIBUTE_UNUSED,
> void *opaque)
> {
> - virSecurityManagerPtr mgr = opaque;
> + struct _virSecuritySELinuxChardevCallbackData *data = opaque;
>
> - return virSecurityDACSetChardevLabel(mgr, def, dev->source);
> + return virSecurityDACSetChardevLabel(data->mgr, def, dev->source,
> + data->chardevStdioLogd);
> }
>
>
> @@ -1549,7 +1573,8 @@ virSecurityDACSetMemoryLabel(virSecurityManagerPtr mgr,
> static int
> virSecurityDACSetAllLabel(virSecurityManagerPtr mgr,
> virDomainDefPtr def,
> - const char *stdin_path ATTRIBUTE_UNUSED)
> + const char *stdin_path ATTRIBUTE_UNUSED,
> + bool chardevStdioLogd)
> {
> virSecurityDACDataPtr priv = virSecurityManagerGetPrivateData(mgr);
> virSecurityLabelDefPtr secdef;
> @@ -1592,10 +1617,15 @@ virSecurityDACSetAllLabel(virSecurityManagerPtr mgr,
> return -1;
> }
>
> + struct _virSecuritySELinuxChardevCallbackData chardevData = {
> + .mgr = mgr,
> + .chardevStdioLogd = chardevStdioLogd,
> + };
> +
> if (virDomainChrDefForeach(def,
> true,
> virSecurityDACSetChardevCallback,
> - mgr) < 0)
> + &chardevData) < 0)
> return -1;
>
> if (def->tpm) {
> diff --git a/src/security/security_driver.h b/src/security/security_driver.h
> index 0f5cce5f8d..0b3b452486 100644
> --- a/src/security/security_driver.h
> +++ b/src/security/security_driver.h
> @@ -91,10 +91,12 @@ typedef int (*virSecurityDomainReleaseLabel) (virSecurityManagerPtr mgr,
> virDomainDefPtr sec);
> typedef int (*virSecurityDomainSetAllLabel) (virSecurityManagerPtr mgr,
> virDomainDefPtr sec,
> - const char *stdin_path);
> + const char *stdin_path,
> + bool chardevStdioLogd);
> typedef int (*virSecurityDomainRestoreAllLabel) (virSecurityManagerPtr mgr,
> virDomainDefPtr def,
> - bool migrated);
> + bool migrated,
> + bool chardevStdioLogd);
> typedef int (*virSecurityDomainGetProcessLabel) (virSecurityManagerPtr mgr,
> virDomainDefPtr def,
> pid_t pid,
> diff --git a/src/security/security_manager.c b/src/security/security_manager.c
> index 90d491c1bc..013bbc37ef 100644
> --- a/src/security/security_manager.c
> +++ b/src/security/security_manager.c
> @@ -856,12 +856,14 @@ int virSecurityManagerCheckAllLabel(virSecurityManagerPtr mgr,
> int
> virSecurityManagerSetAllLabel(virSecurityManagerPtr mgr,
> virDomainDefPtr vm,
> - const char *stdin_path)
> + const char *stdin_path,
> + bool chardevStdioLogd)
> {
> if (mgr->drv->domainSetSecurityAllLabel) {
> int ret;
> virObjectLock(mgr);
> - ret = mgr->drv->domainSetSecurityAllLabel(mgr, vm, stdin_path);
> + ret = mgr->drv->domainSetSecurityAllLabel(mgr, vm, stdin_path,
> + chardevStdioLogd);
> virObjectUnlock(mgr);
> return ret;
> }
> @@ -874,12 +876,14 @@ virSecurityManagerSetAllLabel(virSecurityManagerPtr mgr,
> int
> virSecurityManagerRestoreAllLabel(virSecurityManagerPtr mgr,
> virDomainDefPtr vm,
> - bool migrated)
> + bool migrated,
> + bool chardevStdioLogd)
> {
> if (mgr->drv->domainRestoreSecurityAllLabel) {
> int ret;
> virObjectLock(mgr);
> - ret = mgr->drv->domainRestoreSecurityAllLabel(mgr, vm, migrated);
> + ret = mgr->drv->domainRestoreSecurityAllLabel(mgr, vm, migrated,
> + chardevStdioLogd);
> virObjectUnlock(mgr);
> return ret;
> }
> diff --git a/src/security/security_manager.h b/src/security/security_manager.h
> index 238e66cd0b..01296d339e 100644
> --- a/src/security/security_manager.h
> +++ b/src/security/security_manager.h
> @@ -130,10 +130,12 @@ int virSecurityManagerCheckAllLabel(virSecurityManagerPtr mgr,
> virDomainDefPtr sec);
> int virSecurityManagerSetAllLabel(virSecurityManagerPtr mgr,
> virDomainDefPtr sec,
> - const char *stdin_path);
> + const char *stdin_path,
> + bool chardevStdioLogd);
> int virSecurityManagerRestoreAllLabel(virSecurityManagerPtr mgr,
> virDomainDefPtr def,
> - bool migrated);
> + bool migrated,
> + bool chardevStdioLogd);
> int virSecurityManagerGetProcessLabel(virSecurityManagerPtr mgr,
> virDomainDefPtr def,
> pid_t pid,
> diff --git a/src/security/security_nop.c b/src/security/security_nop.c
> index 0a9b515288..527be11e5a 100644
> --- a/src/security/security_nop.c
> +++ b/src/security/security_nop.c
> @@ -151,7 +151,8 @@ virSecurityDomainReleaseLabelNop(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
> static int
> virSecurityDomainSetAllLabelNop(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
> virDomainDefPtr sec ATTRIBUTE_UNUSED,
> - const char *stdin_path ATTRIBUTE_UNUSED)
> + const char *stdin_path ATTRIBUTE_UNUSED,
> + bool chardevStdioLogd ATTRIBUTE_UNUSED)
> {
> return 0;
> }
> @@ -159,7 +160,8 @@ virSecurityDomainSetAllLabelNop(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
> static int
> virSecurityDomainRestoreAllLabelNop(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
> virDomainDefPtr vm ATTRIBUTE_UNUSED,
> - bool migrated ATTRIBUTE_UNUSED)
> + bool migrated ATTRIBUTE_UNUSED,
> + bool chardevStdioLogd ATTRIBUTE_UNUSED)
> {
> return 0;
> }
> diff --git a/src/security/security_selinux.c b/src/security/security_selinux.c
> index 75f387b3fa..26137f6d8d 100644
> --- a/src/security/security_selinux.c
> +++ b/src/security/security_selinux.c
> @@ -2179,7 +2179,8 @@ virSecuritySELinuxRestoreHostdevLabel(virSecurityManagerPtr mgr,
> static int
> virSecuritySELinuxSetChardevLabel(virSecurityManagerPtr mgr,
> virDomainDefPtr def,
> - virDomainChrSourceDefPtr dev_source)
> + virDomainChrSourceDefPtr dev_source,
> + bool chardevStdioLogd)
>
> {
> virSecurityLabelDefPtr seclabel;
> @@ -2198,6 +2199,9 @@ virSecuritySELinuxSetChardevLabel(virSecurityManagerPtr mgr,
> if (chr_seclabel && !chr_seclabel->relabel)
> return 0;
>
> + if (!chr_seclabel && chardevStdioLogd)
> + return 0;
> +
> if (chr_seclabel)
> imagelabel = chr_seclabel->label;
> if (!imagelabel)
> @@ -2252,7 +2256,8 @@ virSecuritySELinuxSetChardevLabel(virSecurityManagerPtr mgr,
> static int
> virSecuritySELinuxRestoreChardevLabel(virSecurityManagerPtr mgr,
> virDomainDefPtr def,
> - virDomainChrSourceDefPtr dev_source)
> + virDomainChrSourceDefPtr dev_source,
> + bool chardevStdioLogd)
>
> {
> virSecurityLabelDefPtr seclabel;
> @@ -2269,6 +2274,9 @@ virSecuritySELinuxRestoreChardevLabel(virSecurityManagerPtr mgr,
> if (chr_seclabel && !chr_seclabel->relabel)
> return 0;
>
> + if (!chr_seclabel && chardevStdioLogd)
> + return 0;
> +
> switch (dev_source->type) {
> case VIR_DOMAIN_CHR_TYPE_DEV:
> case VIR_DOMAIN_CHR_TYPE_FILE:
> @@ -2312,14 +2320,21 @@ virSecuritySELinuxRestoreChardevLabel(virSecurityManagerPtr mgr,
> }
>
>
> +struct _virSecuritySELinuxChardevCallbackData {
> + virSecurityManagerPtr mgr;
> + bool chardevStdioLogd;
> +};
> +
> +
> static int
> virSecuritySELinuxRestoreSecurityChardevCallback(virDomainDefPtr def,
> virDomainChrDefPtr dev ATTRIBUTE_UNUSED,
> void *opaque)
> {
> - virSecurityManagerPtr mgr = opaque;
> + struct _virSecuritySELinuxChardevCallbackData *data = opaque;
>
> - return virSecuritySELinuxRestoreChardevLabel(mgr, def, dev->source);
> + return virSecuritySELinuxRestoreChardevLabel(data->mgr, def, dev->source,
> + data->chardevStdioLogd);
> }
>
>
> @@ -2342,7 +2357,8 @@ virSecuritySELinuxRestoreSecuritySmartcardCallback(virDomainDefPtr def,
> return virSecuritySELinuxRestoreFileLabel(mgr, database);
>
> case VIR_DOMAIN_SMARTCARD_TYPE_PASSTHROUGH:
> - return virSecuritySELinuxRestoreChardevLabel(mgr, def, dev->data.passthru);
> + return virSecuritySELinuxRestoreChardevLabel(mgr, def,
> + dev->data.passthru, false);
>
> default:
> virReportError(VIR_ERR_INTERNAL_ERROR,
> @@ -2369,7 +2385,8 @@ virSecuritySELinuxGetBaseLabel(virSecurityManagerPtr mgr, int virtType)
> static int
> virSecuritySELinuxRestoreAllLabel(virSecurityManagerPtr mgr,
> virDomainDefPtr def,
> - bool migrated)
> + bool migrated,
> + bool chardevStdioLogd)
> {
> virSecurityLabelDefPtr secdef;
> virSecuritySELinuxDataPtr data = virSecurityManagerGetPrivateData(mgr);
> @@ -2414,10 +2431,15 @@ virSecuritySELinuxRestoreAllLabel(virSecurityManagerPtr mgr,
> rc = -1;
> }
>
> + struct _virSecuritySELinuxChardevCallbackData chardevData = {
> + .mgr = mgr,
> + .chardevStdioLogd = chardevStdioLogd
> + };
> +
> if (virDomainChrDefForeach(def,
> false,
> virSecuritySELinuxRestoreSecurityChardevCallback,
> - mgr) < 0)
> + &chardevData) < 0)
> rc = -1;
>
> if (virDomainSmartcardDefForeach(def,
> @@ -2706,9 +2728,10 @@ virSecuritySELinuxSetSecurityChardevCallback(virDomainDefPtr def,
> virDomainChrDefPtr dev ATTRIBUTE_UNUSED,
> void *opaque)
> {
> - virSecurityManagerPtr mgr = opaque;
> + struct _virSecuritySELinuxChardevCallbackData *data = opaque;
>
> - return virSecuritySELinuxSetChardevLabel(mgr, def, dev->source);
> + return virSecuritySELinuxSetChardevLabel(data->mgr, def, dev->source,
> + data->chardevStdioLogd);
> }
>
>
> @@ -2733,7 +2756,7 @@ virSecuritySELinuxSetSecuritySmartcardCallback(virDomainDefPtr def,
>
> case VIR_DOMAIN_SMARTCARD_TYPE_PASSTHROUGH:
> return virSecuritySELinuxSetChardevLabel(mgr, def,
> - dev->data.passthru);
> + dev->data.passthru, false);
>
> default:
> virReportError(VIR_ERR_INTERNAL_ERROR,
> @@ -2749,7 +2772,8 @@ virSecuritySELinuxSetSecuritySmartcardCallback(virDomainDefPtr def,
> static int
> virSecuritySELinuxSetAllLabel(virSecurityManagerPtr mgr,
> virDomainDefPtr def,
> - const char *stdin_path)
> + const char *stdin_path,
> + bool chardevStdioLogd)
> {
> size_t i;
> virSecuritySELinuxDataPtr data = virSecurityManagerGetPrivateData(mgr);
> @@ -2797,10 +2821,15 @@ virSecuritySELinuxSetAllLabel(virSecurityManagerPtr mgr,
> return -1;
> }
>
> + struct _virSecuritySELinuxChardevCallbackData chardevData = {
> + .mgr = mgr,
> + .chardevStdioLogd = chardevStdioLogd
> + };
> +
> if (virDomainChrDefForeach(def,
> true,
> virSecuritySELinuxSetSecurityChardevCallback,
> - mgr) < 0)
> + &chardevData) < 0)
> return -1;
>
> if (virDomainSmartcardDefForeach(def,
> diff --git a/src/security/security_stack.c b/src/security/security_stack.c
> index 9a1a7b30c5..53eee1692f 100644
> --- a/src/security/security_stack.c
> +++ b/src/security/security_stack.c
> @@ -350,14 +350,16 @@ virSecurityStackRestoreHostdevLabel(virSecurityManagerPtr mgr,
> static int
> virSecurityStackSetAllLabel(virSecurityManagerPtr mgr,
> virDomainDefPtr vm,
> - const char *stdin_path)
> + const char *stdin_path,
> + bool chardevStdioLogd)
> {
> virSecurityStackDataPtr priv = virSecurityManagerGetPrivateData(mgr);
> virSecurityStackItemPtr item = priv->itemsHead;
> int rc = 0;
>
> for (; item; item = item->next) {
> - if (virSecurityManagerSetAllLabel(item->securityManager, vm, stdin_path) < 0)
> + if (virSecurityManagerSetAllLabel(item->securityManager, vm,
> + stdin_path, chardevStdioLogd) < 0)
> rc = -1;
> }
>
> @@ -368,14 +370,16 @@ virSecurityStackSetAllLabel(virSecurityManagerPtr mgr,
> static int
> virSecurityStackRestoreAllLabel(virSecurityManagerPtr mgr,
> virDomainDefPtr vm,
> - bool migrated)
> + bool migrated,
> + bool chardevStdioLogd)
> {
> virSecurityStackDataPtr priv = virSecurityManagerGetPrivateData(mgr);
> virSecurityStackItemPtr item = priv->itemsHead;
> int rc = 0;
>
> for (; item; item = item->next) {
> - if (virSecurityManagerRestoreAllLabel(item->securityManager, vm, migrated) < 0)
> + if (virSecurityManagerRestoreAllLabel(item->securityManager, vm,
> + migrated, chardevStdioLogd) < 0)
> rc = -1;
> }
>
> diff --git a/tests/securityselinuxlabeltest.c b/tests/securityselinuxlabeltest.c
> index 3e134991f2..ddcc954429 100644
> --- a/tests/securityselinuxlabeltest.c
> +++ b/tests/securityselinuxlabeltest.c
> @@ -313,7 +313,7 @@ testSELinuxLabeling(const void *opaque)
> if (!(def = testSELinuxLoadDef(testname)))
> goto cleanup;
>
> - if (virSecurityManagerSetAllLabel(mgr, def, NULL) < 0)
> + if (virSecurityManagerSetAllLabel(mgr, def, NULL, false) < 0)
> goto cleanup;
>
> if (testSELinuxCheckLabels(files, nfiles) < 0)
>
--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list
On Tue, Jun 13, 2017 at 08:00:41PM -0400, John Ferlan wrote: > > > On 05/29/2017 10:31 AM, Pavel Hrdina wrote: > > In the case that virtlogd is used as stdio handler we pass to QEMU > > only FD to a PIPE connected to virtlogd instead of the file itself. > > > > Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1430988 > > > > Signed-off-by: Pavel Hrdina <phrdina@redhat.com> > > --- > > > > Notes: > > new in v2 > > > > src/lxc/lxc_process.c | 6 ++--- > > src/qemu/qemu_security.c | 9 +++++-- > > src/security/security_apparmor.c | 7 ++++-- > > src/security/security_dac.c | 54 +++++++++++++++++++++++++++++++--------- > > src/security/security_driver.h | 6 +++-- > > src/security/security_manager.c | 12 ++++++--- > > src/security/security_manager.h | 6 +++-- > > src/security/security_nop.c | 6 +++-- > > src/security/security_selinux.c | 53 ++++++++++++++++++++++++++++++--------- > > src/security/security_stack.c | 12 ++++++--- > > tests/securityselinuxlabeltest.c | 2 +- > > 11 files changed, 127 insertions(+), 46 deletions(-) > > > > Why is it a (!chr_seclabel && chardevStdioLogd)? More to the point why > is (!chr_seclabel) even matter? If you configure the label we shouldn't ignore it in some cases, that's just wrong. If the label is set for the char device we will configure it every time even if it will fail to start the guest, it's a responsibility of the user to configure proper label if it is provided. > IIUC, whether or not someone set the label for the chardev, for this > particular issue/config where the chardev has a <log file=$path>, we > don't want to set (or restore) the label. I feel like I'm missing > something subtle. Maybe a bit more explanation of the adjustment would > help me... This is not for the <log file=$path/> but for the <source path=$path/>. We don't relabel $path for <log file=$path/> at all. > Wouldn't these changes end up selecting "any" chardev if > chardevStdioLogd ended up being set regardless of whether they were > actually using the log file? I don't know what you mean by this sentence? > As an aside, I think there's an "oddity" when it comes to the Restore, > but I'm not sure how to put it into words exactly. If a guest is running > code prior to this set of changes, would it have successfully run a Set? > If so, then after applying this change and restarting, the label > wouldn't be reset, right? What happens at guest shutdown - does the > label not get unset now? Of course this is all "interaction" with > virtlogd restart that really throws a monkey wrench into things. No, that's not correct. The @chardevStdioLogd is stored in the status XML (the one stored in /var/run/libvirt/qemu/$domain_name.xml). So when the libvirtd is stopped and started with this patch applied the status XML doesn't have the @chardevStdioLogd stored in it so it will be false and we will reset the label. The @chardevStdioLogd is updated only when the domain is started and we will store the value in the status XML only with new libvirtd and only in that case we will not set/restore the label. > Also, why is the Smartcard chardev handling not using this The smartcard doesn't ever use virtlogd as stdio handler. Pavel -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
On 06/15/2017 03:11 AM, Pavel Hrdina wrote: > On Tue, Jun 13, 2017 at 08:00:41PM -0400, John Ferlan wrote: >> >> >> On 05/29/2017 10:31 AM, Pavel Hrdina wrote: >>> In the case that virtlogd is used as stdio handler we pass to QEMU >>> only FD to a PIPE connected to virtlogd instead of the file itself. >>> >>> Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1430988 >>> >>> Signed-off-by: Pavel Hrdina <phrdina@redhat.com> >>> --- >>> >>> Notes: >>> new in v2 >>> >>> src/lxc/lxc_process.c | 6 ++--- >>> src/qemu/qemu_security.c | 9 +++++-- >>> src/security/security_apparmor.c | 7 ++++-- >>> src/security/security_dac.c | 54 +++++++++++++++++++++++++++++++--------- >>> src/security/security_driver.h | 6 +++-- >>> src/security/security_manager.c | 12 ++++++--- >>> src/security/security_manager.h | 6 +++-- >>> src/security/security_nop.c | 6 +++-- >>> src/security/security_selinux.c | 53 ++++++++++++++++++++++++++++++--------- >>> src/security/security_stack.c | 12 ++++++--- >>> tests/securityselinuxlabeltest.c | 2 +- >>> 11 files changed, 127 insertions(+), 46 deletions(-) >>> >> >> Why is it a (!chr_seclabel && chardevStdioLogd)? More to the point why >> is (!chr_seclabel) even matter? > > If you configure the label we shouldn't ignore it in some cases, that's > just wrong. If the label is set for the char device we will configure > it every time even if it will fail to start the guest, it's a > responsibility of the user to configure proper label if it is provided. > When email doesn't convey the question... Ugh... I'm also trying to speed learn an area of the code and review at the same time. If I go back to commit id 'f8b08d0e' where the original implementation to add labels for chardevs was done (but has been modified for patch 1 to change where the label is stored), I get the impression that a label should be added either from something specifically supplied for the <chardev> or to use the per domain one: "The source element may contain an optional seclabel to override the way that labelling is done on the socket path. If this element is not present, the security label is inherited from the per-domain setting." So if I look at the condition "(!chr_seclabel && chardevStdioLogd)" added by this patch to decide whether or not to supply the label, I'm left with the impression that if for this particular chardev a label doesn't exist *and* the configuration option chardevStdioLogd is true, then we're going to return happy status *and* not inherit the per-domain setting. So the bug is then that applying the default domain label for a chardev configured to use a stdio handle is incorrect? Perhaps I didn't get that from reading bz or the patch. >> IIUC, whether or not someone set the label for the chardev, for this >> particular issue/config where the chardev has a <log file=$path>, we >> don't want to set (or restore) the label. I feel like I'm missing >> something subtle. Maybe a bit more explanation of the adjustment would >> help me... > > This is not for the <log file=$path/> but for the <source path=$path/>. > We don't relabel $path for <log file=$path/> at all. > hmm.. ah, right... I kept scrolling back and forth in the bz and the docs, but missed this in the bz: 3) Check the virtlogd.log: error : virRotatingFileWriterEntryNew:113 : Unable to open file: /var/log/libvirt/qemu/log: Permission denied I guess I got lost in the power of suggestion of reading the docs regarding the "optional log file" that can be associated paragraph and trying to learn on the fly so that you at least get a review in a somewhat timely manner ;-) >> Wouldn't these changes end up selecting "any" chardev if >> chardevStdioLogd ended up being set regardless of whether they were >> actually using the log file? > > I don't know what you mean by this sentence? > Well let's see, chardevStdioLogd is set to true when meeting the two conditions a qemu.conf global "cfg->stdioLogd" && a per domain or emulator image capability "QEMU_CAPS_CHARDEV_FILE_APPEND". So, conceivably chardevStdioLogd could be true for *any* domain as long as those conditions are met, right? If you have a domain that has chardev's which are not configured to use the stdio handler, then the chardevStdioLogd could still be true, right? If that's the case and the chardev doesn't have a label associated, then we just return happy status and we do not inherit the per domain setting. Wouldn't that be incorrect? My concern is more we're making a change in a (mostly) common set of functions for a (very) specific problem. >> As an aside, I think there's an "oddity" when it comes to the Restore, >> but I'm not sure how to put it into words exactly. If a guest is running >> code prior to this set of changes, would it have successfully run a Set? >> If so, then after applying this change and restarting, the label >> wouldn't be reset, right? What happens at guest shutdown - does the >> label not get unset now? Of course this is all "interaction" with >> virtlogd restart that really throws a monkey wrench into things. > > No, that's not correct. The @chardevStdioLogd is stored in the status > XML (the one stored in /var/run/libvirt/qemu/$domain_name.xml). So when > the libvirtd is stopped and started with this patch applied the status > XML doesn't have the @chardevStdioLogd stored in it so it will be false > and we will reset the label. The @chardevStdioLogd is updated only when > the domain is started and we will store the value in the status XML > only with new libvirtd and only in that case we will not set/restore > the label. > hmmm.. Reading the bz indicates the 'virtlogd' daemon restarting... This is where all this gets a bit "odd" for me. Like I said it was a weird thing to even try and explain, but I think you talked me off the ledge of concern. John >> Also, why is the Smartcard chardev handling not using this > > The smartcard doesn't ever use virtlogd as stdio handler. > > Pavel > -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
On Thu, Jun 15, 2017 at 07:57:18AM -0400, John Ferlan wrote: > > > On 06/15/2017 03:11 AM, Pavel Hrdina wrote: > > On Tue, Jun 13, 2017 at 08:00:41PM -0400, John Ferlan wrote: > >> > >> > >> On 05/29/2017 10:31 AM, Pavel Hrdina wrote: > >>> In the case that virtlogd is used as stdio handler we pass to QEMU > >>> only FD to a PIPE connected to virtlogd instead of the file itself. > >>> > >>> Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1430988 > >>> > >>> Signed-off-by: Pavel Hrdina <phrdina@redhat.com> > >>> --- > >>> > >>> Notes: > >>> new in v2 > >>> > >>> src/lxc/lxc_process.c | 6 ++--- > >>> src/qemu/qemu_security.c | 9 +++++-- > >>> src/security/security_apparmor.c | 7 ++++-- > >>> src/security/security_dac.c | 54 +++++++++++++++++++++++++++++++--------- > >>> src/security/security_driver.h | 6 +++-- > >>> src/security/security_manager.c | 12 ++++++--- > >>> src/security/security_manager.h | 6 +++-- > >>> src/security/security_nop.c | 6 +++-- > >>> src/security/security_selinux.c | 53 ++++++++++++++++++++++++++++++--------- > >>> src/security/security_stack.c | 12 ++++++--- > >>> tests/securityselinuxlabeltest.c | 2 +- > >>> 11 files changed, 127 insertions(+), 46 deletions(-) > >>> > >> > >> Why is it a (!chr_seclabel && chardevStdioLogd)? More to the point why > >> is (!chr_seclabel) even matter? > > > > If you configure the label we shouldn't ignore it in some cases, that's > > just wrong. If the label is set for the char device we will configure > > it every time even if it will fail to start the guest, it's a > > responsibility of the user to configure proper label if it is provided. > > > > When email doesn't convey the question... Ugh... I'm also trying to > speed learn an area of the code and review at the same time. > > If I go back to commit id 'f8b08d0e' where the original implementation > to add labels for chardevs was done (but has been modified for patch 1 > to change where the label is stored), I get the impression that a label > should be added either from something specifically supplied for the > <chardev> or to use the per domain one: > > "The source element may contain an optional seclabel to override the way > that labelling is done on the socket path. If this element is not > present, the security label is inherited from the per-domain setting." > > So if I look at the condition "(!chr_seclabel && chardevStdioLogd)" > added by this patch to decide whether or not to supply the label, I'm > left with the impression that if for this particular chardev a label > doesn't exist *and* the configuration option chardevStdioLogd is true, > then we're going to return happy status *and* not inherit the per-domain > setting. > > So the bug is then that applying the default domain label for a chardev > configured to use a stdio handle is incorrect? Perhaps I didn't get > that from reading bz or the patch. Yes, that's the bug. If virtlogd is used to handle stdio for char devices we shouldn't relabel the @path to the default labels, the @path doesn't have to be accessible by the qemu process, it has to be accessible by the virtlogd process. > >> IIUC, whether or not someone set the label for the chardev, for this > >> particular issue/config where the chardev has a <log file=$path>, we > >> don't want to set (or restore) the label. I feel like I'm missing > >> something subtle. Maybe a bit more explanation of the adjustment would > >> help me... > > > > This is not for the <log file=$path/> but for the <source path=$path/>. > > We don't relabel $path for <log file=$path/> at all. > > > > hmm.. ah, right... I kept scrolling back and forth in the bz and the > docs, but missed this in the bz: > > 3) Check the virtlogd.log: > error : virRotatingFileWriterEntryNew:113 : Unable to open file: > /var/log/libvirt/qemu/log: Permission denied > > I guess I got lost in the power of suggestion of reading the docs > regarding the "optional log file" that can be associated paragraph and > trying to learn on the fly so that you at least get a review in a > somewhat timely manner ;-) > > >> Wouldn't these changes end up selecting "any" chardev if > >> chardevStdioLogd ended up being set regardless of whether they were > >> actually using the log file? > > > > I don't know what you mean by this sentence? > > > > Well let's see, chardevStdioLogd is set to true when meeting the two > conditions a qemu.conf global "cfg->stdioLogd" && a per domain or > emulator image capability "QEMU_CAPS_CHARDEV_FILE_APPEND". > > So, conceivably chardevStdioLogd could be true for *any* domain as long > as those conditions are met, right? Yes, the two conditions are checked while starting a new domain in qemuProcessPrepareDomain() and stored in the private date of that domain. > If you have a domain that has chardev's which are not configured to use > the stdio handler, then the chardevStdioLogd could still be true, right? No, if the @chardevStdioLogd is true all char devices for that domain will use virtlogd. The only issue I've just found out is that the code path for chardev hot-plug isn't updated to use virtlogd when it should be so for hot-plugged char devices we pass the path directly to QEMU. With this patch applied the hot-plug fails if virtlogd is used because we don't relabel the path but we pass it directly to QEMU, this needs to be fixed to not introduce a regression, sigh. Pavel > If that's the case and the chardev doesn't have a label associated, then > we just return happy status and we do not inherit the per domain > setting. Wouldn't that be incorrect? > > My concern is more we're making a change in a (mostly) common set of > functions for a (very) specific problem. > > > >> As an aside, I think there's an "oddity" when it comes to the Restore, > >> but I'm not sure how to put it into words exactly. If a guest is running > >> code prior to this set of changes, would it have successfully run a Set? > >> If so, then after applying this change and restarting, the label > >> wouldn't be reset, right? What happens at guest shutdown - does the > >> label not get unset now? Of course this is all "interaction" with > >> virtlogd restart that really throws a monkey wrench into things. > > > > No, that's not correct. The @chardevStdioLogd is stored in the status > > XML (the one stored in /var/run/libvirt/qemu/$domain_name.xml). So when > > the libvirtd is stopped and started with this patch applied the status > > XML doesn't have the @chardevStdioLogd stored in it so it will be false > > and we will reset the label. The @chardevStdioLogd is updated only when > > the domain is started and we will store the value in the status XML > > only with new libvirtd and only in that case we will not set/restore > > the label. > > > > hmmm.. Reading the bz indicates the 'virtlogd' daemon restarting... This > is where all this gets a bit "odd" for me. Like I said it was a weird > thing to even try and explain, but I think you talked me off the ledge > of concern. > > John > > >> Also, why is the Smartcard chardev handling not using this > > > > The smartcard doesn't ever use virtlogd as stdio handler. > > > > Pavel > > > > -- > libvir-list mailing list > libvir-list@redhat.com > https://www.redhat.com/mailman/listinfo/libvir-list -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
On Thu, Jun 15, 2017 at 04:40:49PM +0200, Pavel Hrdina wrote: > On Thu, Jun 15, 2017 at 07:57:18AM -0400, John Ferlan wrote: > > > > > > On 06/15/2017 03:11 AM, Pavel Hrdina wrote: > > > On Tue, Jun 13, 2017 at 08:00:41PM -0400, John Ferlan wrote: > > >> > > >> > > >> On 05/29/2017 10:31 AM, Pavel Hrdina wrote: > > >>> In the case that virtlogd is used as stdio handler we pass to QEMU > > >>> only FD to a PIPE connected to virtlogd instead of the file itself. > > >>> > > >>> Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1430988 > > >>> > > >>> Signed-off-by: Pavel Hrdina <phrdina@redhat.com> > > >>> --- > > >>> > > >>> Notes: > > >>> new in v2 > > >>> > > >>> src/lxc/lxc_process.c | 6 ++--- > > >>> src/qemu/qemu_security.c | 9 +++++-- > > >>> src/security/security_apparmor.c | 7 ++++-- > > >>> src/security/security_dac.c | 54 +++++++++++++++++++++++++++++++--------- > > >>> src/security/security_driver.h | 6 +++-- > > >>> src/security/security_manager.c | 12 ++++++--- > > >>> src/security/security_manager.h | 6 +++-- > > >>> src/security/security_nop.c | 6 +++-- > > >>> src/security/security_selinux.c | 53 ++++++++++++++++++++++++++++++--------- > > >>> src/security/security_stack.c | 12 ++++++--- > > >>> tests/securityselinuxlabeltest.c | 2 +- > > >>> 11 files changed, 127 insertions(+), 46 deletions(-) > > >>> > > >> > > >> Why is it a (!chr_seclabel && chardevStdioLogd)? More to the point why > > >> is (!chr_seclabel) even matter? > > > > > > If you configure the label we shouldn't ignore it in some cases, that's > > > just wrong. If the label is set for the char device we will configure > > > it every time even if it will fail to start the guest, it's a > > > responsibility of the user to configure proper label if it is provided. > > > > > > > When email doesn't convey the question... Ugh... I'm also trying to > > speed learn an area of the code and review at the same time. > > > > If I go back to commit id 'f8b08d0e' where the original implementation > > to add labels for chardevs was done (but has been modified for patch 1 > > to change where the label is stored), I get the impression that a label > > should be added either from something specifically supplied for the > > <chardev> or to use the per domain one: > > > > "The source element may contain an optional seclabel to override the way > > that labelling is done on the socket path. If this element is not > > present, the security label is inherited from the per-domain setting." > > > > So if I look at the condition "(!chr_seclabel && chardevStdioLogd)" > > added by this patch to decide whether or not to supply the label, I'm > > left with the impression that if for this particular chardev a label > > doesn't exist *and* the configuration option chardevStdioLogd is true, > > then we're going to return happy status *and* not inherit the per-domain > > setting. > > > > So the bug is then that applying the default domain label for a chardev > > configured to use a stdio handle is incorrect? Perhaps I didn't get > > that from reading bz or the patch. > > Yes, that's the bug. If virtlogd is used to handle stdio for char > devices we shouldn't relabel the @path to the default labels, the > @path doesn't have to be accessible by the qemu process, it has to be > accessible by the virtlogd process. > > > >> IIUC, whether or not someone set the label for the chardev, for this > > >> particular issue/config where the chardev has a <log file=$path>, we > > >> don't want to set (or restore) the label. I feel like I'm missing > > >> something subtle. Maybe a bit more explanation of the adjustment would > > >> help me... > > > > > > This is not for the <log file=$path/> but for the <source path=$path/>. > > > We don't relabel $path for <log file=$path/> at all. > > > > > > > hmm.. ah, right... I kept scrolling back and forth in the bz and the > > docs, but missed this in the bz: > > > > 3) Check the virtlogd.log: > > error : virRotatingFileWriterEntryNew:113 : Unable to open file: > > /var/log/libvirt/qemu/log: Permission denied > > > > I guess I got lost in the power of suggestion of reading the docs > > regarding the "optional log file" that can be associated paragraph and > > trying to learn on the fly so that you at least get a review in a > > somewhat timely manner ;-) > > > > >> Wouldn't these changes end up selecting "any" chardev if > > >> chardevStdioLogd ended up being set regardless of whether they were > > >> actually using the log file? > > > > > > I don't know what you mean by this sentence? > > > > > > > Well let's see, chardevStdioLogd is set to true when meeting the two > > conditions a qemu.conf global "cfg->stdioLogd" && a per domain or > > emulator image capability "QEMU_CAPS_CHARDEV_FILE_APPEND". > > > > So, conceivably chardevStdioLogd could be true for *any* domain as long > > as those conditions are met, right? > > Yes, the two conditions are checked while starting a new domain in > qemuProcessPrepareDomain() and stored in the private date of that > domain. > > > If you have a domain that has chardev's which are not configured to use > > the stdio handler, then the chardevStdioLogd could still be true, right? > > No, if the @chardevStdioLogd is true all char devices for that domain > will use virtlogd. > > The only issue I've just found out is that the code path for chardev > hot-plug isn't updated to use virtlogd when it should be so for > hot-plugged char devices we pass the path directly to QEMU. > > With this patch applied the hot-plug fails if virtlogd is used because > we don't relabel the path but we pass it directly to QEMU, this needs to > be fixed to not introduce a regression, sigh. Ok, I've tried it without this patch and it still fails with permission denied so there is no regression, we just don't relabel the hot-plugged chardev at all. Still it should be fixed. > Pavel > > > If that's the case and the chardev doesn't have a label associated, then > > we just return happy status and we do not inherit the per domain > > setting. Wouldn't that be incorrect? > > > > My concern is more we're making a change in a (mostly) common set of > > functions for a (very) specific problem. > > > > > > >> As an aside, I think there's an "oddity" when it comes to the Restore, > > >> but I'm not sure how to put it into words exactly. If a guest is running > > >> code prior to this set of changes, would it have successfully run a Set? > > >> If so, then after applying this change and restarting, the label > > >> wouldn't be reset, right? What happens at guest shutdown - does the > > >> label not get unset now? Of course this is all "interaction" with > > >> virtlogd restart that really throws a monkey wrench into things. > > > > > > No, that's not correct. The @chardevStdioLogd is stored in the status > > > XML (the one stored in /var/run/libvirt/qemu/$domain_name.xml). So when > > > the libvirtd is stopped and started with this patch applied the status > > > XML doesn't have the @chardevStdioLogd stored in it so it will be false > > > and we will reset the label. The @chardevStdioLogd is updated only when > > > the domain is started and we will store the value in the status XML > > > only with new libvirtd and only in that case we will not set/restore > > > the label. > > > > > > > hmmm.. Reading the bz indicates the 'virtlogd' daemon restarting... This > > is where all this gets a bit "odd" for me. Like I said it was a weird > > thing to even try and explain, but I think you talked me off the ledge > > of concern. > > > > John > > > > >> Also, why is the Smartcard chardev handling not using this > > > > > > The smartcard doesn't ever use virtlogd as stdio handler. > > > > > > Pavel > > > > > > > -- > > libvir-list mailing list > > libvir-list@redhat.com > > https://www.redhat.com/mailman/listinfo/libvir-list > -- > libvir-list mailing list > libvir-list@redhat.com > https://www.redhat.com/mailman/listinfo/libvir-list -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
On 06/15/2017 10:40 AM, Pavel Hrdina wrote: > On Thu, Jun 15, 2017 at 07:57:18AM -0400, John Ferlan wrote: >> >> >> On 06/15/2017 03:11 AM, Pavel Hrdina wrote: >>> On Tue, Jun 13, 2017 at 08:00:41PM -0400, John Ferlan wrote: >>>> >>>> >>>> On 05/29/2017 10:31 AM, Pavel Hrdina wrote: >>>>> In the case that virtlogd is used as stdio handler we pass to QEMU >>>>> only FD to a PIPE connected to virtlogd instead of the file itself. >>>>> >>>>> Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1430988 >>>>> >>>>> Signed-off-by: Pavel Hrdina <phrdina@redhat.com> >>>>> --- >>>>> >>>>> Notes: >>>>> new in v2 >>>>> >>>>> src/lxc/lxc_process.c | 6 ++--- >>>>> src/qemu/qemu_security.c | 9 +++++-- >>>>> src/security/security_apparmor.c | 7 ++++-- >>>>> src/security/security_dac.c | 54 +++++++++++++++++++++++++++++++--------- >>>>> src/security/security_driver.h | 6 +++-- >>>>> src/security/security_manager.c | 12 ++++++--- >>>>> src/security/security_manager.h | 6 +++-- >>>>> src/security/security_nop.c | 6 +++-- >>>>> src/security/security_selinux.c | 53 ++++++++++++++++++++++++++++++--------- >>>>> src/security/security_stack.c | 12 ++++++--- >>>>> tests/securityselinuxlabeltest.c | 2 +- >>>>> 11 files changed, 127 insertions(+), 46 deletions(-) >>>>> >>>> >>>> Why is it a (!chr_seclabel && chardevStdioLogd)? More to the point why >>>> is (!chr_seclabel) even matter? >>> >>> If you configure the label we shouldn't ignore it in some cases, that's >>> just wrong. If the label is set for the char device we will configure >>> it every time even if it will fail to start the guest, it's a >>> responsibility of the user to configure proper label if it is provided. >>> >> >> When email doesn't convey the question... Ugh... I'm also trying to >> speed learn an area of the code and review at the same time. >> >> If I go back to commit id 'f8b08d0e' where the original implementation >> to add labels for chardevs was done (but has been modified for patch 1 >> to change where the label is stored), I get the impression that a label >> should be added either from something specifically supplied for the >> <chardev> or to use the per domain one: >> >> "The source element may contain an optional seclabel to override the way >> that labelling is done on the socket path. If this element is not >> present, the security label is inherited from the per-domain setting." >> >> So if I look at the condition "(!chr_seclabel && chardevStdioLogd)" >> added by this patch to decide whether or not to supply the label, I'm >> left with the impression that if for this particular chardev a label >> doesn't exist *and* the configuration option chardevStdioLogd is true, >> then we're going to return happy status *and* not inherit the per-domain >> setting. >> >> So the bug is then that applying the default domain label for a chardev >> configured to use a stdio handle is incorrect? Perhaps I didn't get >> that from reading bz or the patch. > > Yes, that's the bug. If virtlogd is used to handle stdio for char > devices we shouldn't relabel the @path to the default labels, the > @path doesn't have to be accessible by the qemu process, it has to be > accessible by the virtlogd process. > >>>> IIUC, whether or not someone set the label for the chardev, for this >>>> particular issue/config where the chardev has a <log file=$path>, we >>>> don't want to set (or restore) the label. I feel like I'm missing >>>> something subtle. Maybe a bit more explanation of the adjustment would >>>> help me... >>> >>> This is not for the <log file=$path/> but for the <source path=$path/>. >>> We don't relabel $path for <log file=$path/> at all. >>> >> >> hmm.. ah, right... I kept scrolling back and forth in the bz and the >> docs, but missed this in the bz: >> >> 3) Check the virtlogd.log: >> error : virRotatingFileWriterEntryNew:113 : Unable to open file: >> /var/log/libvirt/qemu/log: Permission denied >> >> I guess I got lost in the power of suggestion of reading the docs >> regarding the "optional log file" that can be associated paragraph and >> trying to learn on the fly so that you at least get a review in a >> somewhat timely manner ;-) >> >>>> Wouldn't these changes end up selecting "any" chardev if >>>> chardevStdioLogd ended up being set regardless of whether they were >>>> actually using the log file? >>> >>> I don't know what you mean by this sentence? >>> >> >> Well let's see, chardevStdioLogd is set to true when meeting the two >> conditions a qemu.conf global "cfg->stdioLogd" && a per domain or >> emulator image capability "QEMU_CAPS_CHARDEV_FILE_APPEND". >> >> So, conceivably chardevStdioLogd could be true for *any* domain as long >> as those conditions are met, right? > > Yes, the two conditions are checked while starting a new domain in > qemuProcessPrepareDomain() and stored in the private date of that > domain. > >> If you have a domain that has chardev's which are not configured to use >> the stdio handler, then the chardevStdioLogd could still be true, right? > > No, if the @chardevStdioLogd is true all char devices for that domain > will use virtlogd. > This is the part I'm stuck on as to why - based on the previous assertion. I'm just not visualizing all those various chardev configs. Just so you know - I have to be out Friday, but will be back Monday. If you get someone else to ACK this one in the mean time - that's fine. John > The only issue I've just found out is that the code path for chardev > hot-plug isn't updated to use virtlogd when it should be so for > hot-plugged char devices we pass the path directly to QEMU. > > With this patch applied the hot-plug fails if virtlogd is used because > we don't relabel the path but we pass it directly to QEMU, this needs to > be fixed to not introduce a regression, sigh. > > Pavel > >> If that's the case and the chardev doesn't have a label associated, then >> we just return happy status and we do not inherit the per domain >> setting. Wouldn't that be incorrect? >> >> My concern is more we're making a change in a (mostly) common set of >> functions for a (very) specific problem. >> >> >>>> As an aside, I think there's an "oddity" when it comes to the Restore, >>>> but I'm not sure how to put it into words exactly. If a guest is running >>>> code prior to this set of changes, would it have successfully run a Set? >>>> If so, then after applying this change and restarting, the label >>>> wouldn't be reset, right? What happens at guest shutdown - does the >>>> label not get unset now? Of course this is all "interaction" with >>>> virtlogd restart that really throws a monkey wrench into things. >>> >>> No, that's not correct. The @chardevStdioLogd is stored in the status >>> XML (the one stored in /var/run/libvirt/qemu/$domain_name.xml). So when >>> the libvirtd is stopped and started with this patch applied the status >>> XML doesn't have the @chardevStdioLogd stored in it so it will be false >>> and we will reset the label. The @chardevStdioLogd is updated only when >>> the domain is started and we will store the value in the status XML >>> only with new libvirtd and only in that case we will not set/restore >>> the label. >>> >> >> hmmm.. Reading the bz indicates the 'virtlogd' daemon restarting... This >> is where all this gets a bit "odd" for me. Like I said it was a weird >> thing to even try and explain, but I think you talked me off the ledge >> of concern. >> >> John >> >>>> Also, why is the Smartcard chardev handling not using this >>> >>> The smartcard doesn't ever use virtlogd as stdio handler. >>> >>> Pavel >>> >> >> -- >> libvir-list mailing list >> libvir-list@redhat.com >> https://www.redhat.com/mailman/listinfo/libvir-list -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
On Thu, Jun 15, 2017 at 10:12:51PM -0400, John Ferlan wrote: >On 06/15/2017 10:40 AM, Pavel Hrdina wrote: >> On Thu, Jun 15, 2017 at 07:57:18AM -0400, John Ferlan wrote: >>> On 06/15/2017 03:11 AM, Pavel Hrdina wrote: >>>> On Tue, Jun 13, 2017 at 08:00:41PM -0400, John Ferlan wrote: [...] >>>>> Wouldn't these changes end up selecting "any" chardev if >>>>> chardevStdioLogd ended up being set regardless of whether they were >>>>> actually using the log file? >>>> >>>> I don't know what you mean by this sentence? >>>> >>> >>> Well let's see, chardevStdioLogd is set to true when meeting the two >>> conditions a qemu.conf global "cfg->stdioLogd" && a per domain or >>> emulator image capability "QEMU_CAPS_CHARDEV_FILE_APPEND". >>> >>> So, conceivably chardevStdioLogd could be true for *any* domain as long >>> as those conditions are met, right? >> >> Yes, the two conditions are checked while starting a new domain in >> qemuProcessPrepareDomain() and stored in the private date of that >> domain. >> >>> If you have a domain that has chardev's which are not configured to use >>> the stdio handler, then the chardevStdioLogd could still be true, right? >> >> No, if the @chardevStdioLogd is true all char devices for that domain >> will use virtlogd. >> > >This is the part I'm stuck on as to why - based on the previous >assertion. I'm just not visualizing all those various chardev configs. >Just so you know - I have to be out Friday, but will be back Monday. If >you get someone else to ACK this one in the mean time - that's fine. > The usage of virlogd can be only set in qemu.conf, not per-chardev, not even per-domain. We need to save it per-domain, though, as it can differ for domains started before and after that setting was changed in qemu.conf and the daemon restarted (or updated to a version with support for virtlogd as that is the default if nothing is specified in the config). The hotplug should be fixed, but as you said that can be a follow-up patch. Reviewed-by: Martin Kletzander <mkletzan@redhat.com> -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
© 2016 - 2025 Red Hat, Inc.