mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2024-12-29 00:55:22 +00:00
selinux: Only create the selabel_handle once.
According to Eric Paris this is slightly more efficient because it
only loads the regular expressions in libselinux once.
(cherry picked from commit 6159710ca1
)
Conflicts:
src/security/security_selinux.c
This commit is contained in:
parent
460e481647
commit
f63b9694dc
@ -62,6 +62,9 @@ struct _virSecuritySELinuxData {
|
|||||||
char *content_context;
|
char *content_context;
|
||||||
virHashTablePtr mcs;
|
virHashTablePtr mcs;
|
||||||
bool skipAllLabel;
|
bool skipAllLabel;
|
||||||
|
#if HAVE_SELINUX_LABEL_H
|
||||||
|
struct selabel_handle *label_handle;
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _virSecuritySELinuxCallbackData {
|
struct _virSecuritySELinuxCallbackData {
|
||||||
@ -366,12 +369,21 @@ virSecuritySELinuxLXCInitialize(virSecurityManagerPtr mgr)
|
|||||||
|
|
||||||
data->skipAllLabel = true;
|
data->skipAllLabel = true;
|
||||||
|
|
||||||
|
#if HAVE_SELINUX_LABEL_H
|
||||||
|
data->label_handle = selabel_open(SELABEL_CTX_FILE, NULL, 0);
|
||||||
|
if (!data->label_handle) {
|
||||||
|
virReportSystemError(errno, "%s",
|
||||||
|
_("cannot open SELinux label_handle"));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
selinux_conf = virConfReadFile(selinux_lxc_contexts_path(), 0);
|
selinux_conf = virConfReadFile(selinux_lxc_contexts_path(), 0);
|
||||||
if (!selinux_conf) {
|
if (!selinux_conf) {
|
||||||
virReportSystemError(errno,
|
virReportSystemError(errno,
|
||||||
_("cannot open SELinux lxc contexts file '%s'"),
|
_("cannot open SELinux lxc contexts file '%s'"),
|
||||||
selinux_lxc_contexts_path());
|
selinux_lxc_contexts_path());
|
||||||
return -1;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
scon = virConfGetValue(selinux_conf, "process");
|
scon = virConfGetValue(selinux_conf, "process");
|
||||||
@ -417,6 +429,9 @@ virSecuritySELinuxLXCInitialize(virSecurityManagerPtr mgr)
|
|||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
error:
|
error:
|
||||||
|
#if HAVE_SELINUX_LABEL_H
|
||||||
|
selabel_close(data->label_handle);
|
||||||
|
#endif
|
||||||
virConfFree(selinux_conf);
|
virConfFree(selinux_conf);
|
||||||
VIR_FREE(data->domain_context);
|
VIR_FREE(data->domain_context);
|
||||||
VIR_FREE(data->file_context);
|
VIR_FREE(data->file_context);
|
||||||
@ -443,6 +458,15 @@ virSecuritySELinuxQEMUInitialize(virSecurityManagerPtr mgr)
|
|||||||
|
|
||||||
data->skipAllLabel = false;
|
data->skipAllLabel = false;
|
||||||
|
|
||||||
|
#if HAVE_SELINUX_LABEL_H
|
||||||
|
data->label_handle = selabel_open(SELABEL_CTX_FILE, NULL, 0);
|
||||||
|
if (!data->label_handle) {
|
||||||
|
virReportSystemError(errno, "%s",
|
||||||
|
_("cannot open SELinux label_handle"));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
if (virFileReadAll(selinux_virtual_domain_context_path(), MAX_CONTEXT, &(data->domain_context)) < 0) {
|
if (virFileReadAll(selinux_virtual_domain_context_path(), MAX_CONTEXT, &(data->domain_context)) < 0) {
|
||||||
virReportSystemError(errno,
|
virReportSystemError(errno,
|
||||||
_("cannot read SELinux virtual domain context file '%s'"),
|
_("cannot read SELinux virtual domain context file '%s'"),
|
||||||
@ -480,6 +504,9 @@ virSecuritySELinuxQEMUInitialize(virSecurityManagerPtr mgr)
|
|||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
error:
|
error:
|
||||||
|
#if HAVE_SELINUX_LABEL_H
|
||||||
|
selabel_close(data->label_handle);
|
||||||
|
#endif
|
||||||
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);
|
||||||
@ -724,6 +751,10 @@ virSecuritySELinuxSecurityDriverClose(virSecurityManagerPtr mgr)
|
|||||||
if (!data)
|
if (!data)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
#if HAVE_SELINUX_LABEL_H
|
||||||
|
selabel_close(data->label_handle);
|
||||||
|
#endif
|
||||||
|
|
||||||
virHashFree(data->mcs);
|
virHashFree(data->mcs);
|
||||||
|
|
||||||
VIR_FREE(data->domain_context);
|
VIR_FREE(data->domain_context);
|
||||||
@ -897,18 +928,13 @@ virSecuritySELinuxFSetFilecon(int fd, char *tcon)
|
|||||||
|
|
||||||
/* Set fcon to the appropriate label for path and mode, or return -1. */
|
/* Set fcon to the appropriate label for path and mode, or return -1. */
|
||||||
static int
|
static int
|
||||||
getContext(const char *newpath, mode_t mode, security_context_t *fcon)
|
getContext(virSecurityManagerPtr mgr,
|
||||||
|
const char *newpath, mode_t mode, security_context_t *fcon)
|
||||||
{
|
{
|
||||||
#if HAVE_SELINUX_LABEL_H
|
#if HAVE_SELINUX_LABEL_H
|
||||||
struct selabel_handle *handle = selabel_open(SELABEL_CTX_FILE, NULL, 0);
|
virSecuritySELinuxDataPtr data = virSecurityManagerGetPrivateData(mgr);
|
||||||
int ret;
|
|
||||||
|
|
||||||
if (handle == NULL)
|
return selabel_lookup_raw(data->label_handle, fcon, newpath, mode);
|
||||||
return -1;
|
|
||||||
|
|
||||||
ret = selabel_lookup_raw(handle, fcon, newpath, mode);
|
|
||||||
selabel_close(handle);
|
|
||||||
return ret;
|
|
||||||
#else
|
#else
|
||||||
return matchpathcon(newpath, mode, fcon);
|
return matchpathcon(newpath, mode, fcon);
|
||||||
#endif
|
#endif
|
||||||
@ -918,7 +944,8 @@ getContext(const char *newpath, mode_t mode, security_context_t *fcon)
|
|||||||
/* This method shouldn't raise errors, since they'll overwrite
|
/* This method shouldn't raise errors, since they'll overwrite
|
||||||
* errors that the caller(s) are already dealing with */
|
* errors that the caller(s) are already dealing with */
|
||||||
static int
|
static int
|
||||||
virSecuritySELinuxRestoreSecurityFileLabel(const char *path)
|
virSecuritySELinuxRestoreSecurityFileLabel(virSecurityManagerPtr mgr,
|
||||||
|
const char *path)
|
||||||
{
|
{
|
||||||
struct stat buf;
|
struct stat buf;
|
||||||
security_context_t fcon = NULL;
|
security_context_t fcon = NULL;
|
||||||
@ -940,7 +967,7 @@ virSecuritySELinuxRestoreSecurityFileLabel(const char *path)
|
|||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (getContext(newpath, buf.st_mode, &fcon) < 0) {
|
if (getContext(mgr, newpath, buf.st_mode, &fcon) < 0) {
|
||||||
/* Any user created path likely does not have a default label,
|
/* Any user created path likely does not have a default label,
|
||||||
* which makes this an expected non error
|
* which makes this an expected non error
|
||||||
*/
|
*/
|
||||||
@ -957,7 +984,7 @@ err:
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
virSecuritySELinuxRestoreSecurityImageLabelInt(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
|
virSecuritySELinuxRestoreSecurityImageLabelInt(virSecurityManagerPtr mgr,
|
||||||
virDomainDefPtr def,
|
virDomainDefPtr def,
|
||||||
virDomainDiskDefPtr disk,
|
virDomainDiskDefPtr disk,
|
||||||
int migrated)
|
int migrated)
|
||||||
@ -1004,7 +1031,7 @@ virSecuritySELinuxRestoreSecurityImageLabelInt(virSecurityManagerPtr mgr ATTRIBU
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return virSecuritySELinuxRestoreSecurityFileLabel(disk->src);
|
return virSecuritySELinuxRestoreSecurityFileLabel(mgr, disk->src);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1189,24 +1216,27 @@ done:
|
|||||||
static int
|
static int
|
||||||
virSecuritySELinuxRestoreSecurityPCILabel(pciDevice *dev ATTRIBUTE_UNUSED,
|
virSecuritySELinuxRestoreSecurityPCILabel(pciDevice *dev ATTRIBUTE_UNUSED,
|
||||||
const char *file,
|
const char *file,
|
||||||
void *opaque ATTRIBUTE_UNUSED)
|
void *opaque)
|
||||||
{
|
{
|
||||||
return virSecuritySELinuxRestoreSecurityFileLabel(file);
|
virSecurityManagerPtr mgr = opaque;
|
||||||
|
|
||||||
|
return virSecuritySELinuxRestoreSecurityFileLabel(mgr, file);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
virSecuritySELinuxRestoreSecurityUSBLabel(usbDevice *dev ATTRIBUTE_UNUSED,
|
virSecuritySELinuxRestoreSecurityUSBLabel(usbDevice *dev ATTRIBUTE_UNUSED,
|
||||||
const char *file,
|
const char *file,
|
||||||
void *opaque ATTRIBUTE_UNUSED)
|
void *opaque)
|
||||||
{
|
{
|
||||||
return virSecuritySELinuxRestoreSecurityFileLabel(file);
|
virSecurityManagerPtr mgr = opaque;
|
||||||
|
|
||||||
|
return virSecuritySELinuxRestoreSecurityFileLabel(mgr, file);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
virSecuritySELinuxRestoreSecurityHostdevLabel(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
|
virSecuritySELinuxRestoreSecurityHostdevLabel(virSecurityManagerPtr mgr,
|
||||||
virDomainDefPtr def,
|
virDomainDefPtr def,
|
||||||
virDomainHostdevDefPtr dev)
|
virDomainHostdevDefPtr dev)
|
||||||
|
|
||||||
{
|
{
|
||||||
virSecurityLabelDefPtr secdef;
|
virSecurityLabelDefPtr secdef;
|
||||||
int ret = -1;
|
int ret = -1;
|
||||||
@ -1229,7 +1259,7 @@ virSecuritySELinuxRestoreSecurityHostdevLabel(virSecurityManagerPtr mgr ATTRIBUT
|
|||||||
if (!usb)
|
if (!usb)
|
||||||
goto done;
|
goto done;
|
||||||
|
|
||||||
ret = usbDeviceFileIterate(usb, virSecuritySELinuxRestoreSecurityUSBLabel, NULL);
|
ret = usbDeviceFileIterate(usb, virSecuritySELinuxRestoreSecurityUSBLabel, mgr);
|
||||||
usbFreeDevice(usb);
|
usbFreeDevice(usb);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
@ -1244,7 +1274,7 @@ virSecuritySELinuxRestoreSecurityHostdevLabel(virSecurityManagerPtr mgr ATTRIBUT
|
|||||||
if (!pci)
|
if (!pci)
|
||||||
goto done;
|
goto done;
|
||||||
|
|
||||||
ret = pciDeviceFileIterate(pci, virSecuritySELinuxRestoreSecurityPCILabel, NULL);
|
ret = pciDeviceFileIterate(pci, virSecuritySELinuxRestoreSecurityPCILabel, mgr);
|
||||||
pciFreeDevice(pci);
|
pciFreeDevice(pci);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
@ -1334,7 +1364,8 @@ done:
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
virSecuritySELinuxRestoreSecurityChardevLabel(virDomainDefPtr def,
|
virSecuritySELinuxRestoreSecurityChardevLabel(virSecurityManagerPtr mgr,
|
||||||
|
virDomainDefPtr def,
|
||||||
virDomainChrDefPtr dev,
|
virDomainChrDefPtr dev,
|
||||||
virDomainChrSourceDefPtr dev_source)
|
virDomainChrSourceDefPtr dev_source)
|
||||||
|
|
||||||
@ -1357,14 +1388,14 @@ virSecuritySELinuxRestoreSecurityChardevLabel(virDomainDefPtr def,
|
|||||||
switch (dev_source->type) {
|
switch (dev_source->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:
|
||||||
if (virSecuritySELinuxRestoreSecurityFileLabel(dev_source->data.file.path) < 0)
|
if (virSecuritySELinuxRestoreSecurityFileLabel(mgr, dev_source->data.file.path) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
ret = 0;
|
ret = 0;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case VIR_DOMAIN_CHR_TYPE_UNIX:
|
case VIR_DOMAIN_CHR_TYPE_UNIX:
|
||||||
if (!dev_source->data.nix.listen) {
|
if (!dev_source->data.nix.listen) {
|
||||||
if (virSecuritySELinuxRestoreSecurityFileLabel(dev_source->data.file.path) < 0)
|
if (virSecuritySELinuxRestoreSecurityFileLabel(mgr, dev_source->data.file.path) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
ret = 0;
|
ret = 0;
|
||||||
@ -1377,11 +1408,11 @@ virSecuritySELinuxRestoreSecurityChardevLabel(virDomainDefPtr def,
|
|||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
if (virFileExists(in) && virFileExists(out)) {
|
if (virFileExists(in) && virFileExists(out)) {
|
||||||
if ((virSecuritySELinuxRestoreSecurityFileLabel(out) < 0) ||
|
if ((virSecuritySELinuxRestoreSecurityFileLabel(mgr, out) < 0) ||
|
||||||
(virSecuritySELinuxRestoreSecurityFileLabel(in) < 0)) {
|
(virSecuritySELinuxRestoreSecurityFileLabel(mgr, in) < 0)) {
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
} else if (virSecuritySELinuxRestoreSecurityFileLabel(dev_source->data.file.path) < 0) {
|
} else if (virSecuritySELinuxRestoreSecurityFileLabel(mgr, dev_source->data.file.path) < 0) {
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
ret = 0;
|
ret = 0;
|
||||||
@ -1402,14 +1433,16 @@ done:
|
|||||||
static int
|
static int
|
||||||
virSecuritySELinuxRestoreSecurityChardevCallback(virDomainDefPtr def,
|
virSecuritySELinuxRestoreSecurityChardevCallback(virDomainDefPtr def,
|
||||||
virDomainChrDefPtr dev,
|
virDomainChrDefPtr dev,
|
||||||
void *opaque ATTRIBUTE_UNUSED)
|
void *opaque)
|
||||||
{
|
{
|
||||||
|
virSecurityManagerPtr mgr = opaque;
|
||||||
|
|
||||||
/* This is taken care of by processing of def->serials */
|
/* This is taken care of by processing of def->serials */
|
||||||
if (dev->deviceType == VIR_DOMAIN_CHR_DEVICE_TYPE_CONSOLE &&
|
if (dev->deviceType == VIR_DOMAIN_CHR_DEVICE_TYPE_CONSOLE &&
|
||||||
dev->targetType == VIR_DOMAIN_CHR_CONSOLE_TARGET_TYPE_SERIAL)
|
dev->targetType == VIR_DOMAIN_CHR_CONSOLE_TARGET_TYPE_SERIAL)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
return virSecuritySELinuxRestoreSecurityChardevLabel(def, dev,
|
return virSecuritySELinuxRestoreSecurityChardevLabel(mgr, def, dev,
|
||||||
&dev->source);
|
&dev->source);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1417,8 +1450,9 @@ virSecuritySELinuxRestoreSecurityChardevCallback(virDomainDefPtr def,
|
|||||||
static int
|
static int
|
||||||
virSecuritySELinuxRestoreSecuritySmartcardCallback(virDomainDefPtr def,
|
virSecuritySELinuxRestoreSecuritySmartcardCallback(virDomainDefPtr def,
|
||||||
virDomainSmartcardDefPtr dev,
|
virDomainSmartcardDefPtr dev,
|
||||||
void *opaque ATTRIBUTE_UNUSED)
|
void *opaque)
|
||||||
{
|
{
|
||||||
|
virSecurityManagerPtr mgr = opaque;
|
||||||
const char *database;
|
const char *database;
|
||||||
|
|
||||||
switch (dev->type) {
|
switch (dev->type) {
|
||||||
@ -1429,10 +1463,10 @@ virSecuritySELinuxRestoreSecuritySmartcardCallback(virDomainDefPtr def,
|
|||||||
database = dev->data.cert.database;
|
database = dev->data.cert.database;
|
||||||
if (!database)
|
if (!database)
|
||||||
database = VIR_DOMAIN_SMARTCARD_DEFAULT_DATABASE;
|
database = VIR_DOMAIN_SMARTCARD_DEFAULT_DATABASE;
|
||||||
return virSecuritySELinuxRestoreSecurityFileLabel(database);
|
return virSecuritySELinuxRestoreSecurityFileLabel(mgr, database);
|
||||||
|
|
||||||
case VIR_DOMAIN_SMARTCARD_TYPE_PASSTHROUGH:
|
case VIR_DOMAIN_SMARTCARD_TYPE_PASSTHROUGH:
|
||||||
return virSecuritySELinuxRestoreSecurityChardevLabel(def, NULL, &dev->data.passthru);
|
return virSecuritySELinuxRestoreSecurityChardevLabel(mgr, def, NULL, &dev->data.passthru);
|
||||||
|
|
||||||
default:
|
default:
|
||||||
virReportError(VIR_ERR_INTERNAL_ERROR,
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
||||||
@ -1481,21 +1515,21 @@ virSecuritySELinuxRestoreSecurityAllLabel(virSecurityManagerPtr mgr,
|
|||||||
if (virDomainChrDefForeach(def,
|
if (virDomainChrDefForeach(def,
|
||||||
false,
|
false,
|
||||||
virSecuritySELinuxRestoreSecurityChardevCallback,
|
virSecuritySELinuxRestoreSecurityChardevCallback,
|
||||||
NULL) < 0)
|
mgr) < 0)
|
||||||
rc = -1;
|
rc = -1;
|
||||||
|
|
||||||
if (virDomainSmartcardDefForeach(def,
|
if (virDomainSmartcardDefForeach(def,
|
||||||
false,
|
false,
|
||||||
virSecuritySELinuxRestoreSecuritySmartcardCallback,
|
virSecuritySELinuxRestoreSecuritySmartcardCallback,
|
||||||
NULL) < 0)
|
mgr) < 0)
|
||||||
rc = -1;
|
rc = -1;
|
||||||
|
|
||||||
if (def->os.kernel &&
|
if (def->os.kernel &&
|
||||||
virSecuritySELinuxRestoreSecurityFileLabel(def->os.kernel) < 0)
|
virSecuritySELinuxRestoreSecurityFileLabel(mgr, def->os.kernel) < 0)
|
||||||
rc = -1;
|
rc = -1;
|
||||||
|
|
||||||
if (def->os.initrd &&
|
if (def->os.initrd &&
|
||||||
virSecuritySELinuxRestoreSecurityFileLabel(def->os.initrd) < 0)
|
virSecuritySELinuxRestoreSecurityFileLabel(mgr, def->os.initrd) < 0)
|
||||||
rc = -1;
|
rc = -1;
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
@ -1548,7 +1582,7 @@ virSecuritySELinuxSetSavedStateLabel(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
|
|||||||
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
virSecuritySELinuxRestoreSavedStateLabel(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
|
virSecuritySELinuxRestoreSavedStateLabel(virSecurityManagerPtr mgr,
|
||||||
virDomainDefPtr def,
|
virDomainDefPtr def,
|
||||||
const char *savefile)
|
const char *savefile)
|
||||||
{
|
{
|
||||||
@ -1561,7 +1595,7 @@ virSecuritySELinuxRestoreSavedStateLabel(virSecurityManagerPtr mgr ATTRIBUTE_UNU
|
|||||||
if (secdef->norelabel)
|
if (secdef->norelabel)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
return virSecuritySELinuxRestoreSecurityFileLabel(savefile);
|
return virSecuritySELinuxRestoreSecurityFileLabel(mgr, savefile);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1890,7 +1924,7 @@ virSecuritySELinuxSetImageFDLabel(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
virSecuritySELinuxSetTapFDLabel(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
|
virSecuritySELinuxSetTapFDLabel(virSecurityManagerPtr mgr,
|
||||||
virDomainDefPtr def,
|
virDomainDefPtr def,
|
||||||
int fd)
|
int fd)
|
||||||
{
|
{
|
||||||
@ -1918,7 +1952,7 @@ virSecuritySELinuxSetTapFDLabel(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
|
|||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (getContext("/dev/tap.*", buf.st_mode, &fcon) < 0) {
|
if (getContext(mgr, "/dev/tap.*", buf.st_mode, &fcon) < 0) {
|
||||||
virReportError(VIR_ERR_INTERNAL_ERROR,
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
||||||
_("cannot lookup default selinux label for tap fd %d"), fd);
|
_("cannot lookup default selinux label for tap fd %d"), fd);
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
Loading…
Reference in New Issue
Block a user