mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2024-10-29 17:33:09 +00:00
SELinux security driver for sVirt support (James Morris, Dan Walsh & Daniel Berrange)
This commit is contained in:
parent
aa2c97263d
commit
41ed6eb327
10
ChangeLog
10
ChangeLog
@ -1,3 +1,13 @@
|
|||||||
|
Tue Mar 3 10:01:13 GMT 2009 Daniel P. Berrange <berrange@redhat.com>
|
||||||
|
|
||||||
|
SELinux security driver for sVirt support (James Morris, Dan Walsh & Daniel
|
||||||
|
Berrange)
|
||||||
|
* configure.in: Check for selinux_virtual_domain_context_path() and
|
||||||
|
selinux_virtual_image_context_path() methods in libselinux.so
|
||||||
|
* po/POTFILES.in: add src/security_selinux.c
|
||||||
|
* src/Makefile.am, src/security.c, src/security_selinux.c,
|
||||||
|
src/security_selinux.h: Add SELinux impl of security driver API
|
||||||
|
|
||||||
Tue Mar 3 09:55:13 GMT 2009 Daniel P. Berrange <berrange@redhat.com>
|
Tue Mar 3 09:55:13 GMT 2009 Daniel P. Berrange <berrange@redhat.com>
|
||||||
|
|
||||||
virsh additions for sVirt support (James Morris & Dan Walsh)
|
virsh additions for sVirt support (James Morris & Dan Walsh)
|
||||||
|
43
configure.in
43
configure.in
@ -640,6 +640,45 @@ AM_CONDITIONAL([HAVE_SELINUX], [test "$with_selinux" != "no"])
|
|||||||
AC_SUBST([SELINUX_CFLAGS])
|
AC_SUBST([SELINUX_CFLAGS])
|
||||||
AC_SUBST([SELINUX_LIBS])
|
AC_SUBST([SELINUX_LIBS])
|
||||||
|
|
||||||
|
|
||||||
|
AC_ARG_WITH([secdriver-selinux],
|
||||||
|
[ --with-secdriver-selinux use SELinux security driver],
|
||||||
|
[],
|
||||||
|
[with_secdriver_selinux=check])
|
||||||
|
|
||||||
|
if test "$with_selinux" != "yes" ; then
|
||||||
|
if test "$with_secdriver_selinux" = "check" ; then
|
||||||
|
with_secdriver_selinux=no
|
||||||
|
else
|
||||||
|
AC_MSG_ERROR([You must install the SELinux development package in order to compile libvirt])
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
old_cflags="$CFLAGS"
|
||||||
|
old_libs="$LIBS"
|
||||||
|
CFLAGS="$CFLAGS $SELINUX_CFLAGS"
|
||||||
|
LIBS="$CFLAGS $SELINUX_LIBS"
|
||||||
|
|
||||||
|
fail=0
|
||||||
|
AC_CHECK_FUNC([selinux_virtual_domain_context_path], [], [fail=1])
|
||||||
|
AC_CHECK_FUNC([selinux_virtual_image_context_path], [], [fail=1])
|
||||||
|
CFLAGS="$old_cflags"
|
||||||
|
LIBS="$old_libs"
|
||||||
|
|
||||||
|
if test "$fail" = "1" ; then
|
||||||
|
if test "$with_secdriver_selinux" = "check" ; then
|
||||||
|
with_secdriver_selinux=no
|
||||||
|
else
|
||||||
|
AC_MSG_ERROR([You must install the SELinux development package in order to compile libvirt])
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
with_secdriver_selinux=yes
|
||||||
|
AC_DEFINE_UNQUOTED([WITH_SECDRIVER_SELINUX], 1, [whether SELinux security driver is available])
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
AM_CONDITIONAL([WITH_SECDRIVER_SELINUX], [test "$with_secdriver_selinux" != "no"])
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
dnl NUMA lib
|
dnl NUMA lib
|
||||||
AC_ARG_WITH([numactl],
|
AC_ARG_WITH([numactl],
|
||||||
[ --with-numactl use numactl for host topology info],
|
[ --with-numactl use numactl for host topology info],
|
||||||
@ -1320,6 +1359,10 @@ AC_MSG_NOTICE([ LVM: $with_storage_lvm])
|
|||||||
AC_MSG_NOTICE([ iSCSI: $with_storage_iscsi])
|
AC_MSG_NOTICE([ iSCSI: $with_storage_iscsi])
|
||||||
AC_MSG_NOTICE([ Disk: $with_storage_disk])
|
AC_MSG_NOTICE([ Disk: $with_storage_disk])
|
||||||
AC_MSG_NOTICE([])
|
AC_MSG_NOTICE([])
|
||||||
|
AC_MSG_NOTICE([Security Drivers])
|
||||||
|
AC_MSG_NOTICE([])
|
||||||
|
AC_MSG_NOTICE([ SELinux: $with_secdriver_selinux])
|
||||||
|
AC_MSG_NOTICE([])
|
||||||
AC_MSG_NOTICE([Driver Loadable Modules])
|
AC_MSG_NOTICE([Driver Loadable Modules])
|
||||||
AC_MSG_NOTICE([])
|
AC_MSG_NOTICE([])
|
||||||
if test "$with_driver_modules" != "no" ; then
|
if test "$with_driver_modules" != "no" ; then
|
||||||
|
@ -24,6 +24,7 @@ src/qemu_conf.c
|
|||||||
src/qemu_driver.c
|
src/qemu_driver.c
|
||||||
src/remote_internal.c
|
src/remote_internal.c
|
||||||
src/security.c
|
src/security.c
|
||||||
|
src/security_selinux.c
|
||||||
src/storage_backend.c
|
src/storage_backend.c
|
||||||
src/storage_backend_disk.c
|
src/storage_backend_disk.c
|
||||||
src/storage_backend_fs.c
|
src/storage_backend_fs.c
|
||||||
|
@ -170,6 +170,9 @@ STORAGE_HELPER_DISK_SOURCES = \
|
|||||||
SECURITY_DRIVER_SOURCES = \
|
SECURITY_DRIVER_SOURCES = \
|
||||||
security.h security.c
|
security.h security.c
|
||||||
|
|
||||||
|
SECURITY_DRIVER_SELINUX_SOURCES = \
|
||||||
|
security_selinux.h security_selinux.c
|
||||||
|
|
||||||
|
|
||||||
NODE_DEVICE_DRIVER_SOURCES = \
|
NODE_DEVICE_DRIVER_SOURCES = \
|
||||||
node_device.c node_device.h
|
node_device.c node_device.h
|
||||||
@ -387,6 +390,9 @@ endif
|
|||||||
libvirt_driver_security_la_SOURCES = $(SECURITY_DRIVER_SOURCES)
|
libvirt_driver_security_la_SOURCES = $(SECURITY_DRIVER_SOURCES)
|
||||||
noinst_LTLIBRARIES += libvirt_driver_security.la
|
noinst_LTLIBRARIES += libvirt_driver_security.la
|
||||||
libvirt_la_LIBADD += libvirt_driver_security.la
|
libvirt_la_LIBADD += libvirt_driver_security.la
|
||||||
|
if WITH_SECDRIVER_SELINUX
|
||||||
|
libvirt_driver_security_la_SOURCES += $(SECURITY_DRIVER_SELINUX_SOURCES)
|
||||||
|
endif
|
||||||
|
|
||||||
# Add all conditional sources just in case...
|
# Add all conditional sources just in case...
|
||||||
EXTRA_DIST += \
|
EXTRA_DIST += \
|
||||||
|
@ -16,8 +16,14 @@
|
|||||||
#include "virterror_internal.h"
|
#include "virterror_internal.h"
|
||||||
|
|
||||||
#include "security.h"
|
#include "security.h"
|
||||||
|
#ifdef WITH_SECDRIVER_SELINUX
|
||||||
|
#include "security_selinux.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
static virSecurityDriverPtr security_drivers[] = {
|
static virSecurityDriverPtr security_drivers[] = {
|
||||||
|
#ifdef WITH_SECDRIVER_SELINUX
|
||||||
|
&virSELinuxSecurityDriver,
|
||||||
|
#endif
|
||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
|
|
||||||
|
377
src/security_selinux.c
Normal file
377
src/security_selinux.c
Normal file
@ -0,0 +1,377 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2008 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.
|
||||||
|
*
|
||||||
|
* Authors:
|
||||||
|
* James Morris <jmorris@namei.org>
|
||||||
|
*
|
||||||
|
* SELinux security driver.
|
||||||
|
*/
|
||||||
|
#include <config.h>
|
||||||
|
#include <selinux/selinux.h>
|
||||||
|
#include <selinux/context.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
|
||||||
|
#include "security.h"
|
||||||
|
#include "security_selinux.h"
|
||||||
|
#include "virterror_internal.h"
|
||||||
|
#include "util.h"
|
||||||
|
#include "memory.h"
|
||||||
|
|
||||||
|
static char default_domain_context[1024];
|
||||||
|
static char default_image_context[1024];
|
||||||
|
#define SECURITY_SELINUX_VOID_DOI "0"
|
||||||
|
#define SECURITY_SELINUX_NAME "selinux"
|
||||||
|
|
||||||
|
/* TODO
|
||||||
|
The data struct of used mcs should be replaced with a better data structure in the future
|
||||||
|
*/
|
||||||
|
|
||||||
|
struct MCS {
|
||||||
|
char *mcs;
|
||||||
|
struct MCS *next;
|
||||||
|
};
|
||||||
|
static struct MCS *mcsList = NULL;
|
||||||
|
|
||||||
|
static int
|
||||||
|
mcsAdd(const char *mcs)
|
||||||
|
{
|
||||||
|
struct MCS *ptr;
|
||||||
|
|
||||||
|
for (ptr = mcsList; ptr; ptr = ptr->next) {
|
||||||
|
if (STREQ(ptr->mcs, mcs) == 0)
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
ptr = malloc(sizeof(struct MCS));
|
||||||
|
ptr->mcs = strdup(mcs);
|
||||||
|
ptr->next = mcsList;
|
||||||
|
mcsList = ptr;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
mcsRemove(const char *mcs)
|
||||||
|
{
|
||||||
|
struct MCS *prevptr = NULL;
|
||||||
|
struct MCS *ptr = NULL;
|
||||||
|
|
||||||
|
for (ptr = mcsList; ptr; ptr = ptr->next) {
|
||||||
|
if (STREQ(ptr->mcs, mcs) == 0) {
|
||||||
|
if (prevptr)
|
||||||
|
prevptr->next = ptr->next;
|
||||||
|
else {
|
||||||
|
mcsList = ptr->next;
|
||||||
|
}
|
||||||
|
free(ptr->mcs);
|
||||||
|
free(ptr);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
prevptr = ptr;
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static char *
|
||||||
|
SELinuxGenNewContext(const char *oldcontext, const char *mcs)
|
||||||
|
{
|
||||||
|
char *newcontext = NULL;
|
||||||
|
char *scontext = strdup(oldcontext);
|
||||||
|
if (!scontext) goto err;
|
||||||
|
context_t con = context_new(scontext);
|
||||||
|
if (!con) goto err;
|
||||||
|
context_range_set(con, mcs);
|
||||||
|
newcontext = strdup(context_str(con));
|
||||||
|
context_free(con);
|
||||||
|
err:
|
||||||
|
freecon(scontext);
|
||||||
|
return (newcontext);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
SELinuxInitialize(virConnectPtr conn)
|
||||||
|
{
|
||||||
|
char *ptr = NULL;
|
||||||
|
int fd = 0;
|
||||||
|
char ebuf[1024];
|
||||||
|
|
||||||
|
virRandomInitialize(time(NULL) ^ getpid());
|
||||||
|
|
||||||
|
fd = open(selinux_virtual_domain_context_path(), O_RDONLY);
|
||||||
|
if (fd < 0) {
|
||||||
|
virSecurityReportError(conn, VIR_ERR_ERROR,
|
||||||
|
_("%s: cannot open SELinux virtual domain context file %s: %s"),
|
||||||
|
__func__,selinux_virtual_domain_context_path(),
|
||||||
|
virStrerror(errno, ebuf, sizeof ebuf));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (saferead(fd, default_domain_context, sizeof(default_domain_context)) < 0) {
|
||||||
|
virSecurityReportError(conn, VIR_ERR_ERROR,
|
||||||
|
_("%s: cannot read SELinux virtual domain context file %s: %s"),
|
||||||
|
__func__,selinux_virtual_domain_context_path(),
|
||||||
|
virStrerror(errno, ebuf, sizeof ebuf));
|
||||||
|
close(fd);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
close(fd);
|
||||||
|
|
||||||
|
ptr = strchrnul(default_domain_context, '\n');
|
||||||
|
*ptr = '\0';
|
||||||
|
|
||||||
|
if ((fd = open(selinux_virtual_image_context_path(), O_RDONLY)) < 0) {
|
||||||
|
virSecurityReportError(conn, VIR_ERR_ERROR,
|
||||||
|
_("%s: cannot open SELinux virtual image context file %s: %s"),
|
||||||
|
__func__,selinux_virtual_image_context_path(),
|
||||||
|
virStrerror(errno, ebuf, sizeof ebuf));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (saferead(fd, default_image_context, sizeof(default_image_context)) < 0) {
|
||||||
|
virSecurityReportError(conn, VIR_ERR_ERROR,
|
||||||
|
_("%s: cannot read SELinux virtual image context file %s: %s"),
|
||||||
|
__func__,selinux_virtual_image_context_path(),
|
||||||
|
virStrerror(errno, ebuf, sizeof ebuf));
|
||||||
|
close(fd);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
close(fd);
|
||||||
|
|
||||||
|
ptr = strchrnul(default_image_context, '\n');
|
||||||
|
*ptr = '\0';
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
SELinuxGenSecurityLabel(virDomainObjPtr vm)
|
||||||
|
{
|
||||||
|
int rc = -1;
|
||||||
|
char mcs[1024];
|
||||||
|
char *scontext = NULL;
|
||||||
|
int c1 = 0;
|
||||||
|
int c2 = 0;
|
||||||
|
if ( ( vm->def->seclabel.label ) ||
|
||||||
|
( vm->def->seclabel.model ) ||
|
||||||
|
( vm->def->seclabel.imagelabel ))
|
||||||
|
return rc;
|
||||||
|
|
||||||
|
do {
|
||||||
|
c1 = virRandom(1024);
|
||||||
|
c2 = virRandom(1024);
|
||||||
|
|
||||||
|
if ( c1 == c2 ) {
|
||||||
|
sprintf(mcs, "s0:c%d", c1);
|
||||||
|
} else {
|
||||||
|
if ( c1 == c2 )
|
||||||
|
sprintf(mcs, "s0:c%d,c%d", c1, c2);
|
||||||
|
else
|
||||||
|
sprintf(mcs, "s0:c%d,c%d", c2, c1);
|
||||||
|
}
|
||||||
|
} while(mcsAdd(mcs) == -1);
|
||||||
|
|
||||||
|
vm->def->seclabel.label = SELinuxGenNewContext(default_domain_context, mcs);
|
||||||
|
if (! vm->def->seclabel.label) goto err;
|
||||||
|
vm->def->seclabel.imagelabel = SELinuxGenNewContext(default_image_context, mcs);
|
||||||
|
if (! vm->def->seclabel.imagelabel) goto err;
|
||||||
|
vm->def->seclabel.model = strdup(SECURITY_SELINUX_NAME);
|
||||||
|
if (! vm->def->seclabel.model) goto err;
|
||||||
|
|
||||||
|
rc = 0;
|
||||||
|
goto done;
|
||||||
|
err:
|
||||||
|
free(vm->def->seclabel.label); vm->def->seclabel.label = NULL;
|
||||||
|
free(vm->def->seclabel.imagelabel); vm->def->seclabel.imagelabel = NULL;
|
||||||
|
free(vm->def->seclabel.model); vm->def->seclabel.model = NULL;
|
||||||
|
done:
|
||||||
|
free(scontext);
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
SELinuxSecurityDriverProbe(void)
|
||||||
|
{
|
||||||
|
return is_selinux_enabled() ? SECURITY_DRIVER_ENABLE : SECURITY_DRIVER_DISABLE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
SELinuxSecurityDriverOpen(virConnectPtr conn, virSecurityDriverPtr drv)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* Where will the DOI come from? SELinux configuration, or qemu
|
||||||
|
* configuration? For the moment, we'll just set it to "0".
|
||||||
|
*/
|
||||||
|
virSecurityDriverSetDOI(conn, drv, SECURITY_SELINUX_VOID_DOI);
|
||||||
|
return SELinuxInitialize(conn);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
SELinuxGetSecurityLabel(virConnectPtr conn,
|
||||||
|
virDomainObjPtr vm,
|
||||||
|
virSecurityLabelPtr sec)
|
||||||
|
{
|
||||||
|
security_context_t ctx;
|
||||||
|
|
||||||
|
if (getpidcon(vm->pid, &ctx) == -1) {
|
||||||
|
char ebuf[1024];
|
||||||
|
virSecurityReportError(conn, VIR_ERR_ERROR, _("%s: error calling "
|
||||||
|
"getpidcon(): %s"), __func__,
|
||||||
|
virStrerror(errno, ebuf, sizeof ebuf));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strlen((char *) ctx) >= VIR_SECURITY_LABEL_BUFLEN) {
|
||||||
|
virSecurityReportError(conn, VIR_ERR_ERROR,
|
||||||
|
_("%s: security label exceeds "
|
||||||
|
"maximum lenth: %d"), __func__,
|
||||||
|
VIR_SECURITY_LABEL_BUFLEN - 1);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
strcpy(sec->label, (char *) ctx);
|
||||||
|
free(ctx);
|
||||||
|
|
||||||
|
sec->enforcing = security_getenforce();
|
||||||
|
if (sec->enforcing == -1) {
|
||||||
|
char ebuf[1024];
|
||||||
|
virSecurityReportError(conn, VIR_ERR_ERROR, _("%s: error calling "
|
||||||
|
"security_getenforce(): %s"), __func__,
|
||||||
|
virStrerror(errno, ebuf, sizeof ebuf));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
SELinuxSetFilecon(virConnectPtr conn, char *path, char *tcon)
|
||||||
|
{
|
||||||
|
char ebuf[1024];
|
||||||
|
|
||||||
|
if(setfilecon(path, tcon) < 0) {
|
||||||
|
virSecurityReportError(conn, VIR_ERR_ERROR,
|
||||||
|
_("%s: unable to set security context "
|
||||||
|
"'\%s\' on %s: %s."), __func__,
|
||||||
|
tcon,
|
||||||
|
path,
|
||||||
|
virStrerror(errno, ebuf, sizeof ebuf));
|
||||||
|
if (security_getenforce() == 1)
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
SELinuxRestoreSecurityImageLabel(virConnectPtr conn,
|
||||||
|
virDomainObjPtr vm,
|
||||||
|
virDomainDeviceDefPtr dev)
|
||||||
|
{
|
||||||
|
const virSecurityLabelDefPtr secdef = &vm->def->seclabel;
|
||||||
|
|
||||||
|
if (secdef->imagelabel) {
|
||||||
|
return SELinuxSetFilecon(conn, dev->data.disk->src, default_image_context);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
SELinuxSetSecurityImageLabel(virConnectPtr conn,
|
||||||
|
virDomainObjPtr vm,
|
||||||
|
virDomainDeviceDefPtr dev)
|
||||||
|
|
||||||
|
{
|
||||||
|
const virSecurityLabelDefPtr secdef = &vm->def->seclabel;
|
||||||
|
|
||||||
|
if (secdef->imagelabel) {
|
||||||
|
return SELinuxSetFilecon(conn, dev->data.disk->src, secdef->imagelabel);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
SELinuxRestoreSecurityLabel(virConnectPtr conn,
|
||||||
|
virDomainObjPtr vm)
|
||||||
|
{
|
||||||
|
const virSecurityLabelDefPtr secdef = &vm->def->seclabel;
|
||||||
|
int i;
|
||||||
|
int rc = 0;
|
||||||
|
if (secdef->imagelabel) {
|
||||||
|
for (i = 0 ; i < vm->def->ndisks ; i++) {
|
||||||
|
if (SELinuxSetFilecon(conn, vm->def->disks[i]->src, default_image_context) < 0)
|
||||||
|
rc = -1;
|
||||||
|
}
|
||||||
|
VIR_FREE(secdef->model);
|
||||||
|
VIR_FREE(secdef->label);
|
||||||
|
context_t con = context_new(secdef->imagelabel);
|
||||||
|
if (con) {
|
||||||
|
mcsRemove(context_range_get(con));
|
||||||
|
context_free(con);
|
||||||
|
}
|
||||||
|
VIR_FREE(secdef->imagelabel);
|
||||||
|
}
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
SELinuxSetSecurityLabel(virConnectPtr conn,
|
||||||
|
virSecurityDriverPtr drv,
|
||||||
|
virDomainObjPtr vm)
|
||||||
|
{
|
||||||
|
/* TODO: verify DOI */
|
||||||
|
const virSecurityLabelDefPtr secdef = &vm->def->seclabel;
|
||||||
|
int i;
|
||||||
|
char ebuf[1024];
|
||||||
|
|
||||||
|
if (!STREQ(drv->name, secdef->model)) {
|
||||||
|
virSecurityReportError(conn, VIR_ERR_ERROR,
|
||||||
|
_("%s: security label driver mismatch: "
|
||||||
|
"\'%s\' model configured for domain, but "
|
||||||
|
"hypervisor driver is \'%s\'."),
|
||||||
|
__func__, secdef->model, drv->name);
|
||||||
|
if (security_getenforce() == 1)
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (setexeccon(secdef->label) == -1) {
|
||||||
|
virSecurityReportError(conn, VIR_ERR_ERROR,
|
||||||
|
_("%s: unable to set security context "
|
||||||
|
"'\%s\': %s."), __func__, secdef->label,
|
||||||
|
virStrerror(errno, ebuf, sizeof ebuf));
|
||||||
|
if (security_getenforce() == 1)
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (secdef->imagelabel) {
|
||||||
|
for (i = 0 ; i < vm->def->ndisks ; i++) {
|
||||||
|
if(setfilecon(vm->def->disks[i]->src, secdef->imagelabel) < 0) {
|
||||||
|
virSecurityReportError(conn, VIR_ERR_ERROR,
|
||||||
|
_("%s: unable to set security context "
|
||||||
|
"'\%s\' on %s: %s."), __func__,
|
||||||
|
secdef->imagelabel,
|
||||||
|
vm->def->disks[i]->src,
|
||||||
|
virStrerror(errno, ebuf, sizeof ebuf));
|
||||||
|
if (security_getenforce() == 1)
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
virSecurityDriver virSELinuxSecurityDriver = {
|
||||||
|
.name = SECURITY_SELINUX_NAME,
|
||||||
|
.probe = SELinuxSecurityDriverProbe,
|
||||||
|
.open = SELinuxSecurityDriverOpen,
|
||||||
|
.domainSetSecurityImageLabel = SELinuxSetSecurityImageLabel,
|
||||||
|
.domainRestoreSecurityImageLabel = SELinuxRestoreSecurityImageLabel,
|
||||||
|
.domainGenSecurityLabel = SELinuxGenSecurityLabel,
|
||||||
|
.domainGetSecurityLabel = SELinuxGetSecurityLabel,
|
||||||
|
.domainRestoreSecurityLabel = SELinuxRestoreSecurityLabel,
|
||||||
|
.domainSetSecurityLabel = SELinuxSetSecurityLabel,
|
||||||
|
};
|
18
src/security_selinux.h
Normal file
18
src/security_selinux.h
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2008 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.
|
||||||
|
*
|
||||||
|
* Authors:
|
||||||
|
* James Morris <jmorris@namei.org>
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#ifndef __VIR_SECURITY_SELINUX_H__
|
||||||
|
#define __VIR_SECURITY_SELINUX_H__
|
||||||
|
|
||||||
|
extern virSecurityDriver virSELinuxSecurityDriver;
|
||||||
|
|
||||||
|
#endif /* __VIR_SECURITY_SELINUX_H__ */
|
Loading…
Reference in New Issue
Block a user