mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2024-12-22 17:34:18 +03:00
Use a hash table for storing MCS labels
Instead of using an O(n) efficiency linked list for storing MCS labels, use a hash table. Instead of having the list be global, put it in the SELinux driver private data struct to ensure uniqueness across different instances of the driver. This also ensures thread safety when multiple hypervisor drivers are used in the same libvirtd process Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
This commit is contained in:
parent
2e668a61d5
commit
a56c347080
@ -32,6 +32,7 @@
|
|||||||
#include "hostusb.h"
|
#include "hostusb.h"
|
||||||
#include "storage_file.h"
|
#include "storage_file.h"
|
||||||
#include "virfile.h"
|
#include "virfile.h"
|
||||||
|
#include "virhash.h"
|
||||||
#include "virrandom.h"
|
#include "virrandom.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "conf.h"
|
#include "conf.h"
|
||||||
@ -50,6 +51,7 @@ struct _virSecuritySELinuxData {
|
|||||||
char *domain_context;
|
char *domain_context;
|
||||||
char *file_context;
|
char *file_context;
|
||||||
char *content_context;
|
char *content_context;
|
||||||
|
virHashTablePtr mcs;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _virSecuritySELinuxCallbackData {
|
struct _virSecuritySELinuxCallbackData {
|
||||||
@ -60,64 +62,31 @@ struct _virSecuritySELinuxCallbackData {
|
|||||||
#define SECURITY_SELINUX_VOID_DOI "0"
|
#define SECURITY_SELINUX_VOID_DOI "0"
|
||||||
#define SECURITY_SELINUX_NAME "selinux"
|
#define SECURITY_SELINUX_NAME "selinux"
|
||||||
|
|
||||||
/* TODO
|
|
||||||
The data struct of used mcs should be replaced with a better data structure in the future
|
|
||||||
*/
|
|
||||||
|
|
||||||
typedef struct virSecuritySELinuxMCS virSecuritySELinuxMCS;
|
|
||||||
typedef virSecuritySELinuxMCS *virSecuritySELinuxMCSPtr;
|
|
||||||
struct virSecuritySELinuxMCS {
|
|
||||||
char *mcs;
|
|
||||||
virSecuritySELinuxMCSPtr next;
|
|
||||||
};
|
|
||||||
static virSecuritySELinuxMCSPtr mcsList = NULL;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Returns 0 on success, 1 if already reserved, or -1 on fatal error
|
* Returns 0 on success, 1 if already reserved, or -1 on fatal error
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
virSecuritySELinuxMCSAdd(const char *mcs)
|
virSecuritySELinuxMCSAdd(virSecurityManagerPtr mgr,
|
||||||
|
const char *mcs)
|
||||||
{
|
{
|
||||||
virSecuritySELinuxMCSPtr ptr;
|
virSecuritySELinuxDataPtr data = virSecurityManagerGetPrivateData(mgr);
|
||||||
|
|
||||||
for (ptr = mcsList; ptr; ptr = ptr->next) {
|
if (virHashLookup(data->mcs, mcs))
|
||||||
if (STREQ(ptr->mcs, mcs))
|
return 1;
|
||||||
return 1;
|
|
||||||
}
|
if (virHashAddEntry(data->mcs, mcs, (void*)0x1) < 0)
|
||||||
if (VIR_ALLOC(ptr) < 0) {
|
|
||||||
virReportOOMError();
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
|
||||||
if (!(ptr->mcs = strdup(mcs))) {
|
|
||||||
virReportOOMError();
|
|
||||||
VIR_FREE(ptr);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
ptr->next = mcsList;
|
|
||||||
mcsList = ptr;
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static void
|
||||||
virSecuritySELinuxMCSRemove(const char *mcs)
|
virSecuritySELinuxMCSRemove(virSecurityManagerPtr mgr,
|
||||||
|
const char *mcs)
|
||||||
{
|
{
|
||||||
virSecuritySELinuxMCSPtr prevptr = NULL;
|
virSecuritySELinuxDataPtr data = virSecurityManagerGetPrivateData(mgr);
|
||||||
virSecuritySELinuxMCSPtr ptr = NULL;
|
|
||||||
|
|
||||||
for (ptr = mcsList; ptr; ptr = ptr->next) {
|
virHashRemoveEntry(data->mcs, mcs);
|
||||||
if (STREQ(ptr->mcs, mcs)) {
|
|
||||||
if (prevptr)
|
|
||||||
prevptr->next = ptr->next;
|
|
||||||
else {
|
|
||||||
mcsList = ptr->next;
|
|
||||||
}
|
|
||||||
VIR_FREE(ptr->mcs);
|
|
||||||
VIR_FREE(ptr);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
prevptr = ptr;
|
|
||||||
}
|
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static char *
|
static char *
|
||||||
@ -191,6 +160,10 @@ virSecuritySELinuxLXCInitialize(virSecurityManagerPtr mgr)
|
|||||||
selinux_lxc_contexts_path());
|
selinux_lxc_contexts_path());
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!(data->mcs = virHashCreate(10, NULL)))
|
||||||
|
goto error;
|
||||||
|
|
||||||
virConfFree(selinux_conf);
|
virConfFree(selinux_conf);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
@ -199,6 +172,7 @@ error:
|
|||||||
VIR_FREE(data->domain_context);
|
VIR_FREE(data->domain_context);
|
||||||
VIR_FREE(data->file_context);
|
VIR_FREE(data->file_context);
|
||||||
VIR_FREE(data->content_context);
|
VIR_FREE(data->content_context);
|
||||||
|
virHashFree(data->mcs);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
@ -249,12 +223,16 @@ virSecuritySELinuxQEMUInitialize(virSecurityManagerPtr mgr)
|
|||||||
*ptr = '\0';
|
*ptr = '\0';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!(data->mcs = virHashCreate(10, NULL)))
|
||||||
|
goto error;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
error:
|
error:
|
||||||
VIR_FREE(data->domain_context);
|
VIR_FREE(data->domain_context);
|
||||||
VIR_FREE(data->file_context);
|
VIR_FREE(data->file_context);
|
||||||
VIR_FREE(data->content_context);
|
VIR_FREE(data->content_context);
|
||||||
|
virHashFree(data->mcs);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -355,7 +333,7 @@ virSecuritySELinuxGenSecurityLabel(virSecurityManagerPtr mgr,
|
|||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ((rv = virSecuritySELinuxMCSAdd(mcs)) < 0)
|
if ((rv = virSecuritySELinuxMCSAdd(mgr, mcs)) < 0)
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
if (rv == 0)
|
if (rv == 0)
|
||||||
break;
|
break;
|
||||||
@ -452,7 +430,7 @@ virSecuritySELinuxReserveSecurityLabel(virSecurityManagerPtr mgr ATTRIBUTE_UNUSE
|
|||||||
if (!mcs)
|
if (!mcs)
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
if ((rv = virSecuritySELinuxMCSAdd(mcs)) < 0)
|
if ((rv = virSecuritySELinuxMCSAdd(mgr, mcs)) < 0)
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
if (rv == 1) {
|
if (rv == 1) {
|
||||||
@ -504,6 +482,8 @@ virSecuritySELinuxSecurityDriverClose(virSecurityManagerPtr mgr)
|
|||||||
if (!data)
|
if (!data)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
virHashFree(data->mcs);
|
||||||
|
|
||||||
VIR_FREE(data->domain_context);
|
VIR_FREE(data->domain_context);
|
||||||
VIR_FREE(data->file_context);
|
VIR_FREE(data->file_context);
|
||||||
VIR_FREE(data->content_context);
|
VIR_FREE(data->content_context);
|
||||||
@ -1195,7 +1175,7 @@ virSecuritySELinuxRestoreSecurityAllLabel(virSecurityManagerPtr mgr ATTRIBUTE_UN
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
virSecuritySELinuxReleaseSecurityLabel(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
|
virSecuritySELinuxReleaseSecurityLabel(virSecurityManagerPtr mgr,
|
||||||
virDomainDefPtr def)
|
virDomainDefPtr def)
|
||||||
{
|
{
|
||||||
const virSecurityLabelDefPtr secdef = &def->seclabel;
|
const virSecurityLabelDefPtr secdef = &def->seclabel;
|
||||||
@ -1204,7 +1184,7 @@ virSecuritySELinuxReleaseSecurityLabel(virSecurityManagerPtr mgr ATTRIBUTE_UNUSE
|
|||||||
if (secdef->label != NULL) {
|
if (secdef->label != NULL) {
|
||||||
context_t con = context_new(secdef->label);
|
context_t con = context_new(secdef->label);
|
||||||
if (con) {
|
if (con) {
|
||||||
virSecuritySELinuxMCSRemove(context_range_get(con));
|
virSecuritySELinuxMCSRemove(mgr, context_range_get(con));
|
||||||
context_free(con);
|
context_free(con);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user