mirror of
https://github.com/libvirt/libvirt.git
synced 2025-02-25 18:55:26 -06:00
Update security layer to handle many security labels
These changes make the security drivers able to find and handle the correct security label information when more than one label is available. They also update the DAC driver to be used as an usual security driver. Signed-off-by: Marcelo Cerri <mhcerri@linux.vnet.ibm.com>
This commit is contained in:
parent
e9377dda36
commit
a994ef2d1a
@ -992,6 +992,7 @@ virSecurityManagerFree;
|
|||||||
virSecurityManagerGenLabel;
|
virSecurityManagerGenLabel;
|
||||||
virSecurityManagerGetDOI;
|
virSecurityManagerGetDOI;
|
||||||
virSecurityManagerGetModel;
|
virSecurityManagerGetModel;
|
||||||
|
virSecurityManagerGetNested;
|
||||||
virSecurityManagerGetProcessLabel;
|
virSecurityManagerGetProcessLabel;
|
||||||
virSecurityManagerNew;
|
virSecurityManagerNew;
|
||||||
virSecurityManagerNewStack;
|
virSecurityManagerNewStack;
|
||||||
@ -1010,6 +1011,7 @@ virSecurityManagerSetHostdevLabel;
|
|||||||
virSecurityManagerSetProcessLabel;
|
virSecurityManagerSetProcessLabel;
|
||||||
virSecurityManagerSetSavedStateLabel;
|
virSecurityManagerSetSavedStateLabel;
|
||||||
virSecurityManagerSetSocketLabel;
|
virSecurityManagerSetSocketLabel;
|
||||||
|
virSecurityManagerStackAddNested;
|
||||||
virSecurityManagerVerify;
|
virSecurityManagerVerify;
|
||||||
virSecurityManagerGetMountOptions;
|
virSecurityManagerGetMountOptions;
|
||||||
|
|
||||||
|
@ -268,8 +268,8 @@ qemuSecurityInit(struct qemud_driver *driver)
|
|||||||
if (!dac)
|
if (!dac)
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
if (!(driver->securityManager = virSecurityManagerNewStack(mgr,
|
if (!(driver->securityManager = virSecurityManagerNewStack(mgr)) ||
|
||||||
dac))) {
|
!(virSecurityManagerStackAddNested(mgr, dac))) {
|
||||||
|
|
||||||
virSecurityManagerFree(dac);
|
virSecurityManagerFree(dac);
|
||||||
goto error;
|
goto error;
|
||||||
@ -291,7 +291,11 @@ static virCapsPtr
|
|||||||
qemuCreateCapabilities(virCapsPtr oldcaps,
|
qemuCreateCapabilities(virCapsPtr oldcaps,
|
||||||
struct qemud_driver *driver)
|
struct qemud_driver *driver)
|
||||||
{
|
{
|
||||||
|
size_t i;
|
||||||
virCapsPtr caps;
|
virCapsPtr caps;
|
||||||
|
virSecurityManagerPtr *sec_managers = NULL;
|
||||||
|
/* Security driver data */
|
||||||
|
const char *doi, *model;
|
||||||
|
|
||||||
/* Basic host arch / guest machine capabilities */
|
/* Basic host arch / guest machine capabilities */
|
||||||
if (!(caps = qemuCapsInit(oldcaps))) {
|
if (!(caps = qemuCapsInit(oldcaps))) {
|
||||||
@ -316,31 +320,38 @@ qemuCreateCapabilities(virCapsPtr oldcaps,
|
|||||||
goto err_exit;
|
goto err_exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Security driver data */
|
/* access sec drivers and create a sec model for each one */
|
||||||
const char *doi, *model;
|
sec_managers = virSecurityManagerGetNested(driver->securityManager);
|
||||||
|
if (sec_managers == NULL) {
|
||||||
|
goto err_exit;
|
||||||
|
}
|
||||||
|
|
||||||
doi = virSecurityManagerGetDOI(driver->securityManager);
|
/* calculate length */
|
||||||
model = virSecurityManagerGetModel(driver->securityManager);
|
for (i = 0; sec_managers[i]; i++)
|
||||||
|
;
|
||||||
|
caps->host.nsecModels = i;
|
||||||
|
|
||||||
if (VIR_ALLOC(caps->host.secModels) < 0) {
|
if (VIR_ALLOC_N(caps->host.secModels, caps->host.nsecModels) < 0)
|
||||||
goto no_memory;
|
goto no_memory;
|
||||||
}
|
|
||||||
|
|
||||||
if (STRNEQ(model, "none")) {
|
for (i = 0; sec_managers[i]; i++) {
|
||||||
if (!(caps->host.secModels[0].model = strdup(model)))
|
doi = virSecurityManagerGetDOI(sec_managers[i]);
|
||||||
|
model = virSecurityManagerGetModel(sec_managers[i]);
|
||||||
|
if (!(caps->host.secModels[i].model = strdup(model)))
|
||||||
goto no_memory;
|
goto no_memory;
|
||||||
if (!(caps->host.secModels[0].doi = strdup(doi)))
|
if (!(caps->host.secModels[i].doi = strdup(doi)))
|
||||||
goto no_memory;
|
goto no_memory;
|
||||||
|
VIR_DEBUG("Initialized caps for security driver \"%s\" with "
|
||||||
|
"DOI \"%s\"", model, doi);
|
||||||
}
|
}
|
||||||
|
VIR_FREE(sec_managers);
|
||||||
VIR_DEBUG("Initialized caps for security driver \"%s\" with "
|
|
||||||
"DOI \"%s\"", model, doi);
|
|
||||||
|
|
||||||
return caps;
|
return caps;
|
||||||
|
|
||||||
no_memory:
|
no_memory:
|
||||||
virReportOOMError();
|
virReportOOMError();
|
||||||
err_exit:
|
err_exit:
|
||||||
|
VIR_FREE(sec_managers);
|
||||||
virCapabilitiesFree(caps);
|
virCapabilitiesFree(caps);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@ -4063,9 +4074,9 @@ static int qemudNodeGetSecurityModel(virConnectPtr conn,
|
|||||||
qemuDriverLock(driver);
|
qemuDriverLock(driver);
|
||||||
memset(secmodel, 0, sizeof(*secmodel));
|
memset(secmodel, 0, sizeof(*secmodel));
|
||||||
|
|
||||||
/* NULL indicates no driver, which we treat as
|
/* We treat no driver as success, but simply return no data in *secmodel */
|
||||||
* success, but simply return no data in *secmodel */
|
if (driver->caps->host.nsecModels == 0 ||
|
||||||
if (driver->caps->host.secModels[0].model == NULL)
|
driver->caps->host.secModels[0].model == NULL)
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
|
||||||
p = driver->caps->host.secModels[0].model;
|
p = driver->caps->host.secModels[0].model;
|
||||||
|
@ -4079,12 +4079,12 @@ void qemuProcessStop(struct qemud_driver *driver,
|
|||||||
virSecurityManagerReleaseLabel(driver->securityManager, vm->def);
|
virSecurityManagerReleaseLabel(driver->securityManager, vm->def);
|
||||||
|
|
||||||
/* Clear out dynamically assigned labels */
|
/* Clear out dynamically assigned labels */
|
||||||
if (vm->def->seclabels[0]->type == VIR_DOMAIN_SECLABEL_DYNAMIC) {
|
for (i = 0; i < vm->def->nseclabels; i++) {
|
||||||
if (!vm->def->seclabels[0]->baselabel)
|
if (vm->def->seclabels[i]->type == VIR_DOMAIN_SECLABEL_DYNAMIC) {
|
||||||
VIR_FREE(vm->def->seclabels[0]->model);
|
VIR_FREE(vm->def->seclabels[i]->label);
|
||||||
VIR_FREE(vm->def->seclabels[0]->label);
|
}
|
||||||
|
VIR_FREE(vm->def->seclabels[i]->imagelabel);
|
||||||
}
|
}
|
||||||
VIR_FREE(vm->def->seclabels[0]->imagelabel);
|
|
||||||
|
|
||||||
virDomainDefClearDeviceAliases(vm->def);
|
virDomainDefClearDeviceAliases(vm->def);
|
||||||
if (!priv->persistentAddrs) {
|
if (!priv->persistentAddrs) {
|
||||||
@ -4188,6 +4188,7 @@ int qemuProcessAttach(virConnectPtr conn ATTRIBUTE_UNUSED,
|
|||||||
virDomainChrSourceDefPtr monConfig,
|
virDomainChrSourceDefPtr monConfig,
|
||||||
bool monJSON)
|
bool monJSON)
|
||||||
{
|
{
|
||||||
|
size_t i;
|
||||||
char ebuf[1024];
|
char ebuf[1024];
|
||||||
int logfile = -1;
|
int logfile = -1;
|
||||||
char *timestamp;
|
char *timestamp;
|
||||||
@ -4195,6 +4196,9 @@ int qemuProcessAttach(virConnectPtr conn ATTRIBUTE_UNUSED,
|
|||||||
bool running = true;
|
bool running = true;
|
||||||
virDomainPausedReason reason;
|
virDomainPausedReason reason;
|
||||||
virSecurityLabelPtr seclabel = NULL;
|
virSecurityLabelPtr seclabel = NULL;
|
||||||
|
virSecurityLabelDefPtr seclabeldef = NULL;
|
||||||
|
virSecurityManagerPtr* sec_managers = NULL;
|
||||||
|
const char *model;
|
||||||
|
|
||||||
VIR_DEBUG("Beginning VM attach process");
|
VIR_DEBUG("Beginning VM attach process");
|
||||||
|
|
||||||
@ -4227,17 +4231,31 @@ int qemuProcessAttach(virConnectPtr conn ATTRIBUTE_UNUSED,
|
|||||||
goto no_memory;
|
goto no_memory;
|
||||||
|
|
||||||
VIR_DEBUG("Detect security driver config");
|
VIR_DEBUG("Detect security driver config");
|
||||||
vm->def->seclabels[0]->type = VIR_DOMAIN_SECLABEL_STATIC;
|
sec_managers = virSecurityManagerGetNested(driver->securityManager);
|
||||||
if (VIR_ALLOC(seclabel) < 0)
|
if (sec_managers == NULL) {
|
||||||
goto no_memory;
|
|
||||||
if (virSecurityManagerGetProcessLabel(driver->securityManager,
|
|
||||||
vm->def, vm->pid, seclabel) < 0)
|
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
if (driver->caps->host.secModels[0].model &&
|
}
|
||||||
!(vm->def->seclabels[0]->model = strdup(driver->caps->host.secModels[0].model)))
|
|
||||||
goto no_memory;
|
for (i = 0; sec_managers[i]; i++) {
|
||||||
if (!(vm->def->seclabels[0]->label = strdup(seclabel->label)))
|
model = virSecurityManagerGetModel(sec_managers[i]);
|
||||||
goto no_memory;
|
seclabeldef = virDomainDefGetSecurityLabelDef(vm->def, model);
|
||||||
|
if (seclabeldef == NULL) {
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
seclabeldef->type = VIR_DOMAIN_SECLABEL_STATIC;
|
||||||
|
if (VIR_ALLOC(seclabel) < 0)
|
||||||
|
goto no_memory;
|
||||||
|
if (virSecurityManagerGetProcessLabel(driver->securityManager,
|
||||||
|
vm->def, vm->pid, seclabel) < 0)
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
|
if (!(seclabeldef->model = strdup(model)))
|
||||||
|
goto no_memory;
|
||||||
|
|
||||||
|
if (!(seclabeldef->label = strdup(seclabel->label)))
|
||||||
|
goto no_memory;
|
||||||
|
VIR_FREE(seclabel);
|
||||||
|
}
|
||||||
|
|
||||||
VIR_DEBUG("Creating domain log file");
|
VIR_DEBUG("Creating domain log file");
|
||||||
if ((logfile = qemuDomainCreateLog(driver, vm, false)) < 0)
|
if ((logfile = qemuDomainCreateLog(driver, vm, false)) < 0)
|
||||||
@ -4362,6 +4380,7 @@ int qemuProcessAttach(virConnectPtr conn ATTRIBUTE_UNUSED,
|
|||||||
|
|
||||||
VIR_FORCE_CLOSE(logfile);
|
VIR_FORCE_CLOSE(logfile);
|
||||||
VIR_FREE(seclabel);
|
VIR_FREE(seclabel);
|
||||||
|
VIR_FREE(sec_managers);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
@ -4373,6 +4392,7 @@ cleanup:
|
|||||||
* pretend we never started it */
|
* pretend we never started it */
|
||||||
VIR_FORCE_CLOSE(logfile);
|
VIR_FORCE_CLOSE(logfile);
|
||||||
VIR_FREE(seclabel);
|
VIR_FREE(seclabel);
|
||||||
|
VIR_FREE(sec_managers);
|
||||||
virDomainChrSourceDefFree(monConfig);
|
virDomainChrSourceDefFree(monConfig);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -272,9 +272,13 @@ reload_profile(virSecurityManagerPtr mgr,
|
|||||||
const char *fn,
|
const char *fn,
|
||||||
bool append)
|
bool append)
|
||||||
{
|
{
|
||||||
const virSecurityLabelDefPtr secdef = &def->seclabel;
|
|
||||||
int rc = -1;
|
int rc = -1;
|
||||||
char *profile_name = NULL;
|
char *profile_name = NULL;
|
||||||
|
const virSecurityLabelDefPtr secdef = virDomainDefGetSecurityLabelDef(
|
||||||
|
def, SECURITY_APPARMOR_NAME);
|
||||||
|
|
||||||
|
if (!secdef)
|
||||||
|
return rc;
|
||||||
|
|
||||||
if (secdef->norelabel)
|
if (secdef->norelabel)
|
||||||
return 0;
|
return 0;
|
||||||
@ -308,10 +312,14 @@ AppArmorSetSecurityUSBLabel(usbDevice *dev ATTRIBUTE_UNUSED,
|
|||||||
virDomainDefPtr def = ptr->def;
|
virDomainDefPtr def = ptr->def;
|
||||||
|
|
||||||
if (reload_profile(ptr->mgr, def, file, true) < 0) {
|
if (reload_profile(ptr->mgr, def, file, true) < 0) {
|
||||||
const virSecurityLabelDefPtr secdef = &def->seclabel;
|
const virSecurityLabelDefPtr secdef = virDomainDefGetSecurityLabelDef(
|
||||||
|
def, SECURITY_APPARMOR_NAME);
|
||||||
|
if (!secdef) {
|
||||||
|
virReportOOMError();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
virReportError(VIR_ERR_INTERNAL_ERROR,
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
||||||
_("cannot update AppArmor profile "
|
_("cannot update AppArmor profile \'%s\'"),
|
||||||
"\'%s\'"),
|
|
||||||
secdef->imagelabel);
|
secdef->imagelabel);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@ -326,10 +334,14 @@ AppArmorSetSecurityPCILabel(pciDevice *dev ATTRIBUTE_UNUSED,
|
|||||||
virDomainDefPtr def = ptr->def;
|
virDomainDefPtr def = ptr->def;
|
||||||
|
|
||||||
if (reload_profile(ptr->mgr, def, file, true) < 0) {
|
if (reload_profile(ptr->mgr, def, file, true) < 0) {
|
||||||
const virSecurityLabelDefPtr secdef = &def->seclabel;
|
const virSecurityLabelDefPtr secdef = virDomainDefGetSecurityLabelDef(
|
||||||
|
def, SECURITY_APPARMOR_NAME);
|
||||||
|
if (!secdef) {
|
||||||
|
virReportOOMError();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
virReportError(VIR_ERR_INTERNAL_ERROR,
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
||||||
_("cannot update AppArmor profile "
|
_("cannot update AppArmor profile \'%s\'"),
|
||||||
"\'%s\'"),
|
|
||||||
secdef->imagelabel);
|
secdef->imagelabel);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@ -408,18 +420,23 @@ AppArmorGenSecurityLabel(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
|
|||||||
{
|
{
|
||||||
int rc = -1;
|
int rc = -1;
|
||||||
char *profile_name = NULL;
|
char *profile_name = NULL;
|
||||||
|
virSecurityLabelDefPtr secdef = virDomainDefGetSecurityLabelDef(def,
|
||||||
|
SECURITY_APPARMOR_NAME);
|
||||||
|
|
||||||
if (def->seclabel.type == VIR_DOMAIN_SECLABEL_STATIC)
|
if (!secdef)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if (secdef->type == VIR_DOMAIN_SECLABEL_STATIC)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (def->seclabel.baselabel) {
|
if (secdef->baselabel) {
|
||||||
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
|
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
|
||||||
"%s", _("Cannot set a base label with AppArmour"));
|
"%s", _("Cannot set a base label with AppArmour"));
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((def->seclabel.label) ||
|
if ((secdef->label) ||
|
||||||
(def->seclabel.model) || (def->seclabel.imagelabel)) {
|
(secdef->model) || (secdef->imagelabel)) {
|
||||||
virReportError(VIR_ERR_INTERNAL_ERROR,
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
||||||
"%s",
|
"%s",
|
||||||
_("security label already defined for VM"));
|
_("security label already defined for VM"));
|
||||||
@ -429,31 +446,31 @@ AppArmorGenSecurityLabel(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
|
|||||||
if ((profile_name = get_profile_name(def)) == NULL)
|
if ((profile_name = get_profile_name(def)) == NULL)
|
||||||
return rc;
|
return rc;
|
||||||
|
|
||||||
def->seclabel.label = strndup(profile_name, strlen(profile_name));
|
secdef->label = strndup(profile_name, strlen(profile_name));
|
||||||
if (!def->seclabel.label) {
|
if (!secdef->label) {
|
||||||
virReportOOMError();
|
virReportOOMError();
|
||||||
goto clean;
|
goto clean;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* set imagelabel the same as label (but we won't use it) */
|
/* set imagelabel the same as label (but we won't use it) */
|
||||||
def->seclabel.imagelabel = strndup(profile_name,
|
secdef->imagelabel = strndup(profile_name,
|
||||||
strlen(profile_name));
|
strlen(profile_name));
|
||||||
if (!def->seclabel.imagelabel) {
|
if (!secdef->imagelabel) {
|
||||||
virReportOOMError();
|
virReportOOMError();
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
|
||||||
def->seclabel.model = strdup(SECURITY_APPARMOR_NAME);
|
secdef->model = strdup(SECURITY_APPARMOR_NAME);
|
||||||
if (!def->seclabel.model) {
|
if (!secdef->model) {
|
||||||
virReportOOMError();
|
virReportOOMError();
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Now that we have a label, load the profile into the kernel. */
|
/* Now that we have a label, load the profile into the kernel. */
|
||||||
if (load_profile(mgr, def->seclabel.label, def, NULL, false) < 0) {
|
if (load_profile(mgr, secdef->label, def, NULL, false) < 0) {
|
||||||
virReportError(VIR_ERR_INTERNAL_ERROR,
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
||||||
_("cannot load AppArmor profile "
|
_("cannot load AppArmor profile "
|
||||||
"\'%s\'"), def->seclabel.label);
|
"\'%s\'"), secdef->label);
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -461,9 +478,9 @@ AppArmorGenSecurityLabel(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
|
|||||||
goto clean;
|
goto clean;
|
||||||
|
|
||||||
err:
|
err:
|
||||||
VIR_FREE(def->seclabel.label);
|
VIR_FREE(secdef->label);
|
||||||
VIR_FREE(def->seclabel.imagelabel);
|
VIR_FREE(secdef->imagelabel);
|
||||||
VIR_FREE(def->seclabel.model);
|
VIR_FREE(secdef->model);
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
VIR_FREE(profile_name);
|
VIR_FREE(profile_name);
|
||||||
@ -475,7 +492,12 @@ static int
|
|||||||
AppArmorSetSecurityAllLabel(virSecurityManagerPtr mgr,
|
AppArmorSetSecurityAllLabel(virSecurityManagerPtr mgr,
|
||||||
virDomainDefPtr def, const char *stdin_path)
|
virDomainDefPtr def, const char *stdin_path)
|
||||||
{
|
{
|
||||||
if (def->seclabel.norelabel)
|
virSecurityLabelDefPtr secdef = virDomainDefGetSecurityLabelDef(def,
|
||||||
|
SECURITY_APPARMOR_NAME);
|
||||||
|
if (!secdef)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if (secdef->norelabel)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
/* Reload the profile if stdin_path is specified. Note that
|
/* Reload the profile if stdin_path is specified. Note that
|
||||||
@ -528,7 +550,10 @@ static int
|
|||||||
AppArmorReleaseSecurityLabel(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
|
AppArmorReleaseSecurityLabel(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
|
||||||
virDomainDefPtr def)
|
virDomainDefPtr def)
|
||||||
{
|
{
|
||||||
const virSecurityLabelDefPtr secdef = &def->seclabel;
|
const virSecurityLabelDefPtr secdef = virDomainDefGetSecurityLabelDef(def,
|
||||||
|
SECURITY_APPARMOR_NAME);
|
||||||
|
if (!secdef)
|
||||||
|
return -1;
|
||||||
|
|
||||||
VIR_FREE(secdef->model);
|
VIR_FREE(secdef->model);
|
||||||
VIR_FREE(secdef->label);
|
VIR_FREE(secdef->label);
|
||||||
@ -543,8 +568,12 @@ AppArmorRestoreSecurityAllLabel(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
|
|||||||
virDomainDefPtr def,
|
virDomainDefPtr def,
|
||||||
int migrated ATTRIBUTE_UNUSED)
|
int migrated ATTRIBUTE_UNUSED)
|
||||||
{
|
{
|
||||||
const virSecurityLabelDefPtr secdef = &def->seclabel;
|
|
||||||
int rc = 0;
|
int rc = 0;
|
||||||
|
const virSecurityLabelDefPtr secdef =
|
||||||
|
virDomainDefGetSecurityLabelDef(def, SECURITY_APPARMOR_NAME);
|
||||||
|
|
||||||
|
if (!secdef)
|
||||||
|
return -1;
|
||||||
|
|
||||||
if (secdef->type == VIR_DOMAIN_SECLABEL_DYNAMIC) {
|
if (secdef->type == VIR_DOMAIN_SECLABEL_DYNAMIC) {
|
||||||
if ((rc = remove_profile(secdef->label)) != 0) {
|
if ((rc = remove_profile(secdef->label)) != 0) {
|
||||||
@ -562,9 +591,13 @@ AppArmorRestoreSecurityAllLabel(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
|
|||||||
static int
|
static int
|
||||||
AppArmorSetSecurityProcessLabel(virSecurityManagerPtr mgr, virDomainDefPtr def)
|
AppArmorSetSecurityProcessLabel(virSecurityManagerPtr mgr, virDomainDefPtr def)
|
||||||
{
|
{
|
||||||
const virSecurityLabelDefPtr secdef = &def->seclabel;
|
|
||||||
int rc = -1;
|
int rc = -1;
|
||||||
char *profile_name = NULL;
|
char *profile_name = NULL;
|
||||||
|
const virSecurityLabelDefPtr secdef =
|
||||||
|
virDomainDefGetSecurityLabelDef(def, SECURITY_APPARMOR_NAME);
|
||||||
|
|
||||||
|
if (!secdef)
|
||||||
|
return -1;
|
||||||
|
|
||||||
if ((profile_name = get_profile_name(def)) == NULL)
|
if ((profile_name = get_profile_name(def)) == NULL)
|
||||||
return rc;
|
return rc;
|
||||||
@ -631,9 +664,13 @@ static int
|
|||||||
AppArmorSetSecurityImageLabel(virSecurityManagerPtr mgr,
|
AppArmorSetSecurityImageLabel(virSecurityManagerPtr mgr,
|
||||||
virDomainDefPtr def, virDomainDiskDefPtr disk)
|
virDomainDefPtr def, virDomainDiskDefPtr disk)
|
||||||
{
|
{
|
||||||
const virSecurityLabelDefPtr secdef = &def->seclabel;
|
|
||||||
int rc = -1;
|
int rc = -1;
|
||||||
char *profile_name;
|
char *profile_name;
|
||||||
|
const virSecurityLabelDefPtr secdef =
|
||||||
|
virDomainDefGetSecurityLabelDef(def, SECURITY_APPARMOR_NAME);
|
||||||
|
|
||||||
|
if (!secdef)
|
||||||
|
return -1;
|
||||||
|
|
||||||
if (secdef->norelabel)
|
if (secdef->norelabel)
|
||||||
return 0;
|
return 0;
|
||||||
@ -676,7 +713,11 @@ static int
|
|||||||
AppArmorSecurityVerify(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
|
AppArmorSecurityVerify(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
|
||||||
virDomainDefPtr def)
|
virDomainDefPtr def)
|
||||||
{
|
{
|
||||||
const virSecurityLabelDefPtr secdef = &def->seclabel;
|
const virSecurityLabelDefPtr secdef =
|
||||||
|
virDomainDefGetSecurityLabelDef(def, SECURITY_APPARMOR_NAME);
|
||||||
|
|
||||||
|
if (!secdef)
|
||||||
|
return -1;
|
||||||
|
|
||||||
if (secdef->type == VIR_DOMAIN_SECLABEL_STATIC) {
|
if (secdef->type == VIR_DOMAIN_SECLABEL_STATIC) {
|
||||||
if (use_apparmor() < 0 || profile_status(secdef->label, 0) < 0) {
|
if (use_apparmor() < 0 || profile_status(secdef->label, 0) < 0) {
|
||||||
@ -704,9 +745,13 @@ AppArmorSetSecurityHostdevLabel(virSecurityManagerPtr mgr,
|
|||||||
virDomainHostdevDefPtr dev)
|
virDomainHostdevDefPtr dev)
|
||||||
|
|
||||||
{
|
{
|
||||||
const virSecurityLabelDefPtr secdef = &def->seclabel;
|
|
||||||
struct SDPDOP *ptr;
|
struct SDPDOP *ptr;
|
||||||
int ret = -1;
|
int ret = -1;
|
||||||
|
const virSecurityLabelDefPtr secdef =
|
||||||
|
virDomainDefGetSecurityLabelDef(def, SECURITY_APPARMOR_NAME);
|
||||||
|
|
||||||
|
if (!secdef)
|
||||||
|
return -1;
|
||||||
|
|
||||||
if (secdef->norelabel)
|
if (secdef->norelabel)
|
||||||
return 0;
|
return 0;
|
||||||
@ -766,7 +811,12 @@ AppArmorRestoreSecurityHostdevLabel(virSecurityManagerPtr mgr,
|
|||||||
virDomainHostdevDefPtr dev ATTRIBUTE_UNUSED)
|
virDomainHostdevDefPtr dev ATTRIBUTE_UNUSED)
|
||||||
|
|
||||||
{
|
{
|
||||||
const virSecurityLabelDefPtr secdef = &def->seclabel;
|
const virSecurityLabelDefPtr secdef =
|
||||||
|
virDomainDefGetSecurityLabelDef(def, SECURITY_APPARMOR_NAME);
|
||||||
|
|
||||||
|
if (!secdef)
|
||||||
|
return -1;
|
||||||
|
|
||||||
if (secdef->norelabel)
|
if (secdef->norelabel)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
@ -799,7 +849,11 @@ AppArmorSetImageFDLabel(virSecurityManagerPtr mgr,
|
|||||||
char *proc = NULL;
|
char *proc = NULL;
|
||||||
char *fd_path = NULL;
|
char *fd_path = NULL;
|
||||||
|
|
||||||
const virSecurityLabelDefPtr secdef = &def->seclabel;
|
const virSecurityLabelDefPtr secdef =
|
||||||
|
virDomainDefGetSecurityLabelDef(def, SECURITY_APPARMOR_NAME);
|
||||||
|
|
||||||
|
if (!secdef)
|
||||||
|
return -1;
|
||||||
|
|
||||||
if (secdef->imagelabel == NULL)
|
if (secdef->imagelabel == NULL)
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -33,6 +33,7 @@
|
|||||||
#include "storage_file.h"
|
#include "storage_file.h"
|
||||||
|
|
||||||
#define VIR_FROM_THIS VIR_FROM_SECURITY
|
#define VIR_FROM_THIS VIR_FROM_SECURITY
|
||||||
|
#define SECURITY_DAC_NAME "dac"
|
||||||
|
|
||||||
typedef struct _virSecurityDACData virSecurityDACData;
|
typedef struct _virSecurityDACData virSecurityDACData;
|
||||||
typedef virSecurityDACData *virSecurityDACDataPtr;
|
typedef virSecurityDACData *virSecurityDACDataPtr;
|
||||||
@ -64,6 +65,134 @@ void virSecurityDACSetDynamicOwnership(virSecurityManagerPtr mgr,
|
|||||||
priv->dynamicOwnership = dynamicOwnership;
|
priv->dynamicOwnership = dynamicOwnership;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
int parseIds(const char *label, uid_t *uidPtr, gid_t *gidPtr)
|
||||||
|
{
|
||||||
|
uid_t uid;
|
||||||
|
gid_t gid;
|
||||||
|
char *endptr = NULL;
|
||||||
|
|
||||||
|
if (label == NULL)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if (virStrToLong_ui(label, &endptr, 10, &uid) ||
|
||||||
|
endptr == NULL || *endptr != ':') {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (virStrToLong_ui(endptr + 1, NULL, 10, &gid))
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if (uidPtr)
|
||||||
|
*uidPtr = uid;
|
||||||
|
if (gidPtr)
|
||||||
|
*gidPtr = gid;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
int virSecurityDACParseIds(virDomainDefPtr def, uid_t *uidPtr, gid_t *gidPtr)
|
||||||
|
{
|
||||||
|
uid_t uid;
|
||||||
|
gid_t gid;
|
||||||
|
virSecurityLabelDefPtr seclabel;
|
||||||
|
|
||||||
|
if (def == NULL)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
seclabel = virDomainDefGetSecurityLabelDef(def, SECURITY_DAC_NAME);
|
||||||
|
if (seclabel == NULL) {
|
||||||
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
||||||
|
_("security label for DAC not found in domain %s"),
|
||||||
|
def->name);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (seclabel->label && parseIds(seclabel->label, &uid, &gid)) {
|
||||||
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
||||||
|
_("failed to parse uid and gid for DAC "
|
||||||
|
"security driver: %s"), seclabel->label);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (uidPtr)
|
||||||
|
*uidPtr = uid;
|
||||||
|
if (gidPtr)
|
||||||
|
*gidPtr = gid;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
int virSecurityDACGetIds(virDomainDefPtr def, virSecurityDACDataPtr priv,
|
||||||
|
uid_t *uidPtr, gid_t *gidPtr)
|
||||||
|
{
|
||||||
|
if (virSecurityDACParseIds(def, uidPtr, gidPtr) == 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (priv) {
|
||||||
|
if (uidPtr)
|
||||||
|
*uidPtr = priv->user;
|
||||||
|
if (gidPtr)
|
||||||
|
*gidPtr = priv->group;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
int virSecurityDACParseImageIds(virDomainDefPtr def,
|
||||||
|
uid_t *uidPtr, gid_t *gidPtr)
|
||||||
|
{
|
||||||
|
uid_t uid;
|
||||||
|
gid_t gid;
|
||||||
|
virSecurityLabelDefPtr seclabel;
|
||||||
|
|
||||||
|
if (def == NULL)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
seclabel = virDomainDefGetSecurityLabelDef(def, SECURITY_DAC_NAME);
|
||||||
|
if (seclabel == NULL) {
|
||||||
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
||||||
|
_("security label for DAC not found in domain %s"),
|
||||||
|
def->name);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (seclabel->imagelabel
|
||||||
|
&& parseIds(seclabel->imagelabel, &uid, &gid)) {
|
||||||
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
||||||
|
_("failed to parse uid and gid for DAC "
|
||||||
|
"security driver: %s"), seclabel->label);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (uidPtr)
|
||||||
|
*uidPtr = uid;
|
||||||
|
if (gidPtr)
|
||||||
|
*gidPtr = gid;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
int virSecurityDACGetImageIds(virDomainDefPtr def, virSecurityDACDataPtr priv,
|
||||||
|
uid_t *uidPtr, gid_t *gidPtr)
|
||||||
|
{
|
||||||
|
if (virSecurityDACParseImageIds(def, uidPtr, gidPtr) == 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (priv) {
|
||||||
|
if (uidPtr)
|
||||||
|
*uidPtr = priv->user;
|
||||||
|
if (gidPtr)
|
||||||
|
*gidPtr = priv->group;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static virSecurityDriverStatus
|
static virSecurityDriverStatus
|
||||||
virSecurityDACProbe(const char *virtDriver ATTRIBUTE_UNUSED)
|
virSecurityDACProbe(const char *virtDriver ATTRIBUTE_UNUSED)
|
||||||
{
|
{
|
||||||
@ -85,7 +214,7 @@ virSecurityDACClose(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED)
|
|||||||
|
|
||||||
static const char * virSecurityDACGetModel(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED)
|
static const char * virSecurityDACGetModel(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED)
|
||||||
{
|
{
|
||||||
return "dac";
|
return SECURITY_DAC_NAME;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const char * virSecurityDACGetDOI(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED)
|
static const char * virSecurityDACGetDOI(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED)
|
||||||
@ -167,10 +296,17 @@ virSecurityDACSetSecurityFileLabel(virDomainDiskDefPtr disk ATTRIBUTE_UNUSED,
|
|||||||
size_t depth ATTRIBUTE_UNUSED,
|
size_t depth ATTRIBUTE_UNUSED,
|
||||||
void *opaque)
|
void *opaque)
|
||||||
{
|
{
|
||||||
virSecurityManagerPtr mgr = opaque;
|
void **params = opaque;
|
||||||
|
virSecurityManagerPtr mgr = params[0];
|
||||||
|
virDomainDefPtr def = params[1];
|
||||||
virSecurityDACDataPtr priv = virSecurityManagerGetPrivateData(mgr);
|
virSecurityDACDataPtr priv = virSecurityManagerGetPrivateData(mgr);
|
||||||
|
uid_t user;
|
||||||
|
gid_t group;
|
||||||
|
|
||||||
return virSecurityDACSetOwnership(path, priv->user, priv->group);
|
if (virSecurityDACGetImageIds(def, priv, &user, &group))
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
return virSecurityDACSetOwnership(path, user, group);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -180,6 +316,9 @@ virSecurityDACSetSecurityImageLabel(virSecurityManagerPtr mgr,
|
|||||||
virDomainDiskDefPtr disk)
|
virDomainDiskDefPtr disk)
|
||||||
|
|
||||||
{
|
{
|
||||||
|
uid_t user;
|
||||||
|
gid_t group;
|
||||||
|
void *params[2];
|
||||||
virSecurityDACDataPtr priv = virSecurityManagerGetPrivateData(mgr);
|
virSecurityDACDataPtr priv = virSecurityManagerGetPrivateData(mgr);
|
||||||
|
|
||||||
if (!priv->dynamicOwnership)
|
if (!priv->dynamicOwnership)
|
||||||
@ -188,12 +327,17 @@ virSecurityDACSetSecurityImageLabel(virSecurityManagerPtr mgr,
|
|||||||
if (disk->type == VIR_DOMAIN_DISK_TYPE_NETWORK)
|
if (disk->type == VIR_DOMAIN_DISK_TYPE_NETWORK)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
if (virSecurityDACGetImageIds(def, priv, &user, &group))
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
params[0] = mgr;
|
||||||
|
params[1] = def;
|
||||||
return virDomainDiskDefForeachPath(disk,
|
return virDomainDiskDefForeachPath(disk,
|
||||||
virSecurityManagerGetAllowDiskFormatProbing(mgr),
|
virSecurityManagerGetAllowDiskFormatProbing(mgr),
|
||||||
false,
|
false,
|
||||||
priv->user, priv->group,
|
user, group,
|
||||||
virSecurityDACSetSecurityFileLabel,
|
virSecurityDACSetSecurityFileLabel,
|
||||||
mgr);
|
params);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -259,10 +403,17 @@ virSecurityDACSetSecurityPCILabel(pciDevice *dev ATTRIBUTE_UNUSED,
|
|||||||
const char *file,
|
const char *file,
|
||||||
void *opaque)
|
void *opaque)
|
||||||
{
|
{
|
||||||
virSecurityManagerPtr mgr = opaque;
|
void **params = opaque;
|
||||||
|
virSecurityManagerPtr mgr = params[0];
|
||||||
|
virDomainDefPtr def = params[1];
|
||||||
virSecurityDACDataPtr priv = virSecurityManagerGetPrivateData(mgr);
|
virSecurityDACDataPtr priv = virSecurityManagerGetPrivateData(mgr);
|
||||||
|
uid_t user;
|
||||||
|
gid_t group;
|
||||||
|
|
||||||
return virSecurityDACSetOwnership(file, priv->user, priv->group);
|
if (virSecurityDACGetIds(def, priv, &user, &group))
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
return virSecurityDACSetOwnership(file, user, group);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -271,18 +422,26 @@ virSecurityDACSetSecurityUSBLabel(usbDevice *dev ATTRIBUTE_UNUSED,
|
|||||||
const char *file,
|
const char *file,
|
||||||
void *opaque)
|
void *opaque)
|
||||||
{
|
{
|
||||||
virSecurityManagerPtr mgr = opaque;
|
void **params = opaque;
|
||||||
|
virSecurityManagerPtr mgr = params[0];
|
||||||
|
virDomainDefPtr def = params[1];
|
||||||
virSecurityDACDataPtr priv = virSecurityManagerGetPrivateData(mgr);
|
virSecurityDACDataPtr priv = virSecurityManagerGetPrivateData(mgr);
|
||||||
|
uid_t user;
|
||||||
|
gid_t group;
|
||||||
|
|
||||||
return virSecurityDACSetOwnership(file, priv->user, priv->group);
|
if (virSecurityDACGetIds(def, priv, &user, &group))
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
return virSecurityDACSetOwnership(file, user, group);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
virSecurityDACSetSecurityHostdevLabel(virSecurityManagerPtr mgr,
|
virSecurityDACSetSecurityHostdevLabel(virSecurityManagerPtr mgr,
|
||||||
virDomainDefPtr def ATTRIBUTE_UNUSED,
|
virDomainDefPtr def,
|
||||||
virDomainHostdevDefPtr dev)
|
virDomainHostdevDefPtr dev)
|
||||||
{
|
{
|
||||||
|
void *params[] = {mgr, def};
|
||||||
virSecurityDACDataPtr priv = virSecurityManagerGetPrivateData(mgr);
|
virSecurityDACDataPtr priv = virSecurityManagerGetPrivateData(mgr);
|
||||||
int ret = -1;
|
int ret = -1;
|
||||||
|
|
||||||
@ -300,7 +459,8 @@ virSecurityDACSetSecurityHostdevLabel(virSecurityManagerPtr mgr,
|
|||||||
if (!usb)
|
if (!usb)
|
||||||
goto done;
|
goto done;
|
||||||
|
|
||||||
ret = usbDeviceFileIterate(usb, virSecurityDACSetSecurityUSBLabel, mgr);
|
ret = usbDeviceFileIterate(usb, virSecurityDACSetSecurityUSBLabel,
|
||||||
|
params);
|
||||||
usbFreeDevice(usb);
|
usbFreeDevice(usb);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -314,7 +474,8 @@ virSecurityDACSetSecurityHostdevLabel(virSecurityManagerPtr mgr,
|
|||||||
if (!pci)
|
if (!pci)
|
||||||
goto done;
|
goto done;
|
||||||
|
|
||||||
ret = pciDeviceFileIterate(pci, virSecurityDACSetSecurityPCILabel, mgr);
|
ret = pciDeviceFileIterate(pci, virSecurityDACSetSecurityPCILabel,
|
||||||
|
params);
|
||||||
pciFreeDevice(pci);
|
pciFreeDevice(pci);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
@ -404,17 +565,23 @@ done:
|
|||||||
|
|
||||||
static int
|
static int
|
||||||
virSecurityDACSetChardevLabel(virSecurityManagerPtr mgr,
|
virSecurityDACSetChardevLabel(virSecurityManagerPtr mgr,
|
||||||
|
virDomainDefPtr def,
|
||||||
virDomainChrSourceDefPtr dev)
|
virDomainChrSourceDefPtr dev)
|
||||||
|
|
||||||
{
|
{
|
||||||
virSecurityDACDataPtr priv = virSecurityManagerGetPrivateData(mgr);
|
virSecurityDACDataPtr priv = virSecurityManagerGetPrivateData(mgr);
|
||||||
char *in = NULL, *out = NULL;
|
char *in = NULL, *out = NULL;
|
||||||
int ret = -1;
|
int ret = -1;
|
||||||
|
uid_t user;
|
||||||
|
gid_t group;
|
||||||
|
|
||||||
|
if (virSecurityDACGetIds(def, priv, &user, &group))
|
||||||
|
return -1;
|
||||||
|
|
||||||
switch (dev->type) {
|
switch (dev->type) {
|
||||||
case VIR_DOMAIN_CHR_TYPE_DEV:
|
case VIR_DOMAIN_CHR_TYPE_DEV:
|
||||||
case VIR_DOMAIN_CHR_TYPE_FILE:
|
case VIR_DOMAIN_CHR_TYPE_FILE:
|
||||||
ret = virSecurityDACSetOwnership(dev->data.file.path, priv->user, priv->group);
|
ret = virSecurityDACSetOwnership(dev->data.file.path, user, group);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case VIR_DOMAIN_CHR_TYPE_PIPE:
|
case VIR_DOMAIN_CHR_TYPE_PIPE:
|
||||||
@ -424,12 +591,12 @@ virSecurityDACSetChardevLabel(virSecurityManagerPtr mgr,
|
|||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
if (virFileExists(in) && virFileExists(out)) {
|
if (virFileExists(in) && virFileExists(out)) {
|
||||||
if ((virSecurityDACSetOwnership(in, priv->user, priv->group) < 0) ||
|
if ((virSecurityDACSetOwnership(in, user, group) < 0) ||
|
||||||
(virSecurityDACSetOwnership(out, priv->user, priv->group) < 0)) {
|
(virSecurityDACSetOwnership(out, user, group) < 0)) {
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
} else if (virSecurityDACSetOwnership(dev->data.file.path,
|
} else if (virSecurityDACSetOwnership(dev->data.file.path,
|
||||||
priv->user, priv->group) < 0) {
|
user, group) < 0) {
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
ret = 0;
|
ret = 0;
|
||||||
@ -554,7 +721,7 @@ virSecurityDACSetChardevCallback(virDomainDefPtr def ATTRIBUTE_UNUSED,
|
|||||||
{
|
{
|
||||||
virSecurityManagerPtr mgr = opaque;
|
virSecurityManagerPtr mgr = opaque;
|
||||||
|
|
||||||
return virSecurityDACSetChardevLabel(mgr, &dev->source);
|
return virSecurityDACSetChardevLabel(mgr, def, &dev->source);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -565,6 +732,8 @@ virSecurityDACSetSecurityAllLabel(virSecurityManagerPtr mgr,
|
|||||||
{
|
{
|
||||||
virSecurityDACDataPtr priv = virSecurityManagerGetPrivateData(mgr);
|
virSecurityDACDataPtr priv = virSecurityManagerGetPrivateData(mgr);
|
||||||
int i;
|
int i;
|
||||||
|
uid_t user;
|
||||||
|
gid_t group;
|
||||||
|
|
||||||
if (!priv->dynamicOwnership)
|
if (!priv->dynamicOwnership)
|
||||||
return 0;
|
return 0;
|
||||||
@ -591,16 +760,15 @@ virSecurityDACSetSecurityAllLabel(virSecurityManagerPtr mgr,
|
|||||||
mgr) < 0)
|
mgr) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
|
if (virSecurityDACGetImageIds(def, priv, &user, &group))
|
||||||
|
return -1;
|
||||||
|
|
||||||
if (def->os.kernel &&
|
if (def->os.kernel &&
|
||||||
virSecurityDACSetOwnership(def->os.kernel,
|
virSecurityDACSetOwnership(def->os.kernel, user, group) < 0)
|
||||||
priv->user,
|
|
||||||
priv->group) < 0)
|
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
if (def->os.initrd &&
|
if (def->os.initrd &&
|
||||||
virSecurityDACSetOwnership(def->os.initrd,
|
virSecurityDACSetOwnership(def->os.initrd, user, group) < 0)
|
||||||
priv->user,
|
|
||||||
priv->group) < 0)
|
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@ -609,12 +777,17 @@ virSecurityDACSetSecurityAllLabel(virSecurityManagerPtr mgr,
|
|||||||
|
|
||||||
static int
|
static int
|
||||||
virSecurityDACSetSavedStateLabel(virSecurityManagerPtr mgr,
|
virSecurityDACSetSavedStateLabel(virSecurityManagerPtr mgr,
|
||||||
virDomainDefPtr def ATTRIBUTE_UNUSED,
|
virDomainDefPtr def,
|
||||||
const char *savefile)
|
const char *savefile)
|
||||||
{
|
{
|
||||||
|
uid_t user;
|
||||||
|
gid_t group;
|
||||||
virSecurityDACDataPtr priv = virSecurityManagerGetPrivateData(mgr);
|
virSecurityDACDataPtr priv = virSecurityManagerGetPrivateData(mgr);
|
||||||
|
|
||||||
return virSecurityDACSetOwnership(savefile, priv->user, priv->group);
|
if (virSecurityDACGetImageIds(def, priv, &user, &group))
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
return virSecurityDACSetOwnership(savefile, user, group);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -636,12 +809,16 @@ static int
|
|||||||
virSecurityDACSetProcessLabel(virSecurityManagerPtr mgr,
|
virSecurityDACSetProcessLabel(virSecurityManagerPtr mgr,
|
||||||
virDomainDefPtr def ATTRIBUTE_UNUSED)
|
virDomainDefPtr def ATTRIBUTE_UNUSED)
|
||||||
{
|
{
|
||||||
|
uid_t user;
|
||||||
|
gid_t group;
|
||||||
virSecurityDACDataPtr priv = virSecurityManagerGetPrivateData(mgr);
|
virSecurityDACDataPtr priv = virSecurityManagerGetPrivateData(mgr);
|
||||||
|
|
||||||
VIR_DEBUG("Dropping privileges of DEF to %u:%u",
|
if (virSecurityDACGetIds(def, priv, &user, &group))
|
||||||
(unsigned int) priv->user, (unsigned int) priv->group);
|
return -1;
|
||||||
|
|
||||||
if (virSetUIDGID(priv->user, priv->group) < 0)
|
VIR_DEBUG("Dropping privileges of DEF to %u:%u", user, group);
|
||||||
|
|
||||||
|
if (virSetUIDGID(user, group) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@ -656,9 +833,85 @@ virSecurityDACVerify(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
virSecurityDACGenLabel(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
|
virSecurityDACGenLabel(virSecurityManagerPtr mgr,
|
||||||
virDomainDefPtr def ATTRIBUTE_UNUSED)
|
virDomainDefPtr def)
|
||||||
{
|
{
|
||||||
|
int rc = -1;
|
||||||
|
virSecurityLabelDefPtr seclabel;
|
||||||
|
virSecurityDACDataPtr priv = virSecurityManagerGetPrivateData(mgr);
|
||||||
|
|
||||||
|
if (mgr == NULL) {
|
||||||
|
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
||||||
|
_("invalid security driver"));
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
seclabel = virDomainDefGetSecurityLabelDef(def, SECURITY_DAC_NAME);
|
||||||
|
if (seclabel == NULL) {
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (seclabel->imagelabel) {
|
||||||
|
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
||||||
|
_("security image label already "
|
||||||
|
"defined for VM"));
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (seclabel->model
|
||||||
|
&& STRNEQ(seclabel->model, SECURITY_DAC_NAME)) {
|
||||||
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
||||||
|
_("security label model %s is not supported "
|
||||||
|
"with selinux"),
|
||||||
|
seclabel->model);
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch(seclabel->type) {
|
||||||
|
case VIR_DOMAIN_SECLABEL_STATIC:
|
||||||
|
if (seclabel->label == NULL) {
|
||||||
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
||||||
|
_("missing label for static security "
|
||||||
|
"driver in domain %s"), def->name);
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case VIR_DOMAIN_SECLABEL_DYNAMIC:
|
||||||
|
if (virAsprintf(&seclabel->label, "%d:%d", priv->user, priv->group) < 0) {
|
||||||
|
virReportOOMError();
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
if (seclabel->label == NULL) {
|
||||||
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
||||||
|
_("cannot generate dac user and group id "
|
||||||
|
"for domain %s"), def->name);
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case VIR_DOMAIN_SECLABEL_NONE:
|
||||||
|
/* no op */
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
||||||
|
_("unexpected security label type '%s'"),
|
||||||
|
virDomainSeclabelTypeToString(seclabel->type));
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!seclabel->norelabel) {
|
||||||
|
if (seclabel->imagelabel == NULL) {
|
||||||
|
seclabel->imagelabel = strdup(seclabel->label);
|
||||||
|
if (seclabel->imagelabel == NULL) {
|
||||||
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
||||||
|
_("cannot generate dac user and group id "
|
||||||
|
"for domain %s"), def->name);
|
||||||
|
VIR_FREE(seclabel->label);
|
||||||
|
seclabel->label = NULL;
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -683,6 +936,15 @@ virSecurityDACGetProcessLabel(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
|
|||||||
pid_t pid ATTRIBUTE_UNUSED,
|
pid_t pid ATTRIBUTE_UNUSED,
|
||||||
virSecurityLabelPtr seclabel ATTRIBUTE_UNUSED)
|
virSecurityLabelPtr seclabel ATTRIBUTE_UNUSED)
|
||||||
{
|
{
|
||||||
|
virSecurityLabelDefPtr secdef =
|
||||||
|
virDomainDefGetSecurityLabelDef(def, SECURITY_DAC_NAME);
|
||||||
|
|
||||||
|
if (!secdef || !seclabel)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if (secdef->label)
|
||||||
|
strcpy(seclabel->label, secdef->label);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -724,7 +986,7 @@ static char *virSecurityDACGetMountOptions(virSecurityManagerPtr mgr ATTRIBUTE_U
|
|||||||
|
|
||||||
virSecurityDriver virSecurityDriverDAC = {
|
virSecurityDriver virSecurityDriverDAC = {
|
||||||
.privateDataLen = sizeof(virSecurityDACData),
|
.privateDataLen = sizeof(virSecurityDACData),
|
||||||
.name = "virDAC",
|
.name = SECURITY_DAC_NAME,
|
||||||
.probe = virSecurityDACProbe,
|
.probe = virSecurityDACProbe,
|
||||||
.open = virSecurityDACOpen,
|
.open = virSecurityDACOpen,
|
||||||
.close = virSecurityDACClose,
|
.close = virSecurityDACClose,
|
||||||
|
@ -68,8 +68,7 @@ static virSecurityManagerPtr virSecurityManagerNewDriver(virSecurityDriverPtr dr
|
|||||||
return mgr;
|
return mgr;
|
||||||
}
|
}
|
||||||
|
|
||||||
virSecurityManagerPtr virSecurityManagerNewStack(virSecurityManagerPtr primary,
|
virSecurityManagerPtr virSecurityManagerNewStack(virSecurityManagerPtr primary)
|
||||||
virSecurityManagerPtr secondary)
|
|
||||||
{
|
{
|
||||||
virSecurityManagerPtr mgr =
|
virSecurityManagerPtr mgr =
|
||||||
virSecurityManagerNewDriver(&virSecurityDriverStack,
|
virSecurityManagerNewDriver(&virSecurityDriverStack,
|
||||||
@ -81,12 +80,19 @@ virSecurityManagerPtr virSecurityManagerNewStack(virSecurityManagerPtr primary,
|
|||||||
if (!mgr)
|
if (!mgr)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
virSecurityStackSetPrimary(mgr, primary);
|
virSecurityStackAddPrimary(mgr, primary);
|
||||||
virSecurityStackSetSecondary(mgr, secondary);
|
|
||||||
|
|
||||||
return mgr;
|
return mgr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int virSecurityManagerStackAddNested(virSecurityManagerPtr stack,
|
||||||
|
virSecurityManagerPtr nested)
|
||||||
|
{
|
||||||
|
if (!STREQ("stack", stack->drv->name))
|
||||||
|
return -1;
|
||||||
|
return virSecurityStackAddNested(stack, nested);
|
||||||
|
}
|
||||||
|
|
||||||
virSecurityManagerPtr virSecurityManagerNewDAC(const char *virtDriver,
|
virSecurityManagerPtr virSecurityManagerNewDAC(const char *virtDriver,
|
||||||
uid_t user,
|
uid_t user,
|
||||||
gid_t group,
|
gid_t group,
|
||||||
@ -308,27 +314,52 @@ int virSecurityManagerRestoreSavedStateLabel(virSecurityManagerPtr mgr,
|
|||||||
int virSecurityManagerGenLabel(virSecurityManagerPtr mgr,
|
int virSecurityManagerGenLabel(virSecurityManagerPtr mgr,
|
||||||
virDomainDefPtr vm)
|
virDomainDefPtr vm)
|
||||||
{
|
{
|
||||||
if (vm->seclabels[0]->type == VIR_DOMAIN_SECLABEL_DEFAULT) {
|
int rc = 0;
|
||||||
if (mgr->defaultConfined) {
|
size_t i;
|
||||||
vm->seclabels[0]->type = VIR_DOMAIN_SECLABEL_DYNAMIC;
|
virSecurityManagerPtr* sec_managers = NULL;
|
||||||
|
virSecurityLabelDefPtr seclabel;
|
||||||
|
|
||||||
|
if (mgr == NULL || mgr->drv == NULL)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if ((sec_managers = virSecurityManagerGetNested(mgr)) == NULL)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
for (i = 0; sec_managers[i]; i++) {
|
||||||
|
seclabel = virDomainDefGetSecurityLabelDef(vm,
|
||||||
|
sec_managers[i]->drv->name);
|
||||||
|
if (seclabel == NULL) {
|
||||||
|
rc = -1;
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (seclabel->type == VIR_DOMAIN_SECLABEL_DEFAULT) {
|
||||||
|
if (sec_managers[i]->defaultConfined)
|
||||||
|
seclabel->type = VIR_DOMAIN_SECLABEL_DYNAMIC;
|
||||||
|
else
|
||||||
|
seclabel->type = VIR_DOMAIN_SECLABEL_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((seclabel->type == VIR_DOMAIN_SECLABEL_NONE) &&
|
||||||
|
sec_managers[i]->requireConfined) {
|
||||||
|
virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
|
||||||
|
_("Unconfined guests are not allowed on this host"));
|
||||||
|
rc = -1;
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!sec_managers[i]->drv->domainGenSecurityLabel) {
|
||||||
|
virReportError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
|
||||||
} else {
|
} else {
|
||||||
vm->seclabels[0]->type = VIR_DOMAIN_SECLABEL_NONE;
|
rc += sec_managers[i]->drv->domainGenSecurityLabel(sec_managers[i], vm);
|
||||||
vm->seclabels[0]->norelabel = true;
|
if (rc)
|
||||||
|
goto cleanup;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((vm->seclabels[0]->type == VIR_DOMAIN_SECLABEL_NONE) &&
|
cleanup:
|
||||||
mgr->requireConfined) {
|
VIR_FREE(sec_managers);
|
||||||
virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
|
return rc;
|
||||||
_("Unconfined guests are not allowed on this host"));
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mgr->drv->domainGenSecurityLabel)
|
|
||||||
return mgr->drv->domainGenSecurityLabel(mgr, vm);
|
|
||||||
|
|
||||||
virReportError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
|
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int virSecurityManagerReserveLabel(virSecurityManagerPtr mgr,
|
int virSecurityManagerReserveLabel(virSecurityManagerPtr mgr,
|
||||||
@ -399,12 +430,17 @@ int virSecurityManagerSetProcessLabel(virSecurityManagerPtr mgr,
|
|||||||
int virSecurityManagerVerify(virSecurityManagerPtr mgr,
|
int virSecurityManagerVerify(virSecurityManagerPtr mgr,
|
||||||
virDomainDefPtr def)
|
virDomainDefPtr def)
|
||||||
{
|
{
|
||||||
const virSecurityLabelDefPtr secdef = def->seclabels[0];
|
virSecurityLabelDefPtr secdef;
|
||||||
|
|
||||||
|
if (mgr == NULL || mgr->drv == NULL)
|
||||||
|
return 0;
|
||||||
|
|
||||||
/* NULL model == dynamic labelling, with whatever driver
|
/* NULL model == dynamic labelling, with whatever driver
|
||||||
* is active, so we can short circuit verify check to
|
* is active, so we can short circuit verify check to
|
||||||
* avoid drivers de-referencing NULLs by accident
|
* avoid drivers de-referencing NULLs by accident
|
||||||
*/
|
*/
|
||||||
if (!secdef->model)
|
secdef = virDomainDefGetSecurityLabelDef(def, mgr->drv->name);
|
||||||
|
if (secdef == NULL || secdef->model == NULL)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (mgr->drv->domainSecurityVerify)
|
if (mgr->drv->domainSecurityVerify)
|
||||||
@ -437,3 +473,22 @@ char *virSecurityManagerGetMountOptions(virSecurityManagerPtr mgr,
|
|||||||
*/
|
*/
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virSecurityManagerPtr*
|
||||||
|
virSecurityManagerGetNested(virSecurityManagerPtr mgr)
|
||||||
|
{
|
||||||
|
virSecurityManagerPtr* list = NULL;
|
||||||
|
|
||||||
|
if (STREQ("stack", mgr->drv->name)) {
|
||||||
|
return virSecurityStackGetNested(mgr);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (VIR_ALLOC_N(list, 2) < 0) {
|
||||||
|
virReportOOMError();
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
list[0] = mgr;
|
||||||
|
list[1] = NULL;
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
@ -34,8 +34,9 @@ virSecurityManagerPtr virSecurityManagerNew(const char *name,
|
|||||||
bool defaultConfined,
|
bool defaultConfined,
|
||||||
bool requireConfined);
|
bool requireConfined);
|
||||||
|
|
||||||
virSecurityManagerPtr virSecurityManagerNewStack(virSecurityManagerPtr primary,
|
virSecurityManagerPtr virSecurityManagerNewStack(virSecurityManagerPtr primary);
|
||||||
virSecurityManagerPtr secondary);
|
int virSecurityManagerStackAddNested(virSecurityManagerPtr stack,
|
||||||
|
virSecurityManagerPtr nested);
|
||||||
|
|
||||||
virSecurityManagerPtr virSecurityManagerNewDAC(const char *virtDriver,
|
virSecurityManagerPtr virSecurityManagerNewDAC(const char *virtDriver,
|
||||||
uid_t user,
|
uid_t user,
|
||||||
@ -106,4 +107,7 @@ int virSecurityManagerSetImageFDLabel(virSecurityManagerPtr mgr,
|
|||||||
int fd);
|
int fd);
|
||||||
char *virSecurityManagerGetMountOptions(virSecurityManagerPtr mgr,
|
char *virSecurityManagerGetMountOptions(virSecurityManagerPtr mgr,
|
||||||
virDomainDefPtr vm);
|
virDomainDefPtr vm);
|
||||||
|
virSecurityManagerPtr*
|
||||||
|
virSecurityManagerGetNested(virSecurityManagerPtr mgr);
|
||||||
|
|
||||||
#endif /* VIR_SECURITY_MANAGER_H__ */
|
#endif /* VIR_SECURITY_MANAGER_H__ */
|
||||||
|
@ -363,46 +363,52 @@ virSecuritySELinuxGenSecurityLabel(virSecurityManagerPtr mgr,
|
|||||||
char *scontext = NULL;
|
char *scontext = NULL;
|
||||||
context_t ctx = NULL;
|
context_t ctx = NULL;
|
||||||
const char *range;
|
const char *range;
|
||||||
virSecuritySELinuxDataPtr data = virSecurityManagerGetPrivateData(mgr);
|
virSecurityLabelDefPtr seclabel;
|
||||||
|
virSecuritySELinuxDataPtr data;
|
||||||
|
|
||||||
VIR_DEBUG("driver=%s", virSecurityManagerGetDriver(mgr));
|
if (mgr == NULL) {
|
||||||
if ((def->seclabels[0]->type == VIR_DOMAIN_SECLABEL_DYNAMIC) &&
|
|
||||||
!def->seclabels[0]->baselabel &&
|
|
||||||
def->seclabels[0]->model) {
|
|
||||||
virReportError(VIR_ERR_INTERNAL_ERROR,
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
||||||
"%s", _("security model already defined for VM"));
|
"%s", _("invalid security driver"));
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (def->seclabels[0]->type == VIR_DOMAIN_SECLABEL_DYNAMIC &&
|
seclabel = virDomainDefGetSecurityLabelDef(def, SECURITY_SELINUX_NAME);
|
||||||
def->seclabels[0]->label) {
|
if (seclabel == NULL) {
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
data = virSecurityManagerGetPrivateData(mgr);
|
||||||
|
|
||||||
|
VIR_DEBUG("label=%s", virSecurityManagerGetDriver(mgr));
|
||||||
|
if (seclabel->type == VIR_DOMAIN_SECLABEL_DYNAMIC &&
|
||||||
|
seclabel->label) {
|
||||||
virReportError(VIR_ERR_INTERNAL_ERROR,
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
||||||
"%s", _("security label already defined for VM"));
|
"%s", _("security label already defined for VM"));
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (def->seclabels[0]->imagelabel) {
|
if (seclabel->imagelabel) {
|
||||||
virReportError(VIR_ERR_INTERNAL_ERROR,
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
||||||
"%s", _("security image label already defined for VM"));
|
"%s", _("security image label already defined for VM"));
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (def->seclabels[0]->model &&
|
if (seclabel->model &&
|
||||||
STRNEQ(def->seclabels[0]->model, SECURITY_SELINUX_NAME)) {
|
STRNEQ(seclabel->model, SECURITY_SELINUX_NAME)) {
|
||||||
virReportError(VIR_ERR_INTERNAL_ERROR,
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
||||||
_("security label model %s is not supported with selinux"),
|
_("security label model %s is not supported with selinux"),
|
||||||
def->seclabels[0]->model);
|
seclabel->model);
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
VIR_DEBUG("type%d", def->seclabels[0]->type);
|
VIR_DEBUG("type=%d", seclabel->type);
|
||||||
|
|
||||||
switch (def->seclabels[0]->type) {
|
switch (seclabel->type) {
|
||||||
case VIR_DOMAIN_SECLABEL_STATIC:
|
case VIR_DOMAIN_SECLABEL_STATIC:
|
||||||
if (!(ctx = context_new(def->seclabels[0]->label)) ) {
|
if (!(ctx = context_new(seclabel->label)) ) {
|
||||||
virReportSystemError(errno,
|
virReportSystemError(errno,
|
||||||
_("unable to allocate socket security context '%s'"),
|
_("unable to allocate socket security context '%s'"),
|
||||||
def->seclabels[0]->label);
|
seclabel->label);
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -421,11 +427,11 @@ virSecuritySELinuxGenSecurityLabel(virSecurityManagerPtr mgr,
|
|||||||
if (virSecuritySELinuxMCSAdd(mgr, mcs) < 0)
|
if (virSecuritySELinuxMCSAdd(mgr, mcs) < 0)
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
|
||||||
def->seclabels[0]->label =
|
seclabel->label =
|
||||||
virSecuritySELinuxGenNewContext(def->seclabels[0]->baselabel ?
|
virSecuritySELinuxGenNewContext(seclabel->baselabel ?
|
||||||
def->seclabels[0]->baselabel :
|
seclabel->baselabel :
|
||||||
data->domain_context, mcs, false);
|
data->domain_context, mcs, false);
|
||||||
if (! def->seclabels[0]->label) {
|
if (!seclabel->label) {
|
||||||
virReportError(VIR_ERR_INTERNAL_ERROR,
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
||||||
_("cannot generate selinux context for %s"), mcs);
|
_("cannot generate selinux context for %s"), mcs);
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
@ -439,23 +445,23 @@ virSecuritySELinuxGenSecurityLabel(virSecurityManagerPtr mgr,
|
|||||||
default:
|
default:
|
||||||
virReportError(VIR_ERR_INTERNAL_ERROR,
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
||||||
_("unexpected security label type '%s'"),
|
_("unexpected security label type '%s'"),
|
||||||
virDomainSeclabelTypeToString(def->seclabels[0]->type));
|
virDomainSeclabelTypeToString(seclabel->type));
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!def->seclabels[0]->norelabel) {
|
if (!seclabel->norelabel) {
|
||||||
def->seclabels[0]->imagelabel = virSecuritySELinuxGenNewContext(data->file_context,
|
seclabel->imagelabel = virSecuritySELinuxGenNewContext(data->domain_context,
|
||||||
mcs,
|
mcs,
|
||||||
true);
|
true);
|
||||||
if (!def->seclabels[0]->imagelabel) {
|
if (!seclabel->imagelabel) {
|
||||||
virReportError(VIR_ERR_INTERNAL_ERROR,
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
||||||
_("cannot generate selinux context for %s"), mcs);
|
_("cannot generate selinux context for %s"), mcs);
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!def->seclabels[0]->model &&
|
if (!seclabel->model &&
|
||||||
!(def->seclabels[0]->model = strdup(SECURITY_SELINUX_NAME))) {
|
!(seclabel->model = strdup(SECURITY_SELINUX_NAME))) {
|
||||||
virReportOOMError();
|
virReportOOMError();
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
@ -464,12 +470,12 @@ virSecuritySELinuxGenSecurityLabel(virSecurityManagerPtr mgr,
|
|||||||
|
|
||||||
cleanup:
|
cleanup:
|
||||||
if (rc != 0) {
|
if (rc != 0) {
|
||||||
if (def->seclabels[0]->type == VIR_DOMAIN_SECLABEL_DYNAMIC)
|
if (seclabel->type == VIR_DOMAIN_SECLABEL_DYNAMIC)
|
||||||
VIR_FREE(def->seclabels[0]->label);
|
VIR_FREE(seclabel->label);
|
||||||
VIR_FREE(def->seclabels[0]->imagelabel);
|
VIR_FREE(seclabel->imagelabel);
|
||||||
if (def->seclabels[0]->type == VIR_DOMAIN_SECLABEL_DYNAMIC &&
|
if (seclabel->type == VIR_DOMAIN_SECLABEL_DYNAMIC &&
|
||||||
!def->seclabels[0]->baselabel)
|
!seclabel->baselabel)
|
||||||
VIR_FREE(def->seclabels[0]->model);
|
VIR_FREE(seclabel->model);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ctx)
|
if (ctx)
|
||||||
@ -478,10 +484,10 @@ cleanup:
|
|||||||
VIR_FREE(mcs);
|
VIR_FREE(mcs);
|
||||||
|
|
||||||
VIR_DEBUG("model=%s label=%s imagelabel=%s baselabel=%s",
|
VIR_DEBUG("model=%s label=%s imagelabel=%s baselabel=%s",
|
||||||
NULLSTR(def->seclabels[0]->model),
|
NULLSTR(seclabel->model),
|
||||||
NULLSTR(def->seclabels[0]->label),
|
NULLSTR(seclabel->label),
|
||||||
NULLSTR(def->seclabels[0]->imagelabel),
|
NULLSTR(seclabel->imagelabel),
|
||||||
NULLSTR(def->seclabels[0]->baselabel));
|
NULLSTR(seclabel->baselabel));
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
@ -495,8 +501,14 @@ virSecuritySELinuxReserveSecurityLabel(virSecurityManagerPtr mgr,
|
|||||||
context_t ctx = NULL;
|
context_t ctx = NULL;
|
||||||
const char *mcs;
|
const char *mcs;
|
||||||
int rv;
|
int rv;
|
||||||
|
virSecurityLabelDefPtr seclabel;
|
||||||
|
|
||||||
if (def->seclabels[0]->type == VIR_DOMAIN_SECLABEL_STATIC)
|
seclabel = virDomainDefGetSecurityLabelDef(def, SECURITY_SELINUX_NAME);
|
||||||
|
if (seclabel == NULL) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (seclabel->type == VIR_DOMAIN_SECLABEL_STATIC)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (getpidcon(pid, &pctx) == -1) {
|
if (getpidcon(pid, &pctx) == -1) {
|
||||||
@ -800,9 +812,16 @@ virSecuritySELinuxRestoreSecurityImageLabelInt(virSecurityManagerPtr mgr ATTRIBU
|
|||||||
virDomainDiskDefPtr disk,
|
virDomainDiskDefPtr disk,
|
||||||
int migrated)
|
int migrated)
|
||||||
{
|
{
|
||||||
const virSecurityLabelDefPtr secdef = def->seclabels[0];
|
virSecurityLabelDefPtr seclabel;
|
||||||
|
virSecurityDeviceLabelDefPtr disk_seclabel;
|
||||||
|
|
||||||
if (secdef->norelabel || (disk->seclabels[0] && disk->seclabels[0]->norelabel))
|
seclabel = virDomainDefGetSecurityLabelDef(def, SECURITY_SELINUX_NAME);
|
||||||
|
if (seclabel == NULL)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
disk_seclabel = virDomainDiskDefGetSecurityLabelDef(disk,
|
||||||
|
SECURITY_SELINUX_NAME);
|
||||||
|
if (seclabel->norelabel || (disk_seclabel && disk_seclabel->norelabel))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
/* Don't restore labels on readoly/shared disks, because
|
/* Don't restore labels on readoly/shared disks, because
|
||||||
@ -854,17 +873,21 @@ virSecuritySELinuxSetSecurityFileLabel(virDomainDiskDefPtr disk,
|
|||||||
size_t depth,
|
size_t depth,
|
||||||
void *opaque)
|
void *opaque)
|
||||||
{
|
{
|
||||||
|
int ret;
|
||||||
|
virSecurityDeviceLabelDefPtr disk_seclabel;
|
||||||
virSecuritySELinuxCallbackDataPtr cbdata = opaque;
|
virSecuritySELinuxCallbackDataPtr cbdata = opaque;
|
||||||
const virSecurityLabelDefPtr secdef = cbdata->secdef;
|
const virSecurityLabelDefPtr secdef = cbdata->secdef;
|
||||||
int ret;
|
|
||||||
virSecuritySELinuxDataPtr data = virSecurityManagerGetPrivateData(cbdata->manager);
|
virSecuritySELinuxDataPtr data = virSecurityManagerGetPrivateData(cbdata->manager);
|
||||||
|
|
||||||
if (disk->seclabels[0] && disk->seclabels[0]->norelabel)
|
disk_seclabel = virDomainDiskDefGetSecurityLabelDef(disk,
|
||||||
|
SECURITY_SELINUX_NAME);
|
||||||
|
|
||||||
|
if (disk_seclabel && disk_seclabel->norelabel)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (disk->seclabels[0] && !disk->seclabels[0]->norelabel &&
|
if (disk_seclabel && !disk_seclabel->norelabel &&
|
||||||
disk->seclabels[0]->label) {
|
disk_seclabel->label) {
|
||||||
ret = virSecuritySELinuxSetFilecon(path, disk->seclabels[0]->label);
|
ret = virSecuritySELinuxSetFilecon(path, disk_seclabel->label);
|
||||||
} else if (depth == 0) {
|
} else if (depth == 0) {
|
||||||
|
|
||||||
if (disk->shared) {
|
if (disk->shared) {
|
||||||
@ -879,14 +902,14 @@ virSecuritySELinuxSetSecurityFileLabel(virDomainDiskDefPtr disk,
|
|||||||
} else {
|
} else {
|
||||||
ret = virSecuritySELinuxSetFileconOptional(path, data->content_context);
|
ret = virSecuritySELinuxSetFileconOptional(path, data->content_context);
|
||||||
}
|
}
|
||||||
if (ret == 1 && !disk->seclabels[0]) {
|
if (ret == 1 && !disk_seclabel) {
|
||||||
/* If we failed to set a label, but virt_use_nfs let us
|
/* If we failed to set a label, but virt_use_nfs let us
|
||||||
* proceed anyway, then we don't need to relabel later. */
|
* proceed anyway, then we don't need to relabel later. */
|
||||||
if (VIR_ALLOC(disk->seclabels[0]) < 0) {
|
if (VIR_ALLOC(disk_seclabel) < 0) {
|
||||||
virReportOOMError();
|
virReportOOMError();
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
disk->seclabels[0]->norelabel = true;
|
disk_seclabel->norelabel = true;
|
||||||
ret = 0;
|
ret = 0;
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
@ -898,11 +921,15 @@ virSecuritySELinuxSetSecurityImageLabel(virSecurityManagerPtr mgr,
|
|||||||
virDomainDiskDefPtr disk)
|
virDomainDiskDefPtr disk)
|
||||||
|
|
||||||
{
|
{
|
||||||
|
bool allowDiskFormatProbing;
|
||||||
virSecuritySELinuxCallbackData cbdata;
|
virSecuritySELinuxCallbackData cbdata;
|
||||||
cbdata.secdef = def->seclabels[0];
|
|
||||||
cbdata.manager = mgr;
|
cbdata.manager = mgr;
|
||||||
|
cbdata.secdef = virDomainDefGetSecurityLabelDef(def, SECURITY_SELINUX_NAME);
|
||||||
|
|
||||||
bool allowDiskFormatProbing = virSecurityManagerGetAllowDiskFormatProbing(mgr);
|
allowDiskFormatProbing = virSecurityManagerGetAllowDiskFormatProbing(mgr);
|
||||||
|
|
||||||
|
if (cbdata.secdef == NULL)
|
||||||
|
return -1;
|
||||||
|
|
||||||
if (cbdata.secdef->norelabel)
|
if (cbdata.secdef->norelabel)
|
||||||
return 0;
|
return 0;
|
||||||
@ -929,9 +956,12 @@ static int
|
|||||||
virSecuritySELinuxSetSecurityPCILabel(pciDevice *dev ATTRIBUTE_UNUSED,
|
virSecuritySELinuxSetSecurityPCILabel(pciDevice *dev ATTRIBUTE_UNUSED,
|
||||||
const char *file, void *opaque)
|
const char *file, void *opaque)
|
||||||
{
|
{
|
||||||
|
virSecurityLabelDefPtr secdef;
|
||||||
virDomainDefPtr def = opaque;
|
virDomainDefPtr def = opaque;
|
||||||
const virSecurityLabelDefPtr secdef = def->seclabels[0];
|
|
||||||
|
|
||||||
|
secdef = virDomainDefGetSecurityLabelDef(def, SECURITY_SELINUX_NAME);
|
||||||
|
if (secdef == NULL)
|
||||||
|
return -1;
|
||||||
return virSecuritySELinuxSetFilecon(file, secdef->imagelabel);
|
return virSecuritySELinuxSetFilecon(file, secdef->imagelabel);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -939,8 +969,12 @@ static int
|
|||||||
virSecuritySELinuxSetSecurityUSBLabel(usbDevice *dev ATTRIBUTE_UNUSED,
|
virSecuritySELinuxSetSecurityUSBLabel(usbDevice *dev ATTRIBUTE_UNUSED,
|
||||||
const char *file, void *opaque)
|
const char *file, void *opaque)
|
||||||
{
|
{
|
||||||
|
virSecurityLabelDefPtr secdef;
|
||||||
virDomainDefPtr def = opaque;
|
virDomainDefPtr def = opaque;
|
||||||
const virSecurityLabelDefPtr secdef = def->seclabels[0];
|
|
||||||
|
secdef = virDomainDefGetSecurityLabelDef(def, SECURITY_SELINUX_NAME);
|
||||||
|
if (secdef == NULL)
|
||||||
|
return -1;
|
||||||
|
|
||||||
return virSecuritySELinuxSetFilecon(file, secdef->imagelabel);
|
return virSecuritySELinuxSetFilecon(file, secdef->imagelabel);
|
||||||
}
|
}
|
||||||
@ -951,9 +985,13 @@ virSecuritySELinuxSetSecurityHostdevLabel(virSecurityManagerPtr mgr ATTRIBUTE_UN
|
|||||||
virDomainHostdevDefPtr dev)
|
virDomainHostdevDefPtr dev)
|
||||||
|
|
||||||
{
|
{
|
||||||
const virSecurityLabelDefPtr secdef = def->seclabels[0];
|
virSecurityLabelDefPtr secdef;
|
||||||
int ret = -1;
|
int ret = -1;
|
||||||
|
|
||||||
|
secdef = virDomainDefGetSecurityLabelDef(def, SECURITY_SELINUX_NAME);
|
||||||
|
if (secdef == NULL)
|
||||||
|
return -1;
|
||||||
|
|
||||||
if (secdef->norelabel)
|
if (secdef->norelabel)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
@ -1020,9 +1058,13 @@ virSecuritySELinuxRestoreSecurityHostdevLabel(virSecurityManagerPtr mgr ATTRIBUT
|
|||||||
virDomainHostdevDefPtr dev)
|
virDomainHostdevDefPtr dev)
|
||||||
|
|
||||||
{
|
{
|
||||||
const virSecurityLabelDefPtr secdef = def->seclabels[0];
|
virSecurityLabelDefPtr secdef;
|
||||||
int ret = -1;
|
int ret = -1;
|
||||||
|
|
||||||
|
secdef = virDomainDefGetSecurityLabelDef(def, SECURITY_SELINUX_NAME);
|
||||||
|
if (secdef == NULL)
|
||||||
|
return -1;
|
||||||
|
|
||||||
if (secdef->norelabel)
|
if (secdef->norelabel)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
@ -1073,10 +1115,14 @@ virSecuritySELinuxSetSecurityChardevLabel(virDomainDefPtr def,
|
|||||||
virDomainChrSourceDefPtr dev)
|
virDomainChrSourceDefPtr dev)
|
||||||
|
|
||||||
{
|
{
|
||||||
const virSecurityLabelDefPtr secdef = def->seclabels[0];
|
virSecurityLabelDefPtr secdef;
|
||||||
char *in = NULL, *out = NULL;
|
char *in = NULL, *out = NULL;
|
||||||
int ret = -1;
|
int ret = -1;
|
||||||
|
|
||||||
|
secdef = virDomainDefGetSecurityLabelDef(def, SECURITY_SELINUX_NAME);
|
||||||
|
if (secdef == NULL)
|
||||||
|
return -1;
|
||||||
|
|
||||||
if (secdef->norelabel)
|
if (secdef->norelabel)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
@ -1119,10 +1165,14 @@ virSecuritySELinuxRestoreSecurityChardevLabel(virDomainDefPtr def,
|
|||||||
virDomainChrSourceDefPtr dev)
|
virDomainChrSourceDefPtr dev)
|
||||||
|
|
||||||
{
|
{
|
||||||
const virSecurityLabelDefPtr secdef = def->seclabels[0];
|
virSecurityLabelDefPtr secdef;
|
||||||
char *in = NULL, *out = NULL;
|
char *in = NULL, *out = NULL;
|
||||||
int ret = -1;
|
int ret = -1;
|
||||||
|
|
||||||
|
secdef = virDomainDefGetSecurityLabelDef(def, SECURITY_SELINUX_NAME);
|
||||||
|
if (secdef == NULL)
|
||||||
|
return -1;
|
||||||
|
|
||||||
if (secdef->norelabel)
|
if (secdef->norelabel)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
@ -1212,12 +1262,16 @@ virSecuritySELinuxRestoreSecurityAllLabel(virSecurityManagerPtr mgr ATTRIBUTE_UN
|
|||||||
virDomainDefPtr def,
|
virDomainDefPtr def,
|
||||||
int migrated ATTRIBUTE_UNUSED)
|
int migrated ATTRIBUTE_UNUSED)
|
||||||
{
|
{
|
||||||
const virSecurityLabelDefPtr secdef = def->seclabels[0];
|
virSecurityLabelDefPtr secdef;
|
||||||
int i;
|
int i;
|
||||||
int rc = 0;
|
int rc = 0;
|
||||||
|
|
||||||
VIR_DEBUG("Restoring security label on %s", def->name);
|
VIR_DEBUG("Restoring security label on %s", def->name);
|
||||||
|
|
||||||
|
secdef = virDomainDefGetSecurityLabelDef(def, SECURITY_SELINUX_NAME);
|
||||||
|
if (secdef == NULL)
|
||||||
|
return -1;
|
||||||
|
|
||||||
if (secdef->norelabel)
|
if (secdef->norelabel)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
@ -1262,7 +1316,11 @@ static int
|
|||||||
virSecuritySELinuxReleaseSecurityLabel(virSecurityManagerPtr mgr,
|
virSecuritySELinuxReleaseSecurityLabel(virSecurityManagerPtr mgr,
|
||||||
virDomainDefPtr def)
|
virDomainDefPtr def)
|
||||||
{
|
{
|
||||||
const virSecurityLabelDefPtr secdef = def->seclabels[0];
|
virSecurityLabelDefPtr secdef;
|
||||||
|
|
||||||
|
secdef = virDomainDefGetSecurityLabelDef(def, SECURITY_SELINUX_NAME);
|
||||||
|
if (secdef == NULL)
|
||||||
|
return -1;
|
||||||
|
|
||||||
if (secdef->type == VIR_DOMAIN_SECLABEL_DYNAMIC) {
|
if (secdef->type == VIR_DOMAIN_SECLABEL_DYNAMIC) {
|
||||||
if (secdef->label != NULL) {
|
if (secdef->label != NULL) {
|
||||||
@ -1287,7 +1345,11 @@ virSecuritySELinuxSetSavedStateLabel(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
|
|||||||
virDomainDefPtr def,
|
virDomainDefPtr def,
|
||||||
const char *savefile)
|
const char *savefile)
|
||||||
{
|
{
|
||||||
const virSecurityLabelDefPtr secdef = def->seclabels[0];
|
virSecurityLabelDefPtr secdef;
|
||||||
|
|
||||||
|
secdef = virDomainDefGetSecurityLabelDef(def, SECURITY_SELINUX_NAME);
|
||||||
|
if (secdef == NULL)
|
||||||
|
return -1;
|
||||||
|
|
||||||
if (secdef->norelabel)
|
if (secdef->norelabel)
|
||||||
return 0;
|
return 0;
|
||||||
@ -1301,7 +1363,11 @@ virSecuritySELinuxRestoreSavedStateLabel(virSecurityManagerPtr mgr ATTRIBUTE_UNU
|
|||||||
virDomainDefPtr def,
|
virDomainDefPtr def,
|
||||||
const char *savefile)
|
const char *savefile)
|
||||||
{
|
{
|
||||||
const virSecurityLabelDefPtr secdef = def->seclabels[0];
|
virSecurityLabelDefPtr secdef;
|
||||||
|
|
||||||
|
secdef = virDomainDefGetSecurityLabelDef(def, SECURITY_SELINUX_NAME);
|
||||||
|
if (secdef == NULL)
|
||||||
|
return -1;
|
||||||
|
|
||||||
if (secdef->norelabel)
|
if (secdef->norelabel)
|
||||||
return 0;
|
return 0;
|
||||||
@ -1314,7 +1380,12 @@ static int
|
|||||||
virSecuritySELinuxSecurityVerify(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
|
virSecuritySELinuxSecurityVerify(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
|
||||||
virDomainDefPtr def)
|
virDomainDefPtr def)
|
||||||
{
|
{
|
||||||
const virSecurityLabelDefPtr secdef = def->seclabels[0];
|
virSecurityLabelDefPtr secdef;
|
||||||
|
|
||||||
|
secdef = virDomainDefGetSecurityLabelDef(def, SECURITY_SELINUX_NAME);
|
||||||
|
if (secdef == NULL)
|
||||||
|
return -1;
|
||||||
|
|
||||||
if (!STREQ(virSecurityManagerGetModel(mgr), secdef->model)) {
|
if (!STREQ(virSecurityManagerGetModel(mgr), secdef->model)) {
|
||||||
virReportError(VIR_ERR_INTERNAL_ERROR,
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
||||||
_("security label driver mismatch: "
|
_("security label driver mismatch: "
|
||||||
@ -1339,12 +1410,16 @@ virSecuritySELinuxSetSecurityProcessLabel(virSecurityManagerPtr mgr,
|
|||||||
virDomainDefPtr def)
|
virDomainDefPtr def)
|
||||||
{
|
{
|
||||||
/* TODO: verify DOI */
|
/* TODO: verify DOI */
|
||||||
const virSecurityLabelDefPtr secdef = def->seclabels[0];
|
virSecurityLabelDefPtr secdef;
|
||||||
VIR_DEBUG("label=%s", secdef->label);
|
|
||||||
|
|
||||||
if (def->seclabels[0]->label == NULL)
|
secdef = virDomainDefGetSecurityLabelDef(def, SECURITY_SELINUX_NAME);
|
||||||
|
if (secdef == NULL)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if (secdef->label == NULL)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
VIR_DEBUG("label=%s", secdef->label);
|
||||||
if (!STREQ(virSecurityManagerGetModel(mgr), secdef->model)) {
|
if (!STREQ(virSecurityManagerGetModel(mgr), secdef->model)) {
|
||||||
virReportError(VIR_ERR_INTERNAL_ERROR,
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
||||||
_("security label driver mismatch: "
|
_("security label driver mismatch: "
|
||||||
@ -1371,13 +1446,17 @@ virSecuritySELinuxSetSecurityDaemonSocketLabel(virSecurityManagerPtr mgr,
|
|||||||
virDomainDefPtr def)
|
virDomainDefPtr def)
|
||||||
{
|
{
|
||||||
/* TODO: verify DOI */
|
/* TODO: verify DOI */
|
||||||
const virSecurityLabelDefPtr secdef = def->seclabels[0];
|
virSecurityLabelDefPtr secdef;
|
||||||
context_t execcon = NULL;
|
context_t execcon = NULL;
|
||||||
context_t proccon = NULL;
|
context_t proccon = NULL;
|
||||||
security_context_t scon = NULL;
|
security_context_t scon = NULL;
|
||||||
int rc = -1;
|
int rc = -1;
|
||||||
|
|
||||||
if (def->seclabels[0]->label == NULL)
|
secdef = virDomainDefGetSecurityLabelDef(def, SECURITY_SELINUX_NAME);
|
||||||
|
if (secdef == NULL)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if (secdef->label == NULL)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (!STREQ(virSecurityManagerGetModel(mgr), secdef->model)) {
|
if (!STREQ(virSecurityManagerGetModel(mgr), secdef->model)) {
|
||||||
@ -1441,9 +1520,13 @@ static int
|
|||||||
virSecuritySELinuxSetSecuritySocketLabel(virSecurityManagerPtr mgr,
|
virSecuritySELinuxSetSecuritySocketLabel(virSecurityManagerPtr mgr,
|
||||||
virDomainDefPtr vm)
|
virDomainDefPtr vm)
|
||||||
{
|
{
|
||||||
const virSecurityLabelDefPtr secdef = vm->seclabels[0];
|
virSecurityLabelDefPtr secdef;
|
||||||
int rc = -1;
|
int rc = -1;
|
||||||
|
|
||||||
|
secdef = virDomainDefGetSecurityLabelDef(vm, SECURITY_SELINUX_NAME);
|
||||||
|
if (secdef == NULL)
|
||||||
|
return -1;
|
||||||
|
|
||||||
if (secdef->label == NULL)
|
if (secdef->label == NULL)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
@ -1479,9 +1562,13 @@ virSecuritySELinuxClearSecuritySocketLabel(virSecurityManagerPtr mgr,
|
|||||||
virDomainDefPtr def)
|
virDomainDefPtr def)
|
||||||
{
|
{
|
||||||
/* TODO: verify DOI */
|
/* TODO: verify DOI */
|
||||||
const virSecurityLabelDefPtr secdef = def->seclabels[0];
|
virSecurityLabelDefPtr secdef;
|
||||||
|
|
||||||
if (def->seclabels[0]->label == NULL)
|
secdef = virDomainDefGetSecurityLabelDef(def, SECURITY_SELINUX_NAME);
|
||||||
|
if (secdef == NULL)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if (secdef->label == NULL)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (!STREQ(virSecurityManagerGetModel(mgr), secdef->model)) {
|
if (!STREQ(virSecurityManagerGetModel(mgr), secdef->model)) {
|
||||||
@ -1557,9 +1644,13 @@ virSecuritySELinuxSetSecurityAllLabel(virSecurityManagerPtr mgr,
|
|||||||
virDomainDefPtr def,
|
virDomainDefPtr def,
|
||||||
const char *stdin_path)
|
const char *stdin_path)
|
||||||
{
|
{
|
||||||
virSecuritySELinuxDataPtr data = virSecurityManagerGetPrivateData(mgr);
|
|
||||||
const virSecurityLabelDefPtr secdef = def->seclabels[0];
|
|
||||||
int i;
|
int i;
|
||||||
|
virSecuritySELinuxDataPtr data = virSecurityManagerGetPrivateData(mgr);
|
||||||
|
virSecurityLabelDefPtr secdef;
|
||||||
|
|
||||||
|
secdef = virDomainDefGetSecurityLabelDef(def, SECURITY_SELINUX_NAME);
|
||||||
|
if (secdef == NULL)
|
||||||
|
return -1;
|
||||||
|
|
||||||
if (secdef->norelabel)
|
if (secdef->norelabel)
|
||||||
return 0;
|
return 0;
|
||||||
@ -1619,7 +1710,11 @@ virSecuritySELinuxSetImageFDLabel(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
|
|||||||
virDomainDefPtr def,
|
virDomainDefPtr def,
|
||||||
int fd)
|
int fd)
|
||||||
{
|
{
|
||||||
const virSecurityLabelDefPtr secdef = def->seclabels[0];
|
virSecurityLabelDefPtr secdef;
|
||||||
|
|
||||||
|
secdef = virDomainDefGetSecurityLabelDef(def, SECURITY_SELINUX_NAME);
|
||||||
|
if (secdef == NULL)
|
||||||
|
return -1;
|
||||||
|
|
||||||
if (secdef->imagelabel == NULL)
|
if (secdef->imagelabel == NULL)
|
||||||
return 0;
|
return 0;
|
||||||
@ -1631,13 +1726,17 @@ static char *
|
|||||||
virSecuritySELinuxGenImageLabel(virSecurityManagerPtr mgr,
|
virSecuritySELinuxGenImageLabel(virSecurityManagerPtr mgr,
|
||||||
virDomainDefPtr def)
|
virDomainDefPtr def)
|
||||||
{
|
{
|
||||||
const virSecurityLabelDefPtr secdef = def->seclabels[0];
|
virSecurityLabelDefPtr secdef;
|
||||||
virSecuritySELinuxDataPtr data = virSecurityManagerGetPrivateData(mgr);
|
virSecuritySELinuxDataPtr data = virSecurityManagerGetPrivateData(mgr);
|
||||||
const char *range;
|
const char *range;
|
||||||
context_t ctx = NULL;
|
context_t ctx = NULL;
|
||||||
char *label = NULL;
|
char *label = NULL;
|
||||||
const char *mcs = NULL;
|
const char *mcs = NULL;
|
||||||
|
|
||||||
|
secdef = virDomainDefGetSecurityLabelDef(def, SECURITY_SELINUX_NAME);
|
||||||
|
if (secdef == NULL)
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
if (secdef->label) {
|
if (secdef->label) {
|
||||||
ctx = context_new(secdef->label);
|
ctx = context_new(secdef->label);
|
||||||
if (!ctx) {
|
if (!ctx) {
|
||||||
@ -1668,7 +1767,11 @@ virSecuritySELinuxGetSecurityMountOptions(virSecurityManagerPtr mgr,
|
|||||||
virDomainDefPtr def)
|
virDomainDefPtr def)
|
||||||
{
|
{
|
||||||
char *opts = NULL;
|
char *opts = NULL;
|
||||||
const virSecurityLabelDefPtr secdef = def->seclabels[0];
|
virSecurityLabelDefPtr secdef;
|
||||||
|
|
||||||
|
secdef = virDomainDefGetSecurityLabelDef(def, SECURITY_SELINUX_NAME);
|
||||||
|
if (secdef == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
if (! secdef->imagelabel)
|
if (! secdef->imagelabel)
|
||||||
secdef->imagelabel = virSecuritySELinuxGenImageLabel(mgr,def);
|
secdef->imagelabel = virSecuritySELinuxGenImageLabel(mgr,def);
|
||||||
|
@ -23,29 +23,70 @@
|
|||||||
#include "security_stack.h"
|
#include "security_stack.h"
|
||||||
|
|
||||||
#include "virterror_internal.h"
|
#include "virterror_internal.h"
|
||||||
|
#include "memory.h"
|
||||||
|
|
||||||
#define VIR_FROM_THIS VIR_FROM_SECURITY
|
#define VIR_FROM_THIS VIR_FROM_SECURITY
|
||||||
|
|
||||||
typedef struct _virSecurityStackData virSecurityStackData;
|
typedef struct _virSecurityStackData virSecurityStackData;
|
||||||
typedef virSecurityStackData *virSecurityStackDataPtr;
|
typedef virSecurityStackData *virSecurityStackDataPtr;
|
||||||
|
typedef struct _virSecurityStackItem virSecurityStackItem;
|
||||||
|
typedef virSecurityStackItem* virSecurityStackItemPtr;
|
||||||
|
|
||||||
|
struct _virSecurityStackItem {
|
||||||
|
virSecurityManagerPtr securityManager;
|
||||||
|
virSecurityStackItemPtr next;
|
||||||
|
};
|
||||||
|
|
||||||
struct _virSecurityStackData {
|
struct _virSecurityStackData {
|
||||||
virSecurityManagerPtr primary;
|
virSecurityManagerPtr primary;
|
||||||
virSecurityManagerPtr secondary;
|
virSecurityStackItemPtr itemsHead;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
int
|
||||||
|
virSecurityStackAddPrimary(virSecurityManagerPtr mgr,
|
||||||
|
virSecurityManagerPtr primary)
|
||||||
|
{
|
||||||
|
virSecurityStackDataPtr priv = virSecurityManagerGetPrivateData(mgr);
|
||||||
|
if (virSecurityStackAddNested(mgr, primary) < 0)
|
||||||
|
return -1;
|
||||||
|
priv->primary = primary;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
virSecurityStackAddNested(virSecurityManagerPtr mgr,
|
||||||
|
virSecurityManagerPtr nested)
|
||||||
|
{
|
||||||
|
virSecurityStackItemPtr item = NULL;
|
||||||
|
virSecurityStackDataPtr priv = virSecurityManagerGetPrivateData(mgr);
|
||||||
|
|
||||||
|
if (VIR_ALLOC(item) < 0) {
|
||||||
|
virReportOOMError();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
item->securityManager = nested;
|
||||||
|
item->next = priv->itemsHead;
|
||||||
|
priv->itemsHead = item;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
virSecurityManagerPtr
|
||||||
|
virSecurityStackGetPrimary(virSecurityManagerPtr mgr)
|
||||||
|
{
|
||||||
|
virSecurityStackDataPtr priv = virSecurityManagerGetPrivateData(mgr);
|
||||||
|
return (priv->primary) ? priv->primary : priv->itemsHead->securityManager;
|
||||||
|
}
|
||||||
|
|
||||||
void virSecurityStackSetPrimary(virSecurityManagerPtr mgr,
|
void virSecurityStackSetPrimary(virSecurityManagerPtr mgr,
|
||||||
virSecurityManagerPtr primary)
|
virSecurityManagerPtr primary)
|
||||||
{
|
{
|
||||||
virSecurityStackDataPtr priv = virSecurityManagerGetPrivateData(mgr);
|
virSecurityStackAddPrimary(mgr, primary);
|
||||||
priv->primary = primary;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void virSecurityStackSetSecondary(virSecurityManagerPtr mgr,
|
void virSecurityStackSetSecondary(virSecurityManagerPtr mgr,
|
||||||
virSecurityManagerPtr secondary)
|
virSecurityManagerPtr secondary)
|
||||||
{
|
{
|
||||||
virSecurityStackDataPtr priv = virSecurityManagerGetPrivateData(mgr);
|
virSecurityStackAddNested(mgr, secondary);
|
||||||
priv->secondary = secondary;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static virSecurityDriverStatus
|
static virSecurityDriverStatus
|
||||||
@ -64,9 +105,14 @@ static int
|
|||||||
virSecurityStackClose(virSecurityManagerPtr mgr)
|
virSecurityStackClose(virSecurityManagerPtr mgr)
|
||||||
{
|
{
|
||||||
virSecurityStackDataPtr priv = virSecurityManagerGetPrivateData(mgr);
|
virSecurityStackDataPtr priv = virSecurityManagerGetPrivateData(mgr);
|
||||||
|
virSecurityStackItemPtr next, item = priv->itemsHead;
|
||||||
|
|
||||||
virSecurityManagerFree(priv->primary);
|
while (item) {
|
||||||
virSecurityManagerFree(priv->secondary);
|
next = item->next;
|
||||||
|
virSecurityManagerFree(item->securityManager);
|
||||||
|
VIR_FREE(item);
|
||||||
|
item = next;
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -74,17 +120,13 @@ virSecurityStackClose(virSecurityManagerPtr mgr)
|
|||||||
static const char *
|
static const char *
|
||||||
virSecurityStackGetModel(virSecurityManagerPtr mgr)
|
virSecurityStackGetModel(virSecurityManagerPtr mgr)
|
||||||
{
|
{
|
||||||
virSecurityStackDataPtr priv = virSecurityManagerGetPrivateData(mgr);
|
return virSecurityManagerGetModel(virSecurityStackGetPrimary(mgr));
|
||||||
|
|
||||||
return virSecurityManagerGetModel(priv->primary);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static const char *
|
static const char *
|
||||||
virSecurityStackGetDOI(virSecurityManagerPtr mgr)
|
virSecurityStackGetDOI(virSecurityManagerPtr mgr)
|
||||||
{
|
{
|
||||||
virSecurityStackDataPtr priv = virSecurityManagerGetPrivateData(mgr);
|
return virSecurityManagerGetDOI(virSecurityStackGetPrimary(mgr));
|
||||||
|
|
||||||
return virSecurityManagerGetDOI(priv->primary);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
@ -92,13 +134,15 @@ virSecurityStackVerify(virSecurityManagerPtr mgr,
|
|||||||
virDomainDefPtr def)
|
virDomainDefPtr def)
|
||||||
{
|
{
|
||||||
virSecurityStackDataPtr priv = virSecurityManagerGetPrivateData(mgr);
|
virSecurityStackDataPtr priv = virSecurityManagerGetPrivateData(mgr);
|
||||||
|
virSecurityStackItemPtr item = priv->itemsHead;
|
||||||
int rc = 0;
|
int rc = 0;
|
||||||
|
|
||||||
if (virSecurityManagerVerify(priv->primary, def) < 0)
|
for(; item; item = item->next) {
|
||||||
rc = -1;
|
if (virSecurityManagerVerify(item->securityManager, def) < 0) {
|
||||||
|
rc = -1;
|
||||||
if (virSecurityManagerVerify(priv->secondary, def) < 0)
|
break;
|
||||||
rc = -1;
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
@ -108,12 +152,12 @@ static int
|
|||||||
virSecurityStackGenLabel(virSecurityManagerPtr mgr,
|
virSecurityStackGenLabel(virSecurityManagerPtr mgr,
|
||||||
virDomainDefPtr vm)
|
virDomainDefPtr vm)
|
||||||
{
|
{
|
||||||
virSecurityStackDataPtr priv = virSecurityManagerGetPrivateData(mgr);
|
|
||||||
int rc = 0;
|
int rc = 0;
|
||||||
|
|
||||||
if (virSecurityManagerGenLabel(priv->primary, vm) < 0)
|
if (virSecurityManagerGenLabel(virSecurityStackGetPrimary(mgr), vm) < 0)
|
||||||
rc = -1;
|
rc = -1;
|
||||||
|
|
||||||
|
// TODO
|
||||||
#if 0
|
#if 0
|
||||||
/* We don't allow secondary drivers to generate labels.
|
/* We don't allow secondary drivers to generate labels.
|
||||||
* This may have to change in the future, but requires
|
* This may have to change in the future, but requires
|
||||||
@ -133,11 +177,12 @@ static int
|
|||||||
virSecurityStackReleaseLabel(virSecurityManagerPtr mgr,
|
virSecurityStackReleaseLabel(virSecurityManagerPtr mgr,
|
||||||
virDomainDefPtr vm)
|
virDomainDefPtr vm)
|
||||||
{
|
{
|
||||||
virSecurityStackDataPtr priv = virSecurityManagerGetPrivateData(mgr);
|
|
||||||
int rc = 0;
|
int rc = 0;
|
||||||
|
|
||||||
if (virSecurityManagerReleaseLabel(priv->primary, vm) < 0)
|
if (virSecurityManagerReleaseLabel(virSecurityStackGetPrimary(mgr), vm) < 0)
|
||||||
rc = -1;
|
rc = -1;
|
||||||
|
|
||||||
|
// TODO
|
||||||
#if 0
|
#if 0
|
||||||
/* XXX See note in GenLabel */
|
/* XXX See note in GenLabel */
|
||||||
if (virSecurityManagerReleaseLabel(priv->secondary, vm) < 0)
|
if (virSecurityManagerReleaseLabel(priv->secondary, vm) < 0)
|
||||||
@ -153,11 +198,11 @@ virSecurityStackReserveLabel(virSecurityManagerPtr mgr,
|
|||||||
virDomainDefPtr vm,
|
virDomainDefPtr vm,
|
||||||
pid_t pid)
|
pid_t pid)
|
||||||
{
|
{
|
||||||
virSecurityStackDataPtr priv = virSecurityManagerGetPrivateData(mgr);
|
|
||||||
int rc = 0;
|
int rc = 0;
|
||||||
|
|
||||||
if (virSecurityManagerReserveLabel(priv->primary, vm, pid) < 0)
|
if (virSecurityManagerReserveLabel(virSecurityStackGetPrimary(mgr), vm, pid) < 0)
|
||||||
rc = -1;
|
rc = -1;
|
||||||
|
// TODO
|
||||||
#if 0
|
#if 0
|
||||||
/* XXX See note in GenLabel */
|
/* XXX See note in GenLabel */
|
||||||
if (virSecurityManagerReserveLabel(priv->secondary, vm, pid) < 0)
|
if (virSecurityManagerReserveLabel(priv->secondary, vm, pid) < 0)
|
||||||
@ -174,12 +219,13 @@ virSecurityStackSetSecurityImageLabel(virSecurityManagerPtr mgr,
|
|||||||
virDomainDiskDefPtr disk)
|
virDomainDiskDefPtr disk)
|
||||||
{
|
{
|
||||||
virSecurityStackDataPtr priv = virSecurityManagerGetPrivateData(mgr);
|
virSecurityStackDataPtr priv = virSecurityManagerGetPrivateData(mgr);
|
||||||
|
virSecurityStackItemPtr item = priv->itemsHead;
|
||||||
int rc = 0;
|
int rc = 0;
|
||||||
|
|
||||||
if (virSecurityManagerSetImageLabel(priv->secondary, vm, disk) < 0)
|
for (; item; item = item->next) {
|
||||||
rc = -1;
|
if (virSecurityManagerSetImageLabel(item->securityManager, vm, disk) < 0)
|
||||||
if (virSecurityManagerSetImageLabel(priv->primary, vm, disk) < 0)
|
rc = -1;
|
||||||
rc = -1;
|
}
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
@ -191,12 +237,13 @@ virSecurityStackRestoreSecurityImageLabel(virSecurityManagerPtr mgr,
|
|||||||
virDomainDiskDefPtr disk)
|
virDomainDiskDefPtr disk)
|
||||||
{
|
{
|
||||||
virSecurityStackDataPtr priv = virSecurityManagerGetPrivateData(mgr);
|
virSecurityStackDataPtr priv = virSecurityManagerGetPrivateData(mgr);
|
||||||
|
virSecurityStackItemPtr item = priv->itemsHead;
|
||||||
int rc = 0;
|
int rc = 0;
|
||||||
|
|
||||||
if (virSecurityManagerRestoreImageLabel(priv->secondary, vm, disk) < 0)
|
for (; item; item = item->next) {
|
||||||
rc = -1;
|
if (virSecurityManagerRestoreImageLabel(item->securityManager, vm, disk) < 0)
|
||||||
if (virSecurityManagerRestoreImageLabel(priv->primary, vm, disk) < 0)
|
rc = -1;
|
||||||
rc = -1;
|
}
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
@ -209,12 +256,13 @@ virSecurityStackSetSecurityHostdevLabel(virSecurityManagerPtr mgr,
|
|||||||
|
|
||||||
{
|
{
|
||||||
virSecurityStackDataPtr priv = virSecurityManagerGetPrivateData(mgr);
|
virSecurityStackDataPtr priv = virSecurityManagerGetPrivateData(mgr);
|
||||||
|
virSecurityStackItemPtr item = priv->itemsHead;
|
||||||
int rc = 0;
|
int rc = 0;
|
||||||
|
|
||||||
if (virSecurityManagerSetHostdevLabel(priv->secondary, vm, dev) < 0)
|
for (; item; item = item->next) {
|
||||||
rc = -1;
|
if (virSecurityManagerSetHostdevLabel(item->securityManager, vm, dev) < 0)
|
||||||
if (virSecurityManagerSetHostdevLabel(priv->primary, vm, dev) < 0)
|
rc = -1;
|
||||||
rc = -1;
|
}
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
@ -226,12 +274,13 @@ virSecurityStackRestoreSecurityHostdevLabel(virSecurityManagerPtr mgr,
|
|||||||
virDomainHostdevDefPtr dev)
|
virDomainHostdevDefPtr dev)
|
||||||
{
|
{
|
||||||
virSecurityStackDataPtr priv = virSecurityManagerGetPrivateData(mgr);
|
virSecurityStackDataPtr priv = virSecurityManagerGetPrivateData(mgr);
|
||||||
|
virSecurityStackItemPtr item = priv->itemsHead;
|
||||||
int rc = 0;
|
int rc = 0;
|
||||||
|
|
||||||
if (virSecurityManagerRestoreHostdevLabel(priv->secondary, vm, dev) < 0)
|
for (; item; item = item->next) {
|
||||||
rc = -1;
|
if (virSecurityManagerRestoreHostdevLabel(item->securityManager, vm, dev) < 0)
|
||||||
if (virSecurityManagerRestoreHostdevLabel(priv->primary, vm, dev) < 0)
|
rc = -1;
|
||||||
rc = -1;
|
}
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
@ -243,12 +292,13 @@ virSecurityStackSetSecurityAllLabel(virSecurityManagerPtr mgr,
|
|||||||
const char *stdin_path)
|
const char *stdin_path)
|
||||||
{
|
{
|
||||||
virSecurityStackDataPtr priv = virSecurityManagerGetPrivateData(mgr);
|
virSecurityStackDataPtr priv = virSecurityManagerGetPrivateData(mgr);
|
||||||
|
virSecurityStackItemPtr item = priv->itemsHead;
|
||||||
int rc = 0;
|
int rc = 0;
|
||||||
|
|
||||||
if (virSecurityManagerSetAllLabel(priv->secondary, vm, stdin_path) < 0)
|
for (; item; item = item->next) {
|
||||||
rc = -1;
|
if (virSecurityManagerSetAllLabel(item->securityManager, vm, stdin_path) < 0)
|
||||||
if (virSecurityManagerSetAllLabel(priv->primary, vm, stdin_path) < 0)
|
rc = -1;
|
||||||
rc = -1;
|
}
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
@ -260,12 +310,13 @@ virSecurityStackRestoreSecurityAllLabel(virSecurityManagerPtr mgr,
|
|||||||
int migrated)
|
int migrated)
|
||||||
{
|
{
|
||||||
virSecurityStackDataPtr priv = virSecurityManagerGetPrivateData(mgr);
|
virSecurityStackDataPtr priv = virSecurityManagerGetPrivateData(mgr);
|
||||||
|
virSecurityStackItemPtr item = priv->itemsHead;
|
||||||
int rc = 0;
|
int rc = 0;
|
||||||
|
|
||||||
if (virSecurityManagerRestoreAllLabel(priv->secondary, vm, migrated) < 0)
|
for (; item; item = item->next) {
|
||||||
rc = -1;
|
if (virSecurityManagerRestoreAllLabel(item->securityManager, vm, migrated) < 0)
|
||||||
if (virSecurityManagerRestoreAllLabel(priv->primary, vm, migrated) < 0)
|
rc = -1;
|
||||||
rc = -1;
|
}
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
@ -277,12 +328,13 @@ virSecurityStackSetSavedStateLabel(virSecurityManagerPtr mgr,
|
|||||||
const char *savefile)
|
const char *savefile)
|
||||||
{
|
{
|
||||||
virSecurityStackDataPtr priv = virSecurityManagerGetPrivateData(mgr);
|
virSecurityStackDataPtr priv = virSecurityManagerGetPrivateData(mgr);
|
||||||
|
virSecurityStackItemPtr item = priv->itemsHead;
|
||||||
int rc = 0;
|
int rc = 0;
|
||||||
|
|
||||||
if (virSecurityManagerSetSavedStateLabel(priv->secondary, vm, savefile) < 0)
|
for (; item; item = item->next) {
|
||||||
rc = -1;
|
if (virSecurityManagerSetSavedStateLabel(item->securityManager, vm, savefile) < 0)
|
||||||
if (virSecurityManagerSetSavedStateLabel(priv->primary, vm, savefile) < 0)
|
rc = -1;
|
||||||
rc = -1;
|
}
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
@ -294,12 +346,13 @@ virSecurityStackRestoreSavedStateLabel(virSecurityManagerPtr mgr,
|
|||||||
const char *savefile)
|
const char *savefile)
|
||||||
{
|
{
|
||||||
virSecurityStackDataPtr priv = virSecurityManagerGetPrivateData(mgr);
|
virSecurityStackDataPtr priv = virSecurityManagerGetPrivateData(mgr);
|
||||||
|
virSecurityStackItemPtr item = priv->itemsHead;
|
||||||
int rc = 0;
|
int rc = 0;
|
||||||
|
|
||||||
if (virSecurityManagerRestoreSavedStateLabel(priv->secondary, vm, savefile) < 0)
|
for (; item; item = item->next) {
|
||||||
rc = -1;
|
if (virSecurityManagerRestoreSavedStateLabel(item->securityManager, vm, savefile) < 0)
|
||||||
if (virSecurityManagerRestoreSavedStateLabel(priv->primary, vm, savefile) < 0)
|
rc = -1;
|
||||||
rc = -1;
|
}
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
@ -310,12 +363,13 @@ virSecurityStackSetProcessLabel(virSecurityManagerPtr mgr,
|
|||||||
virDomainDefPtr vm)
|
virDomainDefPtr vm)
|
||||||
{
|
{
|
||||||
virSecurityStackDataPtr priv = virSecurityManagerGetPrivateData(mgr);
|
virSecurityStackDataPtr priv = virSecurityManagerGetPrivateData(mgr);
|
||||||
|
virSecurityStackItemPtr item = priv->itemsHead;
|
||||||
int rc = 0;
|
int rc = 0;
|
||||||
|
|
||||||
if (virSecurityManagerSetProcessLabel(priv->secondary, vm) < 0)
|
for (; item; item = item->next) {
|
||||||
rc = -1;
|
if (virSecurityManagerSetProcessLabel(item->securityManager, vm) < 0)
|
||||||
if (virSecurityManagerSetProcessLabel(priv->primary, vm) < 0)
|
rc = -1;
|
||||||
rc = -1;
|
}
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
@ -326,14 +380,14 @@ virSecurityStackGetProcessLabel(virSecurityManagerPtr mgr,
|
|||||||
pid_t pid,
|
pid_t pid,
|
||||||
virSecurityLabelPtr seclabel)
|
virSecurityLabelPtr seclabel)
|
||||||
{
|
{
|
||||||
virSecurityStackDataPtr priv = virSecurityManagerGetPrivateData(mgr);
|
|
||||||
int rc = 0;
|
int rc = 0;
|
||||||
|
|
||||||
|
// TODO
|
||||||
#if 0
|
#if 0
|
||||||
if (virSecurityManagerGetProcessLabel(priv->secondary, vm, pid, seclabel) < 0)
|
if (virSecurityManagerGetProcessLabel(priv->secondary, vm, pid, seclabel) < 0)
|
||||||
rc = -1;
|
rc = -1;
|
||||||
#endif
|
#endif
|
||||||
if (virSecurityManagerGetProcessLabel(priv->primary, vm, pid, seclabel) < 0)
|
if (virSecurityManagerGetProcessLabel(virSecurityStackGetPrimary(mgr), vm, pid, seclabel) < 0)
|
||||||
rc = -1;
|
rc = -1;
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
@ -345,12 +399,13 @@ virSecurityStackSetDaemonSocketLabel(virSecurityManagerPtr mgr,
|
|||||||
virDomainDefPtr vm)
|
virDomainDefPtr vm)
|
||||||
{
|
{
|
||||||
virSecurityStackDataPtr priv = virSecurityManagerGetPrivateData(mgr);
|
virSecurityStackDataPtr priv = virSecurityManagerGetPrivateData(mgr);
|
||||||
|
virSecurityStackItemPtr item = priv->itemsHead;
|
||||||
int rc = 0;
|
int rc = 0;
|
||||||
|
|
||||||
if (virSecurityManagerSetDaemonSocketLabel(priv->secondary, vm) < 0)
|
for (; item; item = item->next) {
|
||||||
rc = -1;
|
if (virSecurityManagerSetDaemonSocketLabel(item->securityManager, vm) < 0)
|
||||||
if (virSecurityManagerSetDaemonSocketLabel(priv->primary, vm) < 0)
|
rc = -1;
|
||||||
rc = -1;
|
}
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
@ -361,12 +416,13 @@ virSecurityStackSetSocketLabel(virSecurityManagerPtr mgr,
|
|||||||
virDomainDefPtr vm)
|
virDomainDefPtr vm)
|
||||||
{
|
{
|
||||||
virSecurityStackDataPtr priv = virSecurityManagerGetPrivateData(mgr);
|
virSecurityStackDataPtr priv = virSecurityManagerGetPrivateData(mgr);
|
||||||
|
virSecurityStackItemPtr item = priv->itemsHead;
|
||||||
int rc = 0;
|
int rc = 0;
|
||||||
|
|
||||||
if (virSecurityManagerSetSocketLabel(priv->secondary, vm) < 0)
|
for (; item; item = item->next) {
|
||||||
rc = -1;
|
if (virSecurityManagerSetSocketLabel(item->securityManager, vm) < 0)
|
||||||
if (virSecurityManagerSetSocketLabel(priv->primary, vm) < 0)
|
rc = -1;
|
||||||
rc = -1;
|
}
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
@ -377,12 +433,13 @@ virSecurityStackClearSocketLabel(virSecurityManagerPtr mgr,
|
|||||||
virDomainDefPtr vm)
|
virDomainDefPtr vm)
|
||||||
{
|
{
|
||||||
virSecurityStackDataPtr priv = virSecurityManagerGetPrivateData(mgr);
|
virSecurityStackDataPtr priv = virSecurityManagerGetPrivateData(mgr);
|
||||||
|
virSecurityStackItemPtr item = priv->itemsHead;
|
||||||
int rc = 0;
|
int rc = 0;
|
||||||
|
|
||||||
if (virSecurityManagerClearSocketLabel(priv->secondary, vm) < 0)
|
for (; item; item = item->next) {
|
||||||
rc = -1;
|
if (virSecurityManagerClearSocketLabel(item->securityManager, vm) < 0)
|
||||||
if (virSecurityManagerClearSocketLabel(priv->primary, vm) < 0)
|
rc = -1;
|
||||||
rc = -1;
|
}
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
@ -393,12 +450,13 @@ virSecurityStackSetImageFDLabel(virSecurityManagerPtr mgr,
|
|||||||
int fd)
|
int fd)
|
||||||
{
|
{
|
||||||
virSecurityStackDataPtr priv = virSecurityManagerGetPrivateData(mgr);
|
virSecurityStackDataPtr priv = virSecurityManagerGetPrivateData(mgr);
|
||||||
|
virSecurityStackItemPtr item = priv->itemsHead;
|
||||||
int rc = 0;
|
int rc = 0;
|
||||||
|
|
||||||
if (virSecurityManagerSetImageFDLabel(priv->secondary, vm, fd) < 0)
|
for (; item; item = item->next) {
|
||||||
rc = -1;
|
if (virSecurityManagerSetImageFDLabel(item->securityManager, vm, fd) < 0)
|
||||||
if (virSecurityManagerSetImageFDLabel(priv->primary, vm, fd) < 0)
|
rc = -1;
|
||||||
rc = -1;
|
}
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
@ -408,6 +466,29 @@ static char *virSecurityStackGetMountOptions(virSecurityManagerPtr mgr ATTRIBUTE
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virSecurityManagerPtr*
|
||||||
|
virSecurityStackGetNested(virSecurityManagerPtr mgr)
|
||||||
|
{
|
||||||
|
virSecurityManagerPtr *list = NULL;
|
||||||
|
virSecurityStackDataPtr priv = virSecurityManagerGetPrivateData(mgr);
|
||||||
|
virSecurityStackItemPtr item;
|
||||||
|
int len = 0, i = 0;
|
||||||
|
|
||||||
|
for (item = priv->itemsHead; item; item = item->next)
|
||||||
|
len++;
|
||||||
|
|
||||||
|
if (VIR_ALLOC_N(list, len + 1) < 0) {
|
||||||
|
virReportOOMError();
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (item = priv->itemsHead; item; item = item->next, i++)
|
||||||
|
list[i] = item->securityManager;
|
||||||
|
list[len] = NULL;
|
||||||
|
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
virSecurityDriver virSecurityDriverStack = {
|
virSecurityDriver virSecurityDriverStack = {
|
||||||
.privateDataLen = sizeof(virSecurityStackData),
|
.privateDataLen = sizeof(virSecurityStackData),
|
||||||
.name = "stack",
|
.name = "stack",
|
||||||
|
@ -25,9 +25,22 @@
|
|||||||
|
|
||||||
extern virSecurityDriver virSecurityDriverStack;
|
extern virSecurityDriver virSecurityDriverStack;
|
||||||
|
|
||||||
|
|
||||||
|
int
|
||||||
|
virSecurityStackAddPrimary(virSecurityManagerPtr mgr,
|
||||||
|
virSecurityManagerPtr primary);
|
||||||
|
int
|
||||||
|
virSecurityStackAddNested(virSecurityManagerPtr mgr,
|
||||||
|
virSecurityManagerPtr nested);
|
||||||
|
virSecurityManagerPtr
|
||||||
|
virSecurityStackGetPrimary(virSecurityManagerPtr mgr);
|
||||||
|
|
||||||
void virSecurityStackSetPrimary(virSecurityManagerPtr mgr,
|
void virSecurityStackSetPrimary(virSecurityManagerPtr mgr,
|
||||||
virSecurityManagerPtr primary);
|
virSecurityManagerPtr primary);
|
||||||
void virSecurityStackSetSecondary(virSecurityManagerPtr mgr,
|
void virSecurityStackSetSecondary(virSecurityManagerPtr mgr,
|
||||||
virSecurityManagerPtr secondary);
|
virSecurityManagerPtr secondary);
|
||||||
|
|
||||||
|
virSecurityManagerPtr*
|
||||||
|
virSecurityStackGetNested(virSecurityManagerPtr mgr);
|
||||||
|
|
||||||
#endif /* __VIR_SECURITY_DAC */
|
#endif /* __VIR_SECURITY_DAC */
|
||||||
|
Loading…
Reference in New Issue
Block a user