From d5aba1a4d926849577af950af8f51edff2bf433b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A1n=20Tomko?= Date: Fri, 20 Nov 2015 08:25:41 +0100 Subject: [PATCH] security: label the evdev for input device passthrough Add functions for setting and restoring the label of input devices to DAC and SELinux drivers. https://bugzilla.redhat.com/show_bug.cgi?id=1231114 --- src/security/security_dac.c | 72 +++++++++++++++++++++++++++++++++ src/security/security_selinux.c | 70 ++++++++++++++++++++++++++++++++ 2 files changed, 142 insertions(+) diff --git a/src/security/security_dac.c b/src/security/security_dac.c index dfdeffd1a5..cdde34ec2d 100644 --- a/src/security/security_dac.c +++ b/src/security/security_dac.c @@ -1012,6 +1012,66 @@ virSecurityDACRestoreSecurityTPMFileLabel(virSecurityManagerPtr mgr, } +static int +virSecurityDACSetInputLabel(virSecurityManagerPtr mgr, + virDomainDefPtr def, + virDomainInputDefPtr input) + +{ + virSecurityDACDataPtr priv = virSecurityManagerGetPrivateData(mgr); + virSecurityLabelDefPtr seclabel; + int ret = -1; + uid_t user; + gid_t group; + + seclabel = virDomainDefGetSecurityLabelDef(def, SECURITY_DAC_NAME); + if (seclabel && !seclabel->relabel) + return 0; + + switch ((virDomainInputType) input->type) { + case VIR_DOMAIN_INPUT_TYPE_PASSTHROUGH: + if (virSecurityDACGetIds(seclabel, priv, &user, &group, NULL, NULL) < 0) + return -1; + + ret = virSecurityDACSetOwnership(priv, NULL, input->source.evdev, user, group); + break; + + case VIR_DOMAIN_INPUT_TYPE_MOUSE: + case VIR_DOMAIN_INPUT_TYPE_TABLET: + case VIR_DOMAIN_INPUT_TYPE_KBD: + case VIR_DOMAIN_INPUT_TYPE_LAST: + ret = 0; + break; + } + + return ret; +} + +static int +virSecurityDACRestoreInputLabel(virSecurityManagerPtr mgr, + virDomainDefPtr def ATTRIBUTE_UNUSED, + virDomainInputDefPtr input) +{ + virSecurityDACDataPtr priv = virSecurityManagerGetPrivateData(mgr); + int ret = -1; + + switch ((virDomainInputType) input->type) { + case VIR_DOMAIN_INPUT_TYPE_PASSTHROUGH: + ret = virSecurityDACRestoreSecurityFileLabel(priv, input->source.evdev); + break; + + case VIR_DOMAIN_INPUT_TYPE_MOUSE: + case VIR_DOMAIN_INPUT_TYPE_TABLET: + case VIR_DOMAIN_INPUT_TYPE_KBD: + case VIR_DOMAIN_INPUT_TYPE_LAST: + ret = 0; + break; + } + + return ret; +} + + static int virSecurityDACRestoreSecurityAllLabel(virSecurityManagerPtr mgr, virDomainDefPtr def, @@ -1037,6 +1097,12 @@ virSecurityDACRestoreSecurityAllLabel(virSecurityManagerPtr mgr, NULL) < 0) rc = -1; } + + for (i = 0; i < def->ninputs; i++) { + if (virSecurityDACRestoreInputLabel(mgr, def, def->inputs[i]) < 0) + rc = -1; + } + for (i = 0; i < def->ndisks; i++) { if (virSecurityDACRestoreSecurityImageLabelInt(mgr, def, @@ -1114,6 +1180,12 @@ virSecurityDACSetSecurityAllLabel(virSecurityManagerPtr mgr, def->disks[i]) < 0) return -1; } + + for (i = 0; i < def->ninputs; i++) { + if (virSecurityDACSetInputLabel(mgr, def, def->inputs[i]) < 0) + return -1; + } + for (i = 0; i < def->nhostdevs; i++) { if (virSecurityDACSetSecurityHostdevLabel(mgr, def, diff --git a/src/security/security_selinux.c b/src/security/security_selinux.c index 80b08864d8..b8ebdcc733 100644 --- a/src/security/security_selinux.c +++ b/src/security/security_selinux.c @@ -1055,6 +1055,64 @@ virSecuritySELinuxRestoreSecurityFileLabel(virSecurityManagerPtr mgr, } +static int +virSecuritySELinuxSetInputLabel(virSecurityManagerPtr mgr, + virDomainDefPtr def, + virDomainInputDefPtr input) +{ + virSecurityLabelDefPtr seclabel; + + seclabel = virDomainDefGetSecurityLabelDef(def, SECURITY_SELINUX_NAME); + if (seclabel == NULL) + return 0; + + switch ((virDomainInputType) input->type) { + case VIR_DOMAIN_INPUT_TYPE_PASSTHROUGH: + if (virSecuritySELinuxSetFilecon(mgr, input->source.evdev, + seclabel->imagelabel) < 0) + return -1; + break; + + case VIR_DOMAIN_INPUT_TYPE_MOUSE: + case VIR_DOMAIN_INPUT_TYPE_TABLET: + case VIR_DOMAIN_INPUT_TYPE_KBD: + case VIR_DOMAIN_INPUT_TYPE_LAST: + break; + } + + return 0; +} + + +static int +virSecuritySELinuxRestoreInputLabel(virSecurityManagerPtr mgr, + virDomainDefPtr def, + virDomainInputDefPtr input) +{ + int rc = 0; + virSecurityLabelDefPtr seclabel; + + seclabel = virDomainDefGetSecurityLabelDef(def, SECURITY_SELINUX_NAME); + if (seclabel == NULL) + return 0; + + switch ((virDomainInputType) input->type) { + case VIR_DOMAIN_INPUT_TYPE_PASSTHROUGH: + rc = virSecuritySELinuxRestoreSecurityFileLabel(mgr, + input->source.evdev); + break; + + case VIR_DOMAIN_INPUT_TYPE_MOUSE: + case VIR_DOMAIN_INPUT_TYPE_TABLET: + case VIR_DOMAIN_INPUT_TYPE_KBD: + case VIR_DOMAIN_INPUT_TYPE_LAST: + break; + } + + return rc; +} + + static int virSecuritySELinuxSetSecurityTPMFileLabel(virSecurityManagerPtr mgr, virDomainDefPtr def, @@ -1954,6 +2012,12 @@ virSecuritySELinuxRestoreSecurityAllLabel(virSecurityManagerPtr mgr, NULL) < 0) rc = -1; } + + for (i = 0; i < def->ninputs; i++) { + if (virSecuritySELinuxRestoreInputLabel(mgr, def, def->inputs[i]) < 0) + rc = -1; + } + for (i = 0; i < def->ndisks; i++) { virDomainDiskDefPtr disk = def->disks[i]; @@ -2346,6 +2410,12 @@ virSecuritySELinuxSetSecurityAllLabel(virSecurityManagerPtr mgr, NULL) < 0) return -1; } + + for (i = 0; i < def->ninputs; i++) { + if (virSecuritySELinuxSetInputLabel(mgr, def, def->inputs[i]) < 0) + return -1; + } + if (def->tpm) { if (virSecuritySELinuxSetSecurityTPMFileLabel(mgr, def, def->tpm) < 0) -- GitLab