virSecurityManagerRestoreHostdevLabel;
virSecurityManagerRestoreSavedStateLabel;
virSecurityManagerSetAllLabel;
+virSecurityManagerSetFDLabel;
virSecurityManagerSetImageLabel;
virSecurityManagerSetHostdevLabel;
virSecurityManagerSetProcessLabel;
return reload_profile(mgr, vm, NULL, false);
}
+static int
+AppArmorSetFDLabel(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
+ virDomainObjPtr vm ATTRIBUTE_UNUSED,
+ int fd ATTRIBUTE_UNUSED)
+{
+ return 0;
+}
+
virSecurityDriver virAppArmorSecurityDriver = {
0,
SECURITY_APPARMOR_NAME,
AppArmorSetSavedStateLabel,
AppArmorRestoreSavedStateLabel,
+
+ AppArmorSetFDLabel,
};
return 0;
}
+static int
+virSecurityDACSetFDLabel(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
+ virDomainObjPtr vm ATTRIBUTE_UNUSED,
+ int fd ATTRIBUTE_UNUSED)
+{
+ return 0;
+}
+
virSecurityDriver virSecurityDriverDAC = {
sizeof(virSecurityDACData),
virSecurityDACSetSavedStateLabel,
virSecurityDACRestoreSavedStateLabel,
+
+ virSecurityDACSetFDLabel,
};
virDomainObjPtr vm);
typedef int (*virSecurityDomainSecurityVerify) (virSecurityManagerPtr mgr,
virDomainDefPtr def);
-
+typedef int (*virSecurityDomainSetFDLabel) (virSecurityManagerPtr mgr,
+ virDomainObjPtr vm,
+ int fd);
struct _virSecurityDriver {
size_t privateDataLen;
virSecurityDomainSetSavedStateLabel domainSetSavedStateLabel;
virSecurityDomainRestoreSavedStateLabel domainRestoreSavedStateLabel;
+
+ virSecurityDomainSetFDLabel domainSetSecurityFDLabel;
};
virSecurityDriverPtr virSecurityDriverLookup(const char *name);
virSecurityReportError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
return -1;
}
+
+int virSecurityManagerSetFDLabel(virSecurityManagerPtr mgr,
+ virDomainObjPtr vm,
+ int fd)
+{
+ if (mgr->drv->domainSetSecurityFDLabel)
+ return mgr->drv->domainSetSecurityFDLabel(mgr, vm, fd);
+
+ virSecurityReportError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
+ return -1;
+}
virDomainObjPtr vm);
int virSecurityManagerVerify(virSecurityManagerPtr mgr,
virDomainDefPtr def);
+int virSecurityManagerSetFDLabel(virSecurityManagerPtr mgr,
+ virDomainObjPtr vm,
+ int fd);
#endif /* VIR_SECURITY_MANAGER_H__ */
return 0;
}
+static int virSecurityDomainSetFDLabelNop(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
+ virDomainObjPtr sec ATTRIBUTE_UNUSED,
+ int fd ATTRIBUTE_UNUSED)
+{
+ return 0;
+}
+
virSecurityDriver virSecurityDriverNop = {
0,
"none",
virSecurityDomainSetSavedStateLabelNop,
virSecurityDomainRestoreSavedStateLabelNop,
+
+ virSecurityDomainSetFDLabelNop,
};
return 0;
}
+static int
+SELinuxFSetFilecon(int fd, char *tcon)
+{
+ security_context_t econ;
+
+ VIR_INFO("Setting SELinux context on fd %d to '%s'", fd, tcon);
+
+ if (fsetfilecon(fd, tcon) < 0) {
+ int fsetfilecon_errno = errno;
+
+ if (fgetfilecon(fd, &econ) >= 0) {
+ if (STREQ(tcon, econ)) {
+ freecon(econ);
+ /* It's alright, there's nothing to change anyway. */
+ return 0;
+ }
+ freecon(econ);
+ }
+
+ /* if the error complaint is related to an image hosted on
+ * an nfs mount, or a usbfs/sysfs filesystem not supporting
+ * labelling, then just ignore it & hope for the best.
+ * The user hopefully set one of the necessary SELinux
+ * virt_use_{nfs,usb,pci} boolean tunables to allow it...
+ */
+ if (fsetfilecon_errno != EOPNOTSUPP) {
+ virReportSystemError(fsetfilecon_errno,
+ _("unable to set security context '%s' on fd %d"),
+ tcon, fd);
+ if (security_getenforce() == 1)
+ return -1;
+ } else {
+ VIR_INFO("Setting security context '%s' on fd %d not supported",
+ tcon, fd);
+ }
+ }
+ return 0;
+}
+
/* Set fcon to the appropriate label for path and mode, or return -1. */
static int
getContext(const char *newpath, mode_t mode, security_context_t *fcon)
return 0;
}
+static int
+SELinuxSetFDLabel(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
+ virDomainObjPtr vm,
+ int fd)
+{
+ const virSecurityLabelDefPtr secdef = &vm->def->seclabel;
+
+ if (secdef->imagelabel == NULL)
+ return 0;
+
+ return SELinuxFSetFilecon(fd, secdef->imagelabel);
+}
+
virSecurityDriver virSecurityDriverSELinux = {
0,
SECURITY_SELINUX_NAME,
SELinuxSetSavedStateLabel,
SELinuxRestoreSavedStateLabel,
+
+ SELinuxSetFDLabel,
};
return rc;
}
+static int
+virSecurityStackSetFDLabel(virSecurityManagerPtr mgr,
+ virDomainObjPtr vm,
+ int fd)
+{
+ virSecurityStackDataPtr priv = virSecurityManagerGetPrivateData(mgr);
+ int rc = 0;
+
+ if (virSecurityManagerSetFDLabel(priv->secondary, vm, fd) < 0)
+ rc = -1;
+ if (virSecurityManagerSetFDLabel(priv->primary, vm, fd) < 0)
+ rc = -1;
+
+ return rc;
+}
+
virSecurityDriver virSecurityDriverStack = {
sizeof(virSecurityStackData),
virSecurityStackSetSavedStateLabel,
virSecurityStackRestoreSavedStateLabel,
+
+ virSecurityStackSetFDLabel,
};