]> xenbits.xensource.com Git - libvirt.git/commitdiff
security: label the evdev for input device passthrough
authorJán Tomko <jtomko@redhat.com>
Fri, 20 Nov 2015 07:25:41 +0000 (08:25 +0100)
committerJán Tomko <jtomko@redhat.com>
Mon, 30 Nov 2015 11:57:43 +0000 (12:57 +0100)
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
src/security/security_selinux.c

index dfdeffd1a52030c45cfdf3611503ed18d7b51dac..cdde34ec2d8b7c7c5629e0400bbfe9884a082869 100644 (file)
@@ -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,
index 80b08864d88019c48d3d83fcfb8cdf4422f5f948..b8ebdcc7333f0699bb8cbe6d60f6dea0ece2ffab 100644 (file)
@@ -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)