[libvirt] [PATCH 6/8] security: label the evdev for input device passthrough

Ján Tomko jtomko at redhat.com
Fri Nov 20 08:59:41 UTC 2015


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 dfdeffd..cdde34e 100644
--- a/src/security/security_dac.c
+++ b/src/security/security_dac.c
@@ -1013,6 +1013,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,
                                       bool migrated)
@@ -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 80b0886..b8ebdcc 100644
--- a/src/security/security_selinux.c
+++ b/src/security/security_selinux.c
@@ -1056,6 +1056,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,
                                           virDomainTPMDefPtr tpm)
@@ -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)
-- 
2.4.6




More information about the libvir-list mailing list