mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2024-11-02 19:31:18 +00:00
ea151935bb
otherwise we crash later on if we don't find a match like:
#0 0xb72c2b4f in virSecurityManagerGenLabel (mgr=0xb8e42d20, vm=0xb8ef40c0) at security/security_manager.c:424
#1 0xb18811f3 in qemuProcessStart (conn=conn@entry=0xb8eed880, driver=driver@entry=0xb8e3b1e0, vm=vm@entry=0xb8ef58f0,
migrateFrom=migrateFrom@entry=0xb18f6088 "stdio", stdin_fd=18,
stdin_path=stdin_path@entry=0xb8ea7798 "/var/lib/jenkins/jobs/libvirt-tck-build/workspace/tck.img", snapshot=snapshot@entry=0x0,
vmop=vmop@entry=VIR_NETDEV_VPORT_PROFILE_OP_RESTORE, flags=flags@entry=2) at qemu/qemu_process.c:3364
#2 0xb18d6cb2 in qemuDomainSaveImageStartVM (conn=conn@entry=0xb8eed880, driver=driver@entry=0xb8e3b1e0, vm=0xb8ef58f0, fd=fd@entry=0xb6bf3f98,
header=header@entry=0xb6bf3fa0, path=path@entry=0xb8ea7798 "/var/lib/jenkins/jobs/libvirt-tck-build/workspace/tck.img",
start_paused=start_paused@entry=false) at qemu/qemu_driver.c:4843
#3 0xb18d7eeb in qemuDomainRestoreFlags (conn=conn@entry=0xb8eed880,
path=path@entry=0xb8ea7798 "/var/lib/jenkins/jobs/libvirt-tck-build/workspace/tck.img", dxml=dxml@entry=0x0, flags=flags@entry=0)
at qemu/qemu_driver.c:4962
#4 0xb18d8123 in qemuDomainRestore (conn=0xb8eed880, path=0xb8ea7798 "/var/lib/jenkins/jobs/libvirt-tck-build/workspace/tck.img")
at qemu/qemu_driver.c:4987
#5 0xb718d186 in virDomainRestore (conn=0xb8eed880, from=0xb8ea87d8 "/var/lib/jenkins/jobs/libvirt-tck-build/workspace/tck.img") at libvirt.c:2768
#6 0xb7736363 in remoteDispatchDomainRestore (args=<optimized out>, rerr=0xb6bf41f0, client=0xb8eedaf0, server=<optimized out>, msg=<optimized out>)
at remote_dispatch.h:4679
#7 remoteDispatchDomainRestoreHelper (server=0xb8e1a3e0, client=0xb8eedaf0, msg=0xb8ee72c8, rerr=0xb6bf41f0, args=0xb8ea8968, ret=0xb8ef5330)
at remote_dispatch.h:4661
#8 0xb720db01 in virNetServerProgramDispatchCall (msg=0xb8ee72c8, client=0xb8eedaf0, server=0xb8e1a3e0, prog=0xb8e216b0)
at rpc/virnetserverprogram.c:439
#9 virNetServerProgramDispatch (prog=0xb8e216b0, server=server@entry=0xb8e1a3e0, client=0xb8eedaf0, msg=0xb8ee72c8) at rpc/virnetserverprogram.c:305
#10 0xb7206e97 in virNetServerProcessMsg (msg=<optimized out>, prog=<optimized out>, client=<optimized out>, srv=0xb8e1a3e0) at rpc/virnetserver.c:162
#11 virNetServerHandleJob (jobOpaque=0xb8ea7720, opaque=0xb8e1a3e0) at rpc/virnetserver.c:183
#12 0xb70f9f78 in virThreadPoolWorker (opaque=opaque@entry=0xb8e1a540) at util/virthreadpool.c:144
#13 0xb70f94a5 in virThreadHelper (data=0xb8e0e558) at util/virthreadpthread.c:161
#14 0xb705d954 in start_thread (arg=0xb6bf4b70) at pthread_create.c:304
#15 0xb6fd595e in clone () at ../sysdeps/unix/sysv/linux/i386/clone.S:130
This unbreaks libvirt-tck's domain/100-transient-save-restore.t with
qemu:///session and selinux compiled in but disabled.
Introduced by 8d68cbeaa8
730 lines
21 KiB
C
730 lines
21 KiB
C
/*
|
|
* security_manager.c: Internal security manager API
|
|
*
|
|
* Copyright (C) 2010-2013 Red Hat, Inc.
|
|
*
|
|
* This library is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
* License as published by the Free Software Foundation; either
|
|
* version 2.1 of the License, or (at your option) any later version.
|
|
*
|
|
* This library is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
* Lesser General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
* License along with this library. If not, see
|
|
* <http://www.gnu.org/licenses/>.
|
|
*
|
|
* Author: Daniel P. Berrange <berrange@redhat.com>
|
|
*/
|
|
|
|
#include <config.h>
|
|
|
|
|
|
#include "security_driver.h"
|
|
#include "security_stack.h"
|
|
#include "security_dac.h"
|
|
#include "virerror.h"
|
|
#include "viralloc.h"
|
|
#include "virobject.h"
|
|
#include "virlog.h"
|
|
|
|
#define VIR_FROM_THIS VIR_FROM_SECURITY
|
|
|
|
|
|
struct _virSecurityManager {
|
|
virObjectLockable parent;
|
|
|
|
virSecurityDriverPtr drv;
|
|
bool allowDiskFormatProbing;
|
|
bool defaultConfined;
|
|
bool requireConfined;
|
|
const char *virtDriver;
|
|
void *privateData;
|
|
};
|
|
|
|
static virClassPtr virSecurityManagerClass;
|
|
|
|
static void virSecurityManagerDispose(void *obj);
|
|
|
|
static int virSecurityManagerOnceInit(void)
|
|
{
|
|
if (!(virSecurityManagerClass = virClassNew(virClassForObjectLockable(),
|
|
"virSecurityManagerClass",
|
|
sizeof(virSecurityManager),
|
|
virSecurityManagerDispose)))
|
|
return -1;
|
|
|
|
return 0;
|
|
}
|
|
|
|
VIR_ONCE_GLOBAL_INIT(virSecurityManager);
|
|
|
|
static virSecurityManagerPtr virSecurityManagerNewDriver(virSecurityDriverPtr drv,
|
|
const char *virtDriver,
|
|
bool allowDiskFormatProbing,
|
|
bool defaultConfined,
|
|
bool requireConfined)
|
|
{
|
|
virSecurityManagerPtr mgr;
|
|
char *privateData;
|
|
|
|
if (virSecurityManagerInitialize() < 0)
|
|
return NULL;
|
|
|
|
VIR_DEBUG("drv=%p (%s) virtDriver=%s allowDiskFormatProbing=%d "
|
|
"defaultConfined=%d requireConfined=%d",
|
|
drv, drv->name, virtDriver,
|
|
allowDiskFormatProbing, defaultConfined,
|
|
requireConfined);
|
|
|
|
if (VIR_ALLOC_N(privateData, drv->privateDataLen) < 0) {
|
|
virReportOOMError();
|
|
return NULL;
|
|
}
|
|
|
|
if (!(mgr = virObjectLockableNew(virSecurityManagerClass))) {
|
|
VIR_FREE(privateData);
|
|
return NULL;
|
|
}
|
|
|
|
mgr->drv = drv;
|
|
mgr->allowDiskFormatProbing = allowDiskFormatProbing;
|
|
mgr->defaultConfined = defaultConfined;
|
|
mgr->requireConfined = requireConfined;
|
|
mgr->virtDriver = virtDriver;
|
|
mgr->privateData = privateData;
|
|
|
|
if (drv->open(mgr) < 0) {
|
|
virObjectUnref(mgr);
|
|
return NULL;
|
|
}
|
|
|
|
return mgr;
|
|
}
|
|
|
|
virSecurityManagerPtr virSecurityManagerNewStack(virSecurityManagerPtr primary)
|
|
{
|
|
virSecurityManagerPtr mgr =
|
|
virSecurityManagerNewDriver(&virSecurityDriverStack,
|
|
virSecurityManagerGetDriver(primary),
|
|
virSecurityManagerGetAllowDiskFormatProbing(primary),
|
|
virSecurityManagerGetDefaultConfined(primary),
|
|
virSecurityManagerGetRequireConfined(primary));
|
|
|
|
if (!mgr)
|
|
return NULL;
|
|
|
|
virSecurityStackAddNested(mgr, primary);
|
|
|
|
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,
|
|
uid_t user,
|
|
gid_t group,
|
|
bool allowDiskFormatProbing,
|
|
bool defaultConfined,
|
|
bool requireConfined,
|
|
bool dynamicOwnership)
|
|
{
|
|
virSecurityManagerPtr mgr =
|
|
virSecurityManagerNewDriver(&virSecurityDriverDAC,
|
|
virtDriver,
|
|
allowDiskFormatProbing,
|
|
defaultConfined,
|
|
requireConfined);
|
|
|
|
if (!mgr)
|
|
return NULL;
|
|
|
|
virSecurityDACSetUser(mgr, user);
|
|
virSecurityDACSetGroup(mgr, group);
|
|
virSecurityDACSetDynamicOwnership(mgr, dynamicOwnership);
|
|
|
|
return mgr;
|
|
}
|
|
|
|
virSecurityManagerPtr virSecurityManagerNew(const char *name,
|
|
const char *virtDriver,
|
|
bool allowDiskFormatProbing,
|
|
bool defaultConfined,
|
|
bool requireConfined)
|
|
{
|
|
virSecurityDriverPtr drv = virSecurityDriverLookup(name, virtDriver);
|
|
if (!drv)
|
|
return NULL;
|
|
|
|
/* driver "none" needs some special handling of *Confined bools */
|
|
if (STREQ(drv->name, "none")) {
|
|
if (requireConfined) {
|
|
virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
|
|
_("Security driver \"none\" cannot create confined guests"));
|
|
return NULL;
|
|
}
|
|
|
|
if (defaultConfined) {
|
|
if (name != NULL) {
|
|
VIR_WARN("Configured security driver \"none\" disables default"
|
|
" policy to create confined guests");
|
|
} else {
|
|
VIR_DEBUG("Auto-probed security driver is \"none\";"
|
|
" confined guests will not be created");
|
|
}
|
|
defaultConfined = false;
|
|
}
|
|
}
|
|
|
|
return virSecurityManagerNewDriver(drv,
|
|
virtDriver,
|
|
allowDiskFormatProbing,
|
|
defaultConfined,
|
|
requireConfined);
|
|
}
|
|
|
|
|
|
/*
|
|
* Must be called before fork()'ing to ensure mutex state
|
|
* is sane for the child to use
|
|
*/
|
|
void virSecurityManagerPreFork(virSecurityManagerPtr mgr)
|
|
{
|
|
virObjectLock(mgr);
|
|
}
|
|
|
|
|
|
/*
|
|
* Must be called after fork()'ing in both parent and child
|
|
* to ensure mutex state is sane for the child to use
|
|
*/
|
|
void virSecurityManagerPostFork(virSecurityManagerPtr mgr)
|
|
{
|
|
virObjectUnlock(mgr);
|
|
}
|
|
|
|
void *virSecurityManagerGetPrivateData(virSecurityManagerPtr mgr)
|
|
{
|
|
return mgr->privateData;
|
|
}
|
|
|
|
|
|
static void virSecurityManagerDispose(void *obj)
|
|
{
|
|
virSecurityManagerPtr mgr = obj;
|
|
|
|
if (mgr->drv->close)
|
|
mgr->drv->close(mgr);
|
|
VIR_FREE(mgr->privateData);
|
|
}
|
|
|
|
const char *
|
|
virSecurityManagerGetDriver(virSecurityManagerPtr mgr)
|
|
{
|
|
return mgr->virtDriver;
|
|
}
|
|
|
|
const char *
|
|
virSecurityManagerGetDOI(virSecurityManagerPtr mgr)
|
|
{
|
|
if (mgr->drv->getDOI) {
|
|
const char *ret;
|
|
virObjectLock(mgr);
|
|
ret = mgr->drv->getDOI(mgr);
|
|
virObjectUnlock(mgr);
|
|
return ret;
|
|
}
|
|
|
|
virReportError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
|
|
return NULL;
|
|
}
|
|
|
|
const char *
|
|
virSecurityManagerGetModel(virSecurityManagerPtr mgr)
|
|
{
|
|
if (mgr->drv->getModel) {
|
|
const char *ret;
|
|
virObjectLock(mgr);
|
|
ret = mgr->drv->getModel(mgr);
|
|
virObjectUnlock(mgr);
|
|
return ret;
|
|
}
|
|
|
|
virReportError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
|
|
return NULL;
|
|
}
|
|
|
|
bool virSecurityManagerGetAllowDiskFormatProbing(virSecurityManagerPtr mgr)
|
|
{
|
|
return mgr->allowDiskFormatProbing;
|
|
}
|
|
|
|
bool virSecurityManagerGetDefaultConfined(virSecurityManagerPtr mgr)
|
|
{
|
|
return mgr->defaultConfined;
|
|
}
|
|
|
|
bool virSecurityManagerGetRequireConfined(virSecurityManagerPtr mgr)
|
|
{
|
|
return mgr->requireConfined;
|
|
}
|
|
|
|
int virSecurityManagerRestoreImageLabel(virSecurityManagerPtr mgr,
|
|
virDomainDefPtr vm,
|
|
virDomainDiskDefPtr disk)
|
|
{
|
|
if (mgr->drv->domainRestoreSecurityImageLabel) {
|
|
int ret;
|
|
virObjectLock(mgr);
|
|
ret = mgr->drv->domainRestoreSecurityImageLabel(mgr, vm, disk);
|
|
virObjectUnlock(mgr);
|
|
return ret;
|
|
}
|
|
|
|
virReportError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
|
|
return -1;
|
|
}
|
|
|
|
int virSecurityManagerSetDaemonSocketLabel(virSecurityManagerPtr mgr,
|
|
virDomainDefPtr vm)
|
|
{
|
|
if (mgr->drv->domainSetSecurityDaemonSocketLabel) {
|
|
int ret;
|
|
virObjectLock(mgr);
|
|
ret = mgr->drv->domainSetSecurityDaemonSocketLabel(mgr, vm);
|
|
virObjectUnlock(mgr);
|
|
return ret;
|
|
}
|
|
|
|
virReportError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
|
|
return -1;
|
|
}
|
|
|
|
int virSecurityManagerSetSocketLabel(virSecurityManagerPtr mgr,
|
|
virDomainDefPtr vm)
|
|
{
|
|
if (mgr->drv->domainSetSecuritySocketLabel) {
|
|
int ret;
|
|
virObjectLock(mgr);
|
|
ret = mgr->drv->domainSetSecuritySocketLabel(mgr, vm);
|
|
virObjectUnlock(mgr);
|
|
return ret;
|
|
}
|
|
|
|
virReportError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
|
|
return -1;
|
|
}
|
|
|
|
int virSecurityManagerClearSocketLabel(virSecurityManagerPtr mgr,
|
|
virDomainDefPtr vm)
|
|
{
|
|
if (mgr->drv->domainClearSecuritySocketLabel) {
|
|
int ret;
|
|
virObjectLock(mgr);
|
|
ret = mgr->drv->domainClearSecuritySocketLabel(mgr, vm);
|
|
virObjectUnlock(mgr);
|
|
return ret;
|
|
}
|
|
|
|
virReportError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
|
|
return -1;
|
|
}
|
|
|
|
int virSecurityManagerSetImageLabel(virSecurityManagerPtr mgr,
|
|
virDomainDefPtr vm,
|
|
virDomainDiskDefPtr disk)
|
|
{
|
|
if (mgr->drv->domainSetSecurityImageLabel) {
|
|
int ret;
|
|
virObjectLock(mgr);
|
|
ret = mgr->drv->domainSetSecurityImageLabel(mgr, vm, disk);
|
|
virObjectUnlock(mgr);
|
|
return ret;
|
|
}
|
|
|
|
virReportError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
|
|
return -1;
|
|
}
|
|
|
|
int virSecurityManagerRestoreHostdevLabel(virSecurityManagerPtr mgr,
|
|
virDomainDefPtr vm,
|
|
virDomainHostdevDefPtr dev,
|
|
const char *vroot)
|
|
{
|
|
if (mgr->drv->domainRestoreSecurityHostdevLabel) {
|
|
int ret;
|
|
virObjectLock(mgr);
|
|
ret = mgr->drv->domainRestoreSecurityHostdevLabel(mgr, vm, dev, vroot);
|
|
virObjectUnlock(mgr);
|
|
return ret;
|
|
}
|
|
|
|
virReportError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
|
|
return -1;
|
|
}
|
|
|
|
int virSecurityManagerSetHostdevLabel(virSecurityManagerPtr mgr,
|
|
virDomainDefPtr vm,
|
|
virDomainHostdevDefPtr dev,
|
|
const char *vroot)
|
|
{
|
|
if (mgr->drv->domainSetSecurityHostdevLabel) {
|
|
int ret;
|
|
virObjectLock(mgr);
|
|
ret = mgr->drv->domainSetSecurityHostdevLabel(mgr, vm, dev, vroot);
|
|
virObjectUnlock(mgr);
|
|
return ret;
|
|
}
|
|
|
|
virReportError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
|
|
return -1;
|
|
}
|
|
|
|
int virSecurityManagerSetSavedStateLabel(virSecurityManagerPtr mgr,
|
|
virDomainDefPtr vm,
|
|
const char *savefile)
|
|
{
|
|
if (mgr->drv->domainSetSavedStateLabel) {
|
|
int ret;
|
|
virObjectLock(mgr);
|
|
ret = mgr->drv->domainSetSavedStateLabel(mgr, vm, savefile);
|
|
virObjectUnlock(mgr);
|
|
return ret;
|
|
}
|
|
|
|
virReportError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
|
|
return -1;
|
|
}
|
|
|
|
int virSecurityManagerRestoreSavedStateLabel(virSecurityManagerPtr mgr,
|
|
virDomainDefPtr vm,
|
|
const char *savefile)
|
|
{
|
|
if (mgr->drv->domainRestoreSavedStateLabel) {
|
|
int ret;
|
|
virObjectLock(mgr);
|
|
ret = mgr->drv->domainRestoreSavedStateLabel(mgr, vm, savefile);
|
|
virObjectUnlock(mgr);
|
|
return ret;
|
|
}
|
|
|
|
virReportError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
|
|
return -1;
|
|
}
|
|
|
|
int virSecurityManagerGenLabel(virSecurityManagerPtr mgr,
|
|
virDomainDefPtr vm)
|
|
{
|
|
int ret = -1;
|
|
size_t i, j;
|
|
virSecurityManagerPtr* sec_managers = NULL;
|
|
virSecurityLabelDefPtr seclabel;
|
|
bool generated = false;
|
|
|
|
if (mgr == NULL || mgr->drv == NULL)
|
|
return ret;
|
|
|
|
if ((sec_managers = virSecurityManagerGetNested(mgr)) == NULL)
|
|
return ret;
|
|
|
|
virObjectLock(mgr);
|
|
for (i = 0; i < vm->nseclabels; i++) {
|
|
for (j = 0; sec_managers[j]; j++)
|
|
if (STREQ(vm->seclabels[i]->model, sec_managers[j]->drv->name))
|
|
break;
|
|
|
|
if (!sec_managers[j]) {
|
|
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
|
|
_("Unable to find security driver for label %s"),
|
|
vm->seclabels[i]->model);
|
|
goto cleanup;
|
|
}
|
|
}
|
|
|
|
for (i = 0; sec_managers[i]; i++) {
|
|
generated = false;
|
|
seclabel = virDomainDefGetSecurityLabelDef(vm, sec_managers[i]->drv->name);
|
|
if (!seclabel) {
|
|
if (!(seclabel = virDomainDefGenSecurityLabelDef(sec_managers[i]->drv->name)))
|
|
goto cleanup;
|
|
generated = seclabel->implicit = true;
|
|
}
|
|
|
|
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;
|
|
seclabel->norelabel = true;
|
|
}
|
|
}
|
|
|
|
if (seclabel->type == VIR_DOMAIN_SECLABEL_NONE) {
|
|
if (sec_managers[i]->requireConfined) {
|
|
virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
|
|
_("Unconfined guests are not allowed on this host"));
|
|
goto cleanup;
|
|
} else if (vm->nseclabels && generated) {
|
|
VIR_DEBUG("Skipping auto generated seclabel of type none");
|
|
virSecurityLabelDefFree(seclabel);
|
|
seclabel = NULL;
|
|
continue;
|
|
}
|
|
}
|
|
|
|
if (!sec_managers[i]->drv->domainGenSecurityLabel) {
|
|
virReportError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
|
|
} else {
|
|
/* The seclabel must be added to @vm prior calling domainGenSecurityLabel
|
|
* which may require seclabel to be presented already */
|
|
if (generated &&
|
|
VIR_APPEND_ELEMENT(vm->seclabels, vm->nseclabels, seclabel) < 0) {
|
|
virReportOOMError();
|
|
goto cleanup;
|
|
}
|
|
|
|
if (sec_managers[i]->drv->domainGenSecurityLabel(sec_managers[i], vm) < 0) {
|
|
if (VIR_DELETE_ELEMENT(vm->seclabels,
|
|
vm->nseclabels -1, vm->nseclabels) < 0)
|
|
vm->nseclabels--;
|
|
goto cleanup;
|
|
}
|
|
|
|
seclabel = NULL;
|
|
}
|
|
}
|
|
|
|
ret = 0;
|
|
|
|
cleanup:
|
|
virObjectUnlock(mgr);
|
|
if (generated)
|
|
virSecurityLabelDefFree(seclabel);
|
|
VIR_FREE(sec_managers);
|
|
return ret;
|
|
}
|
|
|
|
int virSecurityManagerReserveLabel(virSecurityManagerPtr mgr,
|
|
virDomainDefPtr vm,
|
|
pid_t pid)
|
|
{
|
|
if (mgr->drv->domainReserveSecurityLabel) {
|
|
int ret;
|
|
virObjectLock(mgr);
|
|
ret = mgr->drv->domainReserveSecurityLabel(mgr, vm, pid);
|
|
virObjectUnlock(mgr);
|
|
return ret;
|
|
}
|
|
|
|
virReportError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
|
|
return -1;
|
|
}
|
|
|
|
int virSecurityManagerReleaseLabel(virSecurityManagerPtr mgr,
|
|
virDomainDefPtr vm)
|
|
{
|
|
if (mgr->drv->domainReleaseSecurityLabel) {
|
|
int ret;
|
|
virObjectLock(mgr);
|
|
ret = mgr->drv->domainReleaseSecurityLabel(mgr, vm);
|
|
virObjectUnlock(mgr);
|
|
return ret;
|
|
}
|
|
|
|
virReportError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
|
|
return -1;
|
|
}
|
|
|
|
int virSecurityManagerSetAllLabel(virSecurityManagerPtr mgr,
|
|
virDomainDefPtr vm,
|
|
const char *stdin_path)
|
|
{
|
|
if (mgr->drv->domainSetSecurityAllLabel) {
|
|
int ret;
|
|
virObjectLock(mgr);
|
|
ret = mgr->drv->domainSetSecurityAllLabel(mgr, vm, stdin_path);
|
|
virObjectUnlock(mgr);
|
|
return ret;
|
|
}
|
|
|
|
virReportError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
|
|
return -1;
|
|
}
|
|
|
|
int virSecurityManagerRestoreAllLabel(virSecurityManagerPtr mgr,
|
|
virDomainDefPtr vm,
|
|
int migrated)
|
|
{
|
|
if (mgr->drv->domainRestoreSecurityAllLabel) {
|
|
int ret;
|
|
virObjectLock(mgr);
|
|
ret = mgr->drv->domainRestoreSecurityAllLabel(mgr, vm, migrated);
|
|
virObjectUnlock(mgr);
|
|
return ret;
|
|
}
|
|
|
|
virReportError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
|
|
return -1;
|
|
}
|
|
|
|
int virSecurityManagerGetProcessLabel(virSecurityManagerPtr mgr,
|
|
virDomainDefPtr vm,
|
|
pid_t pid,
|
|
virSecurityLabelPtr sec)
|
|
{
|
|
if (mgr->drv->domainGetSecurityProcessLabel) {
|
|
int ret;
|
|
virObjectLock(mgr);
|
|
ret = mgr->drv->domainGetSecurityProcessLabel(mgr, vm, pid, sec);
|
|
virObjectUnlock(mgr);
|
|
return ret;
|
|
}
|
|
|
|
virReportError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
|
|
return -1;
|
|
}
|
|
|
|
int virSecurityManagerSetProcessLabel(virSecurityManagerPtr mgr,
|
|
virDomainDefPtr vm)
|
|
{
|
|
if (mgr->drv->domainSetSecurityProcessLabel) {
|
|
int ret;
|
|
virObjectLock(mgr);
|
|
ret = mgr->drv->domainSetSecurityProcessLabel(mgr, vm);
|
|
virObjectUnlock(mgr);
|
|
return ret;
|
|
}
|
|
|
|
virReportError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
|
|
return -1;
|
|
}
|
|
|
|
int virSecurityManagerSetChildProcessLabel(virSecurityManagerPtr mgr,
|
|
virDomainDefPtr vm,
|
|
virCommandPtr cmd)
|
|
{
|
|
if (mgr->drv->domainSetSecurityChildProcessLabel)
|
|
return mgr->drv->domainSetSecurityChildProcessLabel(mgr, vm, cmd);
|
|
|
|
virReportError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
|
|
return -1;
|
|
}
|
|
|
|
int virSecurityManagerVerify(virSecurityManagerPtr mgr,
|
|
virDomainDefPtr def)
|
|
{
|
|
virSecurityLabelDefPtr secdef;
|
|
|
|
if (mgr == NULL || mgr->drv == NULL)
|
|
return 0;
|
|
|
|
/* NULL model == dynamic labelling, with whatever driver
|
|
* is active, so we can short circuit verify check to
|
|
* avoid drivers de-referencing NULLs by accident
|
|
*/
|
|
secdef = virDomainDefGetSecurityLabelDef(def, mgr->drv->name);
|
|
if (secdef == NULL || secdef->model == NULL)
|
|
return 0;
|
|
|
|
if (mgr->drv->domainSecurityVerify) {
|
|
int ret;
|
|
virObjectLock(mgr);
|
|
ret = mgr->drv->domainSecurityVerify(mgr, def);
|
|
virObjectUnlock(mgr);
|
|
return ret;
|
|
}
|
|
|
|
virReportError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
|
|
return -1;
|
|
}
|
|
|
|
int virSecurityManagerSetImageFDLabel(virSecurityManagerPtr mgr,
|
|
virDomainDefPtr vm,
|
|
int fd)
|
|
{
|
|
if (mgr->drv->domainSetSecurityImageFDLabel) {
|
|
int ret;
|
|
virObjectLock(mgr);
|
|
ret = mgr->drv->domainSetSecurityImageFDLabel(mgr, vm, fd);
|
|
virObjectUnlock(mgr);
|
|
return ret;
|
|
}
|
|
|
|
virReportError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
|
|
return -1;
|
|
}
|
|
|
|
int virSecurityManagerSetTapFDLabel(virSecurityManagerPtr mgr,
|
|
virDomainDefPtr vm,
|
|
int fd)
|
|
{
|
|
if (mgr->drv->domainSetSecurityTapFDLabel) {
|
|
int ret;
|
|
virObjectLock(mgr);
|
|
ret = mgr->drv->domainSetSecurityTapFDLabel(mgr, vm, fd);
|
|
virObjectUnlock(mgr);
|
|
return ret;
|
|
}
|
|
|
|
virReportError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
|
|
return -1;
|
|
}
|
|
|
|
char *virSecurityManagerGetMountOptions(virSecurityManagerPtr mgr,
|
|
virDomainDefPtr vm)
|
|
{
|
|
if (mgr->drv->domainGetSecurityMountOptions) {
|
|
char *ret;
|
|
virObjectLock(mgr);
|
|
ret = mgr->drv->domainGetSecurityMountOptions(mgr, vm);
|
|
virObjectUnlock(mgr);
|
|
return ret;
|
|
}
|
|
|
|
virReportError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
|
|
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;
|
|
}
|
|
|
|
int virSecurityManagerSetHugepages(virSecurityManagerPtr mgr,
|
|
virDomainDefPtr vm,
|
|
const char *path)
|
|
{
|
|
if (mgr->drv->domainSetSecurityHugepages) {
|
|
int ret;
|
|
virObjectLock(mgr);
|
|
ret = mgr->drv->domainSetSecurityHugepages(mgr, vm, path);
|
|
virObjectUnlock(mgr);
|
|
return ret;
|
|
}
|
|
|
|
return 0;
|
|
}
|