2009-03-03 10:06:49 +00:00
|
|
|
/*
|
2012-05-11 10:43:30 +01:00
|
|
|
* Copyright (C) 2008-2012 Red Hat, Inc.
|
2009-03-03 10:06:49 +00:00
|
|
|
*
|
|
|
|
* 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.
|
|
|
|
*
|
2012-07-21 18:06:23 +08:00
|
|
|
* 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
|
2012-09-20 16:30:55 -06:00
|
|
|
* License along with this library. If not, see
|
2012-07-21 18:06:23 +08:00
|
|
|
* <http://www.gnu.org/licenses/>.
|
|
|
|
*
|
2009-03-03 10:06:49 +00:00
|
|
|
* Authors:
|
|
|
|
* James Morris <jmorris@namei.org>
|
2009-04-03 10:55:51 +00:00
|
|
|
* Dan Walsh <dwalsh@redhat.com>
|
2009-03-03 10:06:49 +00:00
|
|
|
*
|
|
|
|
* 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>
|
2010-12-14 17:07:52 -07:00
|
|
|
#if HAVE_SELINUX_LABEL_H
|
|
|
|
# include <selinux/label.h>
|
|
|
|
#endif
|
2009-03-03 10:06:49 +00:00
|
|
|
|
2009-09-15 19:06:37 +01:00
|
|
|
#include "security_driver.h"
|
2009-03-03 10:06:49 +00:00
|
|
|
#include "security_selinux.h"
|
|
|
|
#include "virterror_internal.h"
|
|
|
|
#include "util.h"
|
|
|
|
#include "memory.h"
|
2009-07-03 10:26:37 +00:00
|
|
|
#include "logging.h"
|
2009-08-14 14:23:11 +01:00
|
|
|
#include "pci.h"
|
|
|
|
#include "hostusb.h"
|
2009-09-25 14:20:13 +01:00
|
|
|
#include "storage_file.h"
|
2011-07-19 12:32:58 -06:00
|
|
|
#include "virfile.h"
|
2012-05-24 17:22:29 +01:00
|
|
|
#include "virhash.h"
|
2012-01-25 15:17:46 +00:00
|
|
|
#include "virrandom.h"
|
2012-05-11 10:43:30 +01:00
|
|
|
#include "util.h"
|
|
|
|
#include "conf.h"
|
2009-03-03 15:18:24 +00:00
|
|
|
|
|
|
|
#define VIR_FROM_THIS VIR_FROM_SECURITY
|
|
|
|
|
2012-05-11 10:43:30 +01:00
|
|
|
#define MAX_CONTEXT 1024
|
|
|
|
|
|
|
|
typedef struct _virSecuritySELinuxData virSecuritySELinuxData;
|
|
|
|
typedef virSecuritySELinuxData *virSecuritySELinuxDataPtr;
|
|
|
|
|
|
|
|
typedef struct _virSecuritySELinuxCallbackData virSecuritySELinuxCallbackData;
|
|
|
|
typedef virSecuritySELinuxCallbackData *virSecuritySELinuxCallbackDataPtr;
|
|
|
|
|
|
|
|
struct _virSecuritySELinuxData {
|
|
|
|
char *domain_context;
|
2012-12-12 11:47:19 +00:00
|
|
|
char *alt_domain_context;
|
2012-05-11 10:43:30 +01:00
|
|
|
char *file_context;
|
|
|
|
char *content_context;
|
2012-05-24 17:22:29 +01:00
|
|
|
virHashTablePtr mcs;
|
2012-11-28 13:54:39 +00:00
|
|
|
bool skipAllLabel;
|
2012-05-11 10:43:30 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
struct _virSecuritySELinuxCallbackData {
|
|
|
|
virSecurityManagerPtr manager;
|
|
|
|
virSecurityLabelDefPtr secdef;
|
|
|
|
};
|
|
|
|
|
2009-03-03 10:06:49 +00:00
|
|
|
#define SECURITY_SELINUX_VOID_DOI "0"
|
|
|
|
#define SECURITY_SELINUX_NAME "selinux"
|
|
|
|
|
2012-05-24 16:52:18 +01:00
|
|
|
/*
|
|
|
|
* Returns 0 on success, 1 if already reserved, or -1 on fatal error
|
|
|
|
*/
|
2009-03-03 10:06:49 +00:00
|
|
|
static int
|
2012-05-24 17:22:29 +01:00
|
|
|
virSecuritySELinuxMCSAdd(virSecurityManagerPtr mgr,
|
|
|
|
const char *mcs)
|
2009-03-03 10:06:49 +00:00
|
|
|
{
|
2012-05-24 17:22:29 +01:00
|
|
|
virSecuritySELinuxDataPtr data = virSecurityManagerGetPrivateData(mgr);
|
2009-03-03 10:06:49 +00:00
|
|
|
|
2012-05-24 17:22:29 +01:00
|
|
|
if (virHashLookup(data->mcs, mcs))
|
|
|
|
return 1;
|
|
|
|
|
|
|
|
if (virHashAddEntry(data->mcs, mcs, (void*)0x1) < 0)
|
2012-05-24 16:52:18 +01:00
|
|
|
return -1;
|
2012-05-24 17:22:29 +01:00
|
|
|
|
2009-03-03 10:06:49 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2012-05-24 17:22:29 +01:00
|
|
|
static void
|
|
|
|
virSecuritySELinuxMCSRemove(virSecurityManagerPtr mgr,
|
|
|
|
const char *mcs)
|
2009-03-03 10:06:49 +00:00
|
|
|
{
|
2012-05-24 17:22:29 +01:00
|
|
|
virSecuritySELinuxDataPtr data = virSecurityManagerGetPrivateData(mgr);
|
|
|
|
|
|
|
|
virHashRemoveEntry(data->mcs, mcs);
|
2009-03-03 10:06:49 +00:00
|
|
|
}
|
|
|
|
|
2012-08-09 17:43:12 +01:00
|
|
|
|
|
|
|
static char *
|
|
|
|
virSecuritySELinuxMCSFind(virSecurityManagerPtr mgr)
|
|
|
|
{
|
|
|
|
virSecuritySELinuxDataPtr data = virSecurityManagerGetPrivateData(mgr);
|
|
|
|
int c1 = 0;
|
|
|
|
int c2 = 0;
|
|
|
|
char *mcs = NULL;
|
2012-08-10 14:27:51 +01:00
|
|
|
security_context_t ourSecContext = NULL;
|
|
|
|
context_t ourContext = NULL;
|
|
|
|
char *sens, *cat, *tmp;
|
|
|
|
int catMin, catMax, catRange;
|
|
|
|
|
2012-10-05 16:41:22 +02:00
|
|
|
if (getcon_raw(&ourSecContext) < 0) {
|
2012-08-10 14:27:51 +01:00
|
|
|
virReportSystemError(errno, "%s",
|
|
|
|
_("Unable to get current process SELinux context"));
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
if (!(ourContext = context_new(ourSecContext))) {
|
|
|
|
virReportSystemError(errno,
|
|
|
|
_("Unable to parse current SELinux context '%s'"),
|
|
|
|
ourSecContext);
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!(sens = strdup(context_range_get(ourContext)))) {
|
|
|
|
virReportOOMError();
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Find and blank out the category part */
|
|
|
|
if (!(tmp = strchr(sens, ':'))) {
|
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
|
_("Cannot parse sensitivity level in %s"),
|
|
|
|
sens);
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
*tmp = '\0';
|
|
|
|
cat = tmp + 1;
|
|
|
|
/* Find and blank out the sensitivity upper bound */
|
|
|
|
if ((tmp = strchr(sens, '-')))
|
|
|
|
*tmp = '\0';
|
|
|
|
/* sens now just contains the sensitivity lower bound */
|
|
|
|
|
|
|
|
/* Find & extract category min */
|
|
|
|
tmp = cat;
|
|
|
|
if (tmp[0] != 'c') {
|
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
|
_("Cannot parse category in %s"),
|
|
|
|
cat);
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
tmp++;
|
|
|
|
if (virStrToLong_i(tmp, &tmp, 10, &catMin) < 0) {
|
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
|
_("Cannot parse category in %s"),
|
|
|
|
cat);
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* We *must* have a pair of categories otherwise
|
|
|
|
* there's no range to allocate VM categories from */
|
|
|
|
if (!tmp[0]) {
|
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
|
|
|
_("No category range available"));
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Find & extract category max (if any) */
|
|
|
|
if (tmp[0] != '.') {
|
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
|
_("Cannot parse category in %s"),
|
|
|
|
cat);
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
tmp++;
|
|
|
|
if (tmp[0] != 'c') {
|
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
|
_("Cannot parse category in %s"),
|
|
|
|
cat);
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
tmp++;
|
|
|
|
if (virStrToLong_i(tmp, &tmp, 10, &catMax) < 0) {
|
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
|
_("Cannot parse category in %s"),
|
|
|
|
cat);
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* +1 since virRandomInt range is exclusive of the upper bound */
|
|
|
|
catRange = (catMax - catMin) + 1;
|
|
|
|
|
|
|
|
if (catRange < 8) {
|
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
|
_("Category range c%d-c%d too small"),
|
|
|
|
catMin, catMax);
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
VIR_DEBUG("Using sensitivity level '%s' cat min %d max %d range %d",
|
|
|
|
sens, catMin, catMax, catRange);
|
2012-08-09 17:43:12 +01:00
|
|
|
|
|
|
|
for (;;) {
|
2012-08-10 14:27:51 +01:00
|
|
|
c1 = virRandomInt(catRange);
|
|
|
|
c2 = virRandomInt(catRange);
|
|
|
|
VIR_DEBUG("Try cat %s:c%d,c%d", sens, c1+catMin, c2+catMin);
|
2012-08-09 17:43:12 +01:00
|
|
|
|
|
|
|
if (c1 == c2) {
|
2012-08-10 14:27:51 +01:00
|
|
|
if (virAsprintf(&mcs, "%s:c%d", sens, catMin + c1) < 0) {
|
2012-08-09 17:43:12 +01:00
|
|
|
virReportOOMError();
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
if (c1 > c2) {
|
|
|
|
int t = c1;
|
|
|
|
c1 = c2;
|
|
|
|
c2 = t;
|
|
|
|
}
|
2012-08-10 14:27:51 +01:00
|
|
|
if (virAsprintf(&mcs, "%s:c%d,c%d", sens, catMin + c1, catMin + c2) < 0) {
|
2012-08-09 17:43:12 +01:00
|
|
|
virReportOOMError();
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (virHashLookup(data->mcs, mcs) == NULL)
|
|
|
|
goto cleanup;
|
|
|
|
|
|
|
|
VIR_FREE(mcs);
|
|
|
|
}
|
|
|
|
|
|
|
|
cleanup:
|
|
|
|
VIR_DEBUG("Found context '%s'", NULLSTR(mcs));
|
2012-08-10 14:27:51 +01:00
|
|
|
VIR_FREE(sens);
|
|
|
|
freecon(ourSecContext);
|
|
|
|
context_free(ourContext);
|
2012-08-09 17:43:12 +01:00
|
|
|
return mcs;
|
|
|
|
}
|
|
|
|
|
2012-10-15 17:03:49 +08:00
|
|
|
static char *
|
|
|
|
virSecuritySELinuxContextAddRange(security_context_t src,
|
|
|
|
security_context_t dst)
|
|
|
|
{
|
|
|
|
char *str = NULL;
|
|
|
|
char *ret = NULL;
|
|
|
|
context_t srccon = NULL;
|
|
|
|
context_t dstcon = NULL;
|
|
|
|
|
|
|
|
if (!src || !dst)
|
|
|
|
return ret;
|
|
|
|
|
|
|
|
if (!(srccon = context_new(src)) || !(dstcon = context_new(dst))) {
|
|
|
|
virReportSystemError(errno, "%s",
|
|
|
|
_("unable to allocate security context"));
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (context_range_set(dstcon, context_range_get(srccon)) == -1) {
|
|
|
|
virReportSystemError(errno,
|
|
|
|
_("unable to set security context range '%s'"), dst);
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!(str = context_str(dstcon))) {
|
|
|
|
virReportSystemError(errno, "%s",
|
|
|
|
_("Unable to format SELinux context"));
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!(ret = strdup(str))) {
|
|
|
|
virReportOOMError();
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
cleanup:
|
|
|
|
if (srccon) context_free(srccon);
|
|
|
|
if (dstcon) context_free(dstcon);
|
|
|
|
return ret;
|
|
|
|
}
|
2012-08-09 17:43:12 +01:00
|
|
|
|
2009-03-03 10:06:49 +00:00
|
|
|
static char *
|
2012-08-20 16:12:14 +02:00
|
|
|
virSecuritySELinuxGenNewContext(const char *basecontext,
|
|
|
|
const char *mcs,
|
|
|
|
bool isObjectContext)
|
2009-03-03 10:06:49 +00:00
|
|
|
{
|
2012-08-09 17:20:25 +01:00
|
|
|
context_t context = NULL;
|
2012-08-09 17:07:51 +01:00
|
|
|
char *ret = NULL;
|
|
|
|
char *str;
|
2012-08-09 17:20:25 +01:00
|
|
|
security_context_t ourSecContext = NULL;
|
|
|
|
context_t ourContext = NULL;
|
|
|
|
|
2012-08-10 14:27:51 +01:00
|
|
|
VIR_DEBUG("basecontext=%s mcs=%s isObjectContext=%d",
|
|
|
|
basecontext, mcs, isObjectContext);
|
|
|
|
|
2012-10-05 16:41:22 +02:00
|
|
|
if (getcon_raw(&ourSecContext) < 0) {
|
2012-08-09 17:20:25 +01:00
|
|
|
virReportSystemError(errno, "%s",
|
|
|
|
_("Unable to get current process SELinux context"));
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
if (!(ourContext = context_new(ourSecContext))) {
|
|
|
|
virReportSystemError(errno,
|
|
|
|
_("Unable to parse current SELinux context '%s'"),
|
|
|
|
ourSecContext);
|
|
|
|
goto cleanup;
|
|
|
|
}
|
2012-08-10 14:27:51 +01:00
|
|
|
VIR_DEBUG("process=%s", ourSecContext);
|
2012-08-09 17:07:51 +01:00
|
|
|
|
|
|
|
if (!(context = context_new(basecontext))) {
|
|
|
|
virReportSystemError(errno,
|
|
|
|
_("Unable to parse base SELinux context '%s'"),
|
|
|
|
basecontext);
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
2012-08-09 17:20:25 +01:00
|
|
|
if (context_user_set(context,
|
|
|
|
context_user_get(ourContext)) != 0) {
|
|
|
|
virReportSystemError(errno,
|
|
|
|
_("Unable to set SELinux context user '%s'"),
|
|
|
|
context_user_get(ourContext));
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
2012-08-20 16:12:14 +02:00
|
|
|
if (!isObjectContext &&
|
|
|
|
context_role_set(context,
|
2012-08-09 17:20:25 +01:00
|
|
|
context_role_get(ourContext)) != 0) {
|
|
|
|
virReportSystemError(errno,
|
2012-08-20 16:12:14 +02:00
|
|
|
_("Unable to set SELinux context role '%s'"),
|
2012-08-09 17:20:25 +01:00
|
|
|
context_role_get(ourContext));
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
2012-08-09 17:07:51 +01:00
|
|
|
if (context_range_set(context, mcs) != 0) {
|
|
|
|
virReportSystemError(errno,
|
|
|
|
_("Unable to set SELinux context MCS '%s'"),
|
|
|
|
mcs);
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
if (!(str = context_str(context))) {
|
|
|
|
virReportSystemError(errno, "%s",
|
|
|
|
_("Unable to format SELinux context"));
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
if (!(ret = strdup(str))) {
|
|
|
|
virReportOOMError();
|
|
|
|
goto cleanup;
|
|
|
|
}
|
2012-08-10 14:27:51 +01:00
|
|
|
VIR_DEBUG("Generated context '%s'", ret);
|
2012-08-09 17:07:51 +01:00
|
|
|
cleanup:
|
2012-08-09 17:20:25 +01:00
|
|
|
freecon(ourSecContext);
|
|
|
|
context_free(ourContext);
|
2012-08-09 17:07:51 +01:00
|
|
|
context_free(context);
|
|
|
|
return ret;
|
2009-03-03 10:06:49 +00:00
|
|
|
}
|
|
|
|
|
2012-05-11 10:54:31 +01:00
|
|
|
|
2012-05-16 14:18:25 +01:00
|
|
|
#ifdef HAVE_SELINUX_LXC_CONTEXTS_PATH
|
2009-03-03 10:06:49 +00:00
|
|
|
static int
|
2012-05-24 16:42:51 +01:00
|
|
|
virSecuritySELinuxLXCInitialize(virSecurityManagerPtr mgr)
|
2012-05-11 10:54:31 +01:00
|
|
|
{
|
|
|
|
virConfValuePtr scon = NULL;
|
|
|
|
virConfValuePtr tcon = NULL;
|
|
|
|
virConfValuePtr dcon = NULL;
|
|
|
|
virConfPtr selinux_conf;
|
|
|
|
virSecuritySELinuxDataPtr data = virSecurityManagerGetPrivateData(mgr);
|
|
|
|
|
2012-11-28 13:54:39 +00:00
|
|
|
data->skipAllLabel = true;
|
|
|
|
|
2012-05-11 10:54:31 +01:00
|
|
|
selinux_conf = virConfReadFile(selinux_lxc_contexts_path(), 0);
|
|
|
|
if (!selinux_conf) {
|
|
|
|
virReportSystemError(errno,
|
|
|
|
_("cannot open SELinux lxc contexts file '%s'"),
|
|
|
|
selinux_lxc_contexts_path());
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
scon = virConfGetValue(selinux_conf, "process");
|
|
|
|
if (! scon || scon->type != VIR_CONF_STRING || (! scon->str)) {
|
|
|
|
virReportSystemError(errno,
|
|
|
|
_("cannot read 'process' value from selinux lxc contexts file '%s'"),
|
|
|
|
selinux_lxc_contexts_path());
|
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
|
|
|
|
tcon = virConfGetValue(selinux_conf, "file");
|
|
|
|
if (! tcon || tcon->type != VIR_CONF_STRING || (! tcon->str)) {
|
|
|
|
virReportSystemError(errno,
|
|
|
|
_("cannot read 'file' value from selinux lxc contexts file '%s'"),
|
|
|
|
selinux_lxc_contexts_path());
|
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
|
|
|
|
dcon = virConfGetValue(selinux_conf, "content");
|
|
|
|
if (! dcon || dcon->type != VIR_CONF_STRING || (! dcon->str)) {
|
|
|
|
virReportSystemError(errno,
|
|
|
|
_("cannot read 'file' value from selinux lxc contexts file '%s'"),
|
|
|
|
selinux_lxc_contexts_path());
|
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
|
|
|
|
data->domain_context = strdup(scon->str);
|
|
|
|
data->file_context = strdup(tcon->str);
|
|
|
|
data->content_context = strdup(dcon->str);
|
|
|
|
if (!data->domain_context ||
|
|
|
|
!data->file_context ||
|
|
|
|
!data->content_context) {
|
|
|
|
virReportSystemError(errno,
|
|
|
|
_("cannot allocate memory for LXC SELinux contexts '%s'"),
|
|
|
|
selinux_lxc_contexts_path());
|
|
|
|
goto error;
|
|
|
|
}
|
2012-05-24 17:22:29 +01:00
|
|
|
|
|
|
|
if (!(data->mcs = virHashCreate(10, NULL)))
|
|
|
|
goto error;
|
|
|
|
|
2012-05-11 10:54:31 +01:00
|
|
|
virConfFree(selinux_conf);
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
error:
|
|
|
|
virConfFree(selinux_conf);
|
|
|
|
VIR_FREE(data->domain_context);
|
|
|
|
VIR_FREE(data->file_context);
|
|
|
|
VIR_FREE(data->content_context);
|
2012-05-24 17:22:29 +01:00
|
|
|
virHashFree(data->mcs);
|
2012-05-11 10:54:31 +01:00
|
|
|
return -1;
|
|
|
|
}
|
2012-05-16 14:18:25 +01:00
|
|
|
#else
|
|
|
|
static int
|
2012-05-24 16:42:51 +01:00
|
|
|
virSecuritySELinuxLXCInitialize(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED)
|
2012-05-16 14:18:25 +01:00
|
|
|
{
|
|
|
|
virReportSystemError(ENOSYS, "%s",
|
|
|
|
_("libselinux does not support LXC contexts path"));
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
#endif
|
2012-05-11 10:54:31 +01:00
|
|
|
|
|
|
|
|
|
|
|
static int
|
2012-05-24 16:42:51 +01:00
|
|
|
virSecuritySELinuxQEMUInitialize(virSecurityManagerPtr mgr)
|
2009-03-03 10:06:49 +00:00
|
|
|
{
|
2012-05-11 10:43:30 +01:00
|
|
|
char *ptr;
|
|
|
|
virSecuritySELinuxDataPtr data = virSecurityManagerGetPrivateData(mgr);
|
2009-03-03 10:06:49 +00:00
|
|
|
|
2012-11-28 13:54:39 +00:00
|
|
|
data->skipAllLabel = false;
|
|
|
|
|
2012-05-11 10:43:30 +01:00
|
|
|
if (virFileReadAll(selinux_virtual_domain_context_path(), MAX_CONTEXT, &(data->domain_context)) < 0) {
|
2010-02-04 21:02:58 +01:00
|
|
|
virReportSystemError(errno,
|
2012-05-11 10:43:30 +01:00
|
|
|
_("cannot read SELinux virtual domain context file '%s'"),
|
2009-08-28 18:44:43 +01:00
|
|
|
selinux_virtual_domain_context_path());
|
2012-05-11 10:43:30 +01:00
|
|
|
goto error;
|
2009-03-03 10:06:49 +00:00
|
|
|
}
|
|
|
|
|
2012-05-11 10:43:30 +01:00
|
|
|
ptr = strchrnul(data->domain_context, '\n');
|
2012-12-12 11:47:19 +00:00
|
|
|
if (ptr && *ptr == '\n') {
|
2012-05-11 10:43:30 +01:00
|
|
|
*ptr = '\0';
|
2012-12-12 11:47:19 +00:00
|
|
|
ptr++;
|
|
|
|
if (*ptr != '\0') {
|
|
|
|
data->alt_domain_context = strdup(ptr);
|
|
|
|
if (!data->alt_domain_context) {
|
|
|
|
virReportOOMError();
|
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
ptr = strchrnul(data->alt_domain_context, '\n');
|
|
|
|
if (ptr && *ptr == '\n')
|
|
|
|
*ptr = '\0';
|
|
|
|
}
|
|
|
|
}
|
|
|
|
VIR_DEBUG("Loaded domain context '%s', alt domain context '%s'",
|
|
|
|
data->domain_context, NULLSTR(data->alt_domain_context));
|
|
|
|
|
2009-03-03 10:06:49 +00:00
|
|
|
|
2012-05-11 10:43:30 +01:00
|
|
|
if (virFileReadAll(selinux_virtual_image_context_path(), 2*MAX_CONTEXT, &(data->file_context)) < 0) {
|
2010-02-04 21:02:58 +01:00
|
|
|
virReportSystemError(errno,
|
2009-08-28 18:44:43 +01:00
|
|
|
_("cannot read SELinux virtual image context file %s"),
|
|
|
|
selinux_virtual_image_context_path());
|
2012-05-11 10:43:30 +01:00
|
|
|
goto error;
|
2009-03-03 10:06:49 +00:00
|
|
|
}
|
|
|
|
|
2012-05-11 10:43:30 +01:00
|
|
|
ptr = strchrnul(data->file_context, '\n');
|
|
|
|
if (ptr && *ptr == '\n') {
|
2009-07-03 10:26:37 +00:00
|
|
|
*ptr = '\0';
|
2012-05-11 10:43:30 +01:00
|
|
|
data->content_context = strdup(ptr+1);
|
|
|
|
if (!data->content_context) {
|
|
|
|
virReportOOMError();
|
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
ptr = strchrnul(data->content_context, '\n');
|
|
|
|
if (ptr && *ptr == '\n')
|
2009-07-03 10:26:37 +00:00
|
|
|
*ptr = '\0';
|
|
|
|
}
|
2012-05-11 10:43:30 +01:00
|
|
|
|
2012-12-12 11:47:19 +00:00
|
|
|
VIR_DEBUG("Loaded file context '%s', content context '%s'",
|
|
|
|
data->file_context, data->content_context);
|
|
|
|
|
2012-05-24 17:22:29 +01:00
|
|
|
if (!(data->mcs = virHashCreate(10, NULL)))
|
|
|
|
goto error;
|
|
|
|
|
2009-03-03 10:06:49 +00:00
|
|
|
return 0;
|
2012-05-11 10:43:30 +01:00
|
|
|
|
|
|
|
error:
|
|
|
|
VIR_FREE(data->domain_context);
|
2012-12-12 11:47:19 +00:00
|
|
|
VIR_FREE(data->alt_domain_context);
|
2012-05-11 10:43:30 +01:00
|
|
|
VIR_FREE(data->file_context);
|
|
|
|
VIR_FREE(data->content_context);
|
2012-05-24 17:22:29 +01:00
|
|
|
virHashFree(data->mcs);
|
2012-05-11 10:43:30 +01:00
|
|
|
return -1;
|
2009-03-03 10:06:49 +00:00
|
|
|
}
|
|
|
|
|
2012-05-11 10:54:31 +01:00
|
|
|
|
|
|
|
static int
|
2012-05-24 16:42:51 +01:00
|
|
|
virSecuritySELinuxInitialize(virSecurityManagerPtr mgr)
|
2012-05-11 10:54:31 +01:00
|
|
|
{
|
|
|
|
VIR_DEBUG("SELinuxInitialize %s", virSecurityManagerGetDriver(mgr));
|
|
|
|
if (STREQ(virSecurityManagerGetDriver(mgr), "LXC")) {
|
2012-05-24 16:42:51 +01:00
|
|
|
return virSecuritySELinuxLXCInitialize(mgr);
|
2012-05-11 10:54:31 +01:00
|
|
|
} else {
|
2012-05-24 16:42:51 +01:00
|
|
|
return virSecuritySELinuxQEMUInitialize(mgr);
|
2012-05-11 10:54:31 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2009-03-03 10:06:49 +00:00
|
|
|
static int
|
2012-05-24 16:42:51 +01:00
|
|
|
virSecuritySELinuxGenSecurityLabel(virSecurityManagerPtr mgr,
|
|
|
|
virDomainDefPtr def)
|
2009-03-03 10:06:49 +00:00
|
|
|
{
|
|
|
|
int rc = -1;
|
2011-06-24 10:21:33 +01:00
|
|
|
char *mcs = NULL;
|
2009-03-03 10:06:49 +00:00
|
|
|
char *scontext = NULL;
|
2011-06-24 10:21:33 +01:00
|
|
|
context_t ctx = NULL;
|
Add two new security label types
Curently security labels can be of type 'dynamic' or 'static'.
If no security label is given, then 'dynamic' is assumed. The
current code takes advantage of this default, and avoids even
saving <seclabel> elements with type='dynamic' to disk. This
means if you temporarily change security driver, the guests
can all still start.
With the introduction of sVirt to LXC though, there needs to be
a new default of 'none' to allow unconfined LXC containers.
This patch introduces two new security label types
- default: the host configuration decides whether to run the
guest with type 'none' or 'dynamic' at guest start
- none: the guest will run unconfined by security policy
The 'none' label type will obviously be undesirable for some
deployments, so a new qemu.conf option allows a host admin to
mandate confined guests. It is also possible to turn off default
confinement
security_default_confined = 1|0 (default == 1)
security_require_confined = 1|0 (default == 0)
* src/conf/domain_conf.c, src/conf/domain_conf.h: Add new
seclabel types
* src/security/security_manager.c, src/security/security_manager.h:
Set default sec label types
* src/security/security_selinux.c: Handle 'none' seclabel type
* src/qemu/qemu.conf, src/qemu/qemu_conf.c, src/qemu/qemu_conf.h,
src/qemu/libvirtd_qemu.aug: New security config options
* src/qemu/qemu_driver.c: Tell security driver about default
config
2012-01-25 14:12:52 +00:00
|
|
|
const char *range;
|
2012-08-15 19:10:37 -03:00
|
|
|
virSecurityLabelDefPtr seclabel;
|
|
|
|
virSecuritySELinuxDataPtr data;
|
2012-12-12 11:47:19 +00:00
|
|
|
const char *baselabel;
|
2010-01-13 14:03:04 +00:00
|
|
|
|
2012-08-15 19:10:37 -03:00
|
|
|
if (mgr == NULL) {
|
2012-07-18 15:39:18 +01:00
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
2012-08-15 19:10:37 -03:00
|
|
|
"%s", _("invalid security driver"));
|
2011-06-23 15:48:48 +01:00
|
|
|
return rc;
|
|
|
|
}
|
|
|
|
|
2012-08-15 19:10:37 -03:00
|
|
|
seclabel = virDomainDefGetSecurityLabelDef(def, SECURITY_SELINUX_NAME);
|
|
|
|
if (seclabel == NULL) {
|
|
|
|
return rc;
|
|
|
|
}
|
|
|
|
|
|
|
|
data = virSecurityManagerGetPrivateData(mgr);
|
|
|
|
|
|
|
|
VIR_DEBUG("label=%s", virSecurityManagerGetDriver(mgr));
|
|
|
|
if (seclabel->type == VIR_DOMAIN_SECLABEL_DYNAMIC &&
|
|
|
|
seclabel->label) {
|
2012-07-18 15:39:18 +01:00
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
|
"%s", _("security label already defined for VM"));
|
2010-10-27 11:01:27 +01:00
|
|
|
return rc;
|
2009-03-03 15:18:24 +00:00
|
|
|
}
|
2009-03-03 10:06:49 +00:00
|
|
|
|
2012-08-15 19:10:37 -03:00
|
|
|
if (seclabel->imagelabel) {
|
2012-07-18 15:39:18 +01:00
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
|
"%s", _("security image label already defined for VM"));
|
2011-06-24 10:21:33 +01:00
|
|
|
return rc;
|
|
|
|
}
|
|
|
|
|
2012-08-15 19:10:37 -03:00
|
|
|
if (seclabel->model &&
|
|
|
|
STRNEQ(seclabel->model, SECURITY_SELINUX_NAME)) {
|
2012-07-18 15:39:18 +01:00
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
|
_("security label model %s is not supported with selinux"),
|
2012-08-15 19:10:37 -03:00
|
|
|
seclabel->model);
|
2011-06-23 15:48:48 +01:00
|
|
|
return rc;
|
|
|
|
}
|
|
|
|
|
2012-08-15 19:10:37 -03:00
|
|
|
VIR_DEBUG("type=%d", seclabel->type);
|
2012-05-11 10:43:30 +01:00
|
|
|
|
2012-08-15 19:10:37 -03:00
|
|
|
switch (seclabel->type) {
|
Add two new security label types
Curently security labels can be of type 'dynamic' or 'static'.
If no security label is given, then 'dynamic' is assumed. The
current code takes advantage of this default, and avoids even
saving <seclabel> elements with type='dynamic' to disk. This
means if you temporarily change security driver, the guests
can all still start.
With the introduction of sVirt to LXC though, there needs to be
a new default of 'none' to allow unconfined LXC containers.
This patch introduces two new security label types
- default: the host configuration decides whether to run the
guest with type 'none' or 'dynamic' at guest start
- none: the guest will run unconfined by security policy
The 'none' label type will obviously be undesirable for some
deployments, so a new qemu.conf option allows a host admin to
mandate confined guests. It is also possible to turn off default
confinement
security_default_confined = 1|0 (default == 1)
security_require_confined = 1|0 (default == 0)
* src/conf/domain_conf.c, src/conf/domain_conf.h: Add new
seclabel types
* src/security/security_manager.c, src/security/security_manager.h:
Set default sec label types
* src/security/security_selinux.c: Handle 'none' seclabel type
* src/qemu/qemu.conf, src/qemu/qemu_conf.c, src/qemu/qemu_conf.h,
src/qemu/libvirtd_qemu.aug: New security config options
* src/qemu/qemu_driver.c: Tell security driver about default
config
2012-01-25 14:12:52 +00:00
|
|
|
case VIR_DOMAIN_SECLABEL_STATIC:
|
2012-10-17 10:23:12 +01:00
|
|
|
if (!(ctx = context_new(seclabel->label))) {
|
2011-06-24 10:21:33 +01:00
|
|
|
virReportSystemError(errno,
|
|
|
|
_("unable to allocate socket security context '%s'"),
|
2012-08-15 19:10:37 -03:00
|
|
|
seclabel->label);
|
2011-06-24 10:21:33 +01:00
|
|
|
return rc;
|
2009-03-03 10:06:49 +00:00
|
|
|
}
|
|
|
|
|
Add two new security label types
Curently security labels can be of type 'dynamic' or 'static'.
If no security label is given, then 'dynamic' is assumed. The
current code takes advantage of this default, and avoids even
saving <seclabel> elements with type='dynamic' to disk. This
means if you temporarily change security driver, the guests
can all still start.
With the introduction of sVirt to LXC though, there needs to be
a new default of 'none' to allow unconfined LXC containers.
This patch introduces two new security label types
- default: the host configuration decides whether to run the
guest with type 'none' or 'dynamic' at guest start
- none: the guest will run unconfined by security policy
The 'none' label type will obviously be undesirable for some
deployments, so a new qemu.conf option allows a host admin to
mandate confined guests. It is also possible to turn off default
confinement
security_default_confined = 1|0 (default == 1)
security_require_confined = 1|0 (default == 0)
* src/conf/domain_conf.c, src/conf/domain_conf.h: Add new
seclabel types
* src/security/security_manager.c, src/security/security_manager.h:
Set default sec label types
* src/security/security_selinux.c: Handle 'none' seclabel type
* src/qemu/qemu.conf, src/qemu/qemu_conf.c, src/qemu/qemu_conf.h,
src/qemu/libvirtd_qemu.aug: New security config options
* src/qemu/qemu_driver.c: Tell security driver about default
config
2012-01-25 14:12:52 +00:00
|
|
|
range = context_range_get(ctx);
|
2011-06-24 10:21:33 +01:00
|
|
|
if (!range ||
|
|
|
|
!(mcs = strdup(range))) {
|
|
|
|
virReportOOMError();
|
|
|
|
goto cleanup;
|
|
|
|
}
|
Add two new security label types
Curently security labels can be of type 'dynamic' or 'static'.
If no security label is given, then 'dynamic' is assumed. The
current code takes advantage of this default, and avoids even
saving <seclabel> elements with type='dynamic' to disk. This
means if you temporarily change security driver, the guests
can all still start.
With the introduction of sVirt to LXC though, there needs to be
a new default of 'none' to allow unconfined LXC containers.
This patch introduces two new security label types
- default: the host configuration decides whether to run the
guest with type 'none' or 'dynamic' at guest start
- none: the guest will run unconfined by security policy
The 'none' label type will obviously be undesirable for some
deployments, so a new qemu.conf option allows a host admin to
mandate confined guests. It is also possible to turn off default
confinement
security_default_confined = 1|0 (default == 1)
security_require_confined = 1|0 (default == 0)
* src/conf/domain_conf.c, src/conf/domain_conf.h: Add new
seclabel types
* src/security/security_manager.c, src/security/security_manager.h:
Set default sec label types
* src/security/security_selinux.c: Handle 'none' seclabel type
* src/qemu/qemu.conf, src/qemu/qemu_conf.c, src/qemu/qemu_conf.h,
src/qemu/libvirtd_qemu.aug: New security config options
* src/qemu/qemu_driver.c: Tell security driver about default
config
2012-01-25 14:12:52 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
case VIR_DOMAIN_SECLABEL_DYNAMIC:
|
2012-08-09 17:43:12 +01:00
|
|
|
if (!(mcs = virSecuritySELinuxMCSFind(mgr)))
|
|
|
|
goto cleanup;
|
|
|
|
|
|
|
|
if (virSecuritySELinuxMCSAdd(mgr, mcs) < 0)
|
|
|
|
goto cleanup;
|
2011-06-24 10:21:33 +01:00
|
|
|
|
2012-12-12 11:47:19 +00:00
|
|
|
baselabel = seclabel->baselabel;
|
|
|
|
if (!baselabel) {
|
|
|
|
if (def->virtType == VIR_DOMAIN_VIRT_QEMU) {
|
|
|
|
if (data->alt_domain_context == NULL) {
|
|
|
|
static bool warned = false;
|
|
|
|
if (!warned) {
|
|
|
|
VIR_WARN("SELinux policy does not define a domain type for QEMU TCG. "
|
|
|
|
"Guest startup may be denied due to missing 'execmem' privilege "
|
|
|
|
"unless the 'virt_use_execmem' policy boolean is enabled");
|
|
|
|
warned = true;
|
|
|
|
}
|
|
|
|
baselabel = data->domain_context;
|
|
|
|
} else {
|
|
|
|
baselabel = data->alt_domain_context;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
baselabel = data->domain_context;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-08-15 19:10:37 -03:00
|
|
|
seclabel->label =
|
2012-12-12 11:47:19 +00:00
|
|
|
virSecuritySELinuxGenNewContext(baselabel, mcs, false);
|
2012-08-15 19:10:37 -03:00
|
|
|
if (!seclabel->label) {
|
2012-08-15 19:10:35 -03:00
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
|
_("cannot generate selinux context for %s"), mcs);
|
2011-06-24 10:21:33 +01:00
|
|
|
goto cleanup;
|
2012-08-15 19:10:35 -03:00
|
|
|
}
|
Add two new security label types
Curently security labels can be of type 'dynamic' or 'static'.
If no security label is given, then 'dynamic' is assumed. The
current code takes advantage of this default, and avoids even
saving <seclabel> elements with type='dynamic' to disk. This
means if you temporarily change security driver, the guests
can all still start.
With the introduction of sVirt to LXC though, there needs to be
a new default of 'none' to allow unconfined LXC containers.
This patch introduces two new security label types
- default: the host configuration decides whether to run the
guest with type 'none' or 'dynamic' at guest start
- none: the guest will run unconfined by security policy
The 'none' label type will obviously be undesirable for some
deployments, so a new qemu.conf option allows a host admin to
mandate confined guests. It is also possible to turn off default
confinement
security_default_confined = 1|0 (default == 1)
security_require_confined = 1|0 (default == 0)
* src/conf/domain_conf.c, src/conf/domain_conf.h: Add new
seclabel types
* src/security/security_manager.c, src/security/security_manager.h:
Set default sec label types
* src/security/security_selinux.c: Handle 'none' seclabel type
* src/qemu/qemu.conf, src/qemu/qemu_conf.c, src/qemu/qemu_conf.h,
src/qemu/libvirtd_qemu.aug: New security config options
* src/qemu/qemu_driver.c: Tell security driver about default
config
2012-01-25 14:12:52 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
case VIR_DOMAIN_SECLABEL_NONE:
|
|
|
|
/* no op */
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
2012-07-18 15:39:18 +01:00
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
|
_("unexpected security label type '%s'"),
|
2012-08-15 19:10:37 -03:00
|
|
|
virDomainSeclabelTypeToString(seclabel->type));
|
2011-06-24 10:21:33 +01:00
|
|
|
goto cleanup;
|
2009-03-03 15:18:24 +00:00
|
|
|
}
|
2011-06-24 10:21:33 +01:00
|
|
|
|
2012-08-15 19:10:37 -03:00
|
|
|
if (!seclabel->norelabel) {
|
2012-08-21 11:36:14 +01:00
|
|
|
seclabel->imagelabel = virSecuritySELinuxGenNewContext(data->file_context,
|
2012-08-15 19:10:37 -03:00
|
|
|
mcs,
|
|
|
|
true);
|
|
|
|
if (!seclabel->imagelabel) {
|
2012-08-15 19:10:35 -03:00
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
|
_("cannot generate selinux context for %s"), mcs);
|
Add two new security label types
Curently security labels can be of type 'dynamic' or 'static'.
If no security label is given, then 'dynamic' is assumed. The
current code takes advantage of this default, and avoids even
saving <seclabel> elements with type='dynamic' to disk. This
means if you temporarily change security driver, the guests
can all still start.
With the introduction of sVirt to LXC though, there needs to be
a new default of 'none' to allow unconfined LXC containers.
This patch introduces two new security label types
- default: the host configuration decides whether to run the
guest with type 'none' or 'dynamic' at guest start
- none: the guest will run unconfined by security policy
The 'none' label type will obviously be undesirable for some
deployments, so a new qemu.conf option allows a host admin to
mandate confined guests. It is also possible to turn off default
confinement
security_default_confined = 1|0 (default == 1)
security_require_confined = 1|0 (default == 0)
* src/conf/domain_conf.c, src/conf/domain_conf.h: Add new
seclabel types
* src/security/security_manager.c, src/security/security_manager.h:
Set default sec label types
* src/security/security_selinux.c: Handle 'none' seclabel type
* src/qemu/qemu.conf, src/qemu/qemu_conf.c, src/qemu/qemu_conf.h,
src/qemu/libvirtd_qemu.aug: New security config options
* src/qemu/qemu_driver.c: Tell security driver about default
config
2012-01-25 14:12:52 +00:00
|
|
|
goto cleanup;
|
2012-08-15 19:10:35 -03:00
|
|
|
}
|
Add two new security label types
Curently security labels can be of type 'dynamic' or 'static'.
If no security label is given, then 'dynamic' is assumed. The
current code takes advantage of this default, and avoids even
saving <seclabel> elements with type='dynamic' to disk. This
means if you temporarily change security driver, the guests
can all still start.
With the introduction of sVirt to LXC though, there needs to be
a new default of 'none' to allow unconfined LXC containers.
This patch introduces two new security label types
- default: the host configuration decides whether to run the
guest with type 'none' or 'dynamic' at guest start
- none: the guest will run unconfined by security policy
The 'none' label type will obviously be undesirable for some
deployments, so a new qemu.conf option allows a host admin to
mandate confined guests. It is also possible to turn off default
confinement
security_default_confined = 1|0 (default == 1)
security_require_confined = 1|0 (default == 0)
* src/conf/domain_conf.c, src/conf/domain_conf.h: Add new
seclabel types
* src/security/security_manager.c, src/security/security_manager.h:
Set default sec label types
* src/security/security_selinux.c: Handle 'none' seclabel type
* src/qemu/qemu.conf, src/qemu/qemu_conf.c, src/qemu/qemu_conf.h,
src/qemu/libvirtd_qemu.aug: New security config options
* src/qemu/qemu_driver.c: Tell security driver about default
config
2012-01-25 14:12:52 +00:00
|
|
|
}
|
|
|
|
|
2012-08-15 19:10:37 -03:00
|
|
|
if (!seclabel->model &&
|
|
|
|
!(seclabel->model = strdup(SECURITY_SELINUX_NAME))) {
|
2010-02-04 19:19:08 +01:00
|
|
|
virReportOOMError();
|
2011-06-24 10:21:33 +01:00
|
|
|
goto cleanup;
|
2009-03-03 15:18:24 +00:00
|
|
|
}
|
|
|
|
|
2009-03-03 10:06:49 +00:00
|
|
|
rc = 0;
|
2011-06-24 10:21:33 +01:00
|
|
|
|
|
|
|
cleanup:
|
|
|
|
if (rc != 0) {
|
2012-08-15 19:10:37 -03:00
|
|
|
if (seclabel->type == VIR_DOMAIN_SECLABEL_DYNAMIC)
|
|
|
|
VIR_FREE(seclabel->label);
|
|
|
|
VIR_FREE(seclabel->imagelabel);
|
|
|
|
if (seclabel->type == VIR_DOMAIN_SECLABEL_DYNAMIC &&
|
|
|
|
!seclabel->baselabel)
|
|
|
|
VIR_FREE(seclabel->model);
|
2011-06-24 10:21:33 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
if (ctx)
|
|
|
|
context_free(ctx);
|
2009-03-03 15:18:24 +00:00
|
|
|
VIR_FREE(scontext);
|
2011-06-24 10:21:33 +01:00
|
|
|
VIR_FREE(mcs);
|
|
|
|
|
|
|
|
VIR_DEBUG("model=%s label=%s imagelabel=%s baselabel=%s",
|
2012-08-15 19:10:37 -03:00
|
|
|
NULLSTR(seclabel->model),
|
|
|
|
NULLSTR(seclabel->label),
|
|
|
|
NULLSTR(seclabel->imagelabel),
|
|
|
|
NULLSTR(seclabel->baselabel));
|
2011-06-24 10:21:33 +01:00
|
|
|
|
2009-03-03 10:06:49 +00:00
|
|
|
return rc;
|
|
|
|
}
|
|
|
|
|
2009-06-12 11:38:50 +00:00
|
|
|
static int
|
2012-08-15 19:10:35 -03:00
|
|
|
virSecuritySELinuxReserveSecurityLabel(virSecurityManagerPtr mgr,
|
2012-05-24 16:42:51 +01:00
|
|
|
virDomainDefPtr def,
|
|
|
|
pid_t pid)
|
2009-06-12 11:38:50 +00:00
|
|
|
{
|
|
|
|
security_context_t pctx;
|
|
|
|
context_t ctx = NULL;
|
|
|
|
const char *mcs;
|
2012-05-24 16:52:18 +01:00
|
|
|
int rv;
|
2012-08-15 19:10:37 -03:00
|
|
|
virSecurityLabelDefPtr seclabel;
|
2009-06-12 11:38:50 +00:00
|
|
|
|
2012-08-15 19:10:37 -03:00
|
|
|
seclabel = virDomainDefGetSecurityLabelDef(def, SECURITY_SELINUX_NAME);
|
|
|
|
if (seclabel == NULL) {
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (seclabel->type == VIR_DOMAIN_SECLABEL_STATIC)
|
2010-01-13 14:03:04 +00:00
|
|
|
return 0;
|
|
|
|
|
2012-10-05 16:41:22 +02:00
|
|
|
if (getpidcon_raw(pid, &pctx) == -1) {
|
2010-02-04 21:02:58 +01:00
|
|
|
virReportSystemError(errno,
|
Change security driver APIs to use virDomainDefPtr instead of virDomainObjPtr
When sVirt is integrated with the LXC driver, it will be neccessary
to invoke the security driver APIs using only a virDomainDefPtr
since the lxc_container.c code has no virDomainObjPtr available.
Aside from two functions which want obj->pid, every bit of the
security driver code only touches obj->def. So we don't need to
pass a virDomainObjPtr into the security drivers, a virDomainDefPtr
is sufficient. Two functions also gain a 'pid_t pid' argument.
* src/qemu/qemu_driver.c, src/qemu/qemu_hotplug.c,
src/qemu/qemu_migration.c, src/qemu/qemu_process.c,
src/security/security_apparmor.c,
src/security/security_dac.c,
src/security/security_driver.h,
src/security/security_manager.c,
src/security/security_manager.h,
src/security/security_nop.c,
src/security/security_selinux.c,
src/security/security_stack.c: Change all security APIs to use a
virDomainDefPtr instead of virDomainObjPtr
2011-07-14 14:32:06 +01:00
|
|
|
_("unable to get PID %d security context"), pid);
|
2009-06-12 11:38:50 +00:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
ctx = context_new(pctx);
|
2010-11-24 14:09:58 -07:00
|
|
|
freecon(pctx);
|
2009-06-12 11:38:50 +00:00
|
|
|
if (!ctx)
|
2012-05-24 16:52:18 +01:00
|
|
|
goto error;
|
2009-06-12 11:38:50 +00:00
|
|
|
|
|
|
|
mcs = context_range_get(ctx);
|
|
|
|
if (!mcs)
|
2012-05-24 16:52:18 +01:00
|
|
|
goto error;
|
|
|
|
|
2012-05-24 17:22:29 +01:00
|
|
|
if ((rv = virSecuritySELinuxMCSAdd(mgr, mcs)) < 0)
|
2012-05-24 16:52:18 +01:00
|
|
|
goto error;
|
2009-06-12 11:38:50 +00:00
|
|
|
|
2012-05-24 16:52:18 +01:00
|
|
|
if (rv == 1) {
|
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
|
_("MCS level for existing domain label %s already reserved"),
|
|
|
|
(char*)pctx);
|
|
|
|
goto error;
|
|
|
|
}
|
2009-06-12 11:38:50 +00:00
|
|
|
|
|
|
|
context_free(ctx);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
2012-05-24 16:52:18 +01:00
|
|
|
error:
|
2009-06-12 11:38:50 +00:00
|
|
|
context_free(ctx);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2009-03-03 10:06:49 +00:00
|
|
|
static int
|
2012-05-24 16:42:51 +01:00
|
|
|
virSecuritySELinuxSecurityDriverProbe(const char *virtDriver)
|
2009-03-03 10:06:49 +00:00
|
|
|
{
|
2012-05-11 10:43:30 +01:00
|
|
|
if (!is_selinux_enabled())
|
|
|
|
return SECURITY_DRIVER_DISABLE;
|
|
|
|
|
2012-05-16 14:18:25 +01:00
|
|
|
if (virtDriver && STREQ(virtDriver, "LXC")) {
|
|
|
|
#if HAVE_SELINUX_LXC_CONTEXTS_PATH
|
|
|
|
if (!virFileExists(selinux_lxc_contexts_path()))
|
|
|
|
#endif
|
|
|
|
return SECURITY_DRIVER_DISABLE;
|
|
|
|
}
|
2012-05-11 10:43:30 +01:00
|
|
|
|
|
|
|
return SECURITY_DRIVER_ENABLE;
|
2009-03-03 10:06:49 +00:00
|
|
|
}
|
|
|
|
|
2012-05-11 10:43:30 +01:00
|
|
|
|
2009-03-03 10:06:49 +00:00
|
|
|
static int
|
2012-05-24 16:42:51 +01:00
|
|
|
virSecuritySELinuxSecurityDriverOpen(virSecurityManagerPtr mgr)
|
Refactor the security drivers to simplify usage
The current security driver usage requires horrible code like
if (driver->securityDriver &&
driver->securityDriver->domainSetSecurityHostdevLabel &&
driver->securityDriver->domainSetSecurityHostdevLabel(driver->securityDriver,
vm, hostdev) < 0)
This pair of checks for NULL clutters up the code, making the driver
calls 2 lines longer than they really need to be. The goal of the
patchset is to change the calling convention to simply
if (virSecurityManagerSetHostdevLabel(driver->securityDriver,
vm, hostdev) < 0)
The first check for 'driver->securityDriver' being NULL is removed
by introducing a 'no op' security driver that will always be present
if no real driver is enabled. This guarentees driver->securityDriver
!= NULL.
The second check for 'driver->securityDriver->domainSetSecurityHostdevLabel'
being non-NULL is hidden in a new abstraction called virSecurityManager.
This separates the driver callbacks, from main internal API. The addition
of a virSecurityManager object, that is separate from the virSecurityDriver
struct also allows for security drivers to carry state / configuration
information directly. Thus the DAC/Stack drivers from src/qemu which
used to pull config from 'struct qemud_driver' can now be moved into
the 'src/security' directory and store their config directly.
* src/qemu/qemu_conf.h, src/qemu/qemu_driver.c: Update to
use new virSecurityManager APIs
* src/qemu/qemu_security_dac.c, src/qemu/qemu_security_dac.h
src/qemu/qemu_security_stacked.c, src/qemu/qemu_security_stacked.h:
Move into src/security directory
* src/security/security_stack.c, src/security/security_stack.h,
src/security/security_dac.c, src/security/security_dac.h: Generic
versions of previous QEMU specific drivers
* src/security/security_apparmor.c, src/security/security_apparmor.h,
src/security/security_driver.c, src/security/security_driver.h,
src/security/security_selinux.c, src/security/security_selinux.h:
Update to take virSecurityManagerPtr object as the first param
in all callbacks
* src/security/security_nop.c, src/security/security_nop.h: Stub
implementation of all security driver APIs.
* src/security/security_manager.h, src/security/security_manager.c:
New internal API for invoking security drivers
* src/libvirt.c: Add missing debug for security APIs
2010-11-17 20:26:30 +00:00
|
|
|
{
|
2012-05-24 16:42:51 +01:00
|
|
|
return virSecuritySELinuxInitialize(mgr);
|
Refactor the security drivers to simplify usage
The current security driver usage requires horrible code like
if (driver->securityDriver &&
driver->securityDriver->domainSetSecurityHostdevLabel &&
driver->securityDriver->domainSetSecurityHostdevLabel(driver->securityDriver,
vm, hostdev) < 0)
This pair of checks for NULL clutters up the code, making the driver
calls 2 lines longer than they really need to be. The goal of the
patchset is to change the calling convention to simply
if (virSecurityManagerSetHostdevLabel(driver->securityDriver,
vm, hostdev) < 0)
The first check for 'driver->securityDriver' being NULL is removed
by introducing a 'no op' security driver that will always be present
if no real driver is enabled. This guarentees driver->securityDriver
!= NULL.
The second check for 'driver->securityDriver->domainSetSecurityHostdevLabel'
being non-NULL is hidden in a new abstraction called virSecurityManager.
This separates the driver callbacks, from main internal API. The addition
of a virSecurityManager object, that is separate from the virSecurityDriver
struct also allows for security drivers to carry state / configuration
information directly. Thus the DAC/Stack drivers from src/qemu which
used to pull config from 'struct qemud_driver' can now be moved into
the 'src/security' directory and store their config directly.
* src/qemu/qemu_conf.h, src/qemu/qemu_driver.c: Update to
use new virSecurityManager APIs
* src/qemu/qemu_security_dac.c, src/qemu/qemu_security_dac.h
src/qemu/qemu_security_stacked.c, src/qemu/qemu_security_stacked.h:
Move into src/security directory
* src/security/security_stack.c, src/security/security_stack.h,
src/security/security_dac.c, src/security/security_dac.h: Generic
versions of previous QEMU specific drivers
* src/security/security_apparmor.c, src/security/security_apparmor.h,
src/security/security_driver.c, src/security/security_driver.h,
src/security/security_selinux.c, src/security/security_selinux.h:
Update to take virSecurityManagerPtr object as the first param
in all callbacks
* src/security/security_nop.c, src/security/security_nop.h: Stub
implementation of all security driver APIs.
* src/security/security_manager.h, src/security/security_manager.c:
New internal API for invoking security drivers
* src/libvirt.c: Add missing debug for security APIs
2010-11-17 20:26:30 +00:00
|
|
|
}
|
|
|
|
|
2012-05-11 10:43:30 +01:00
|
|
|
|
Refactor the security drivers to simplify usage
The current security driver usage requires horrible code like
if (driver->securityDriver &&
driver->securityDriver->domainSetSecurityHostdevLabel &&
driver->securityDriver->domainSetSecurityHostdevLabel(driver->securityDriver,
vm, hostdev) < 0)
This pair of checks for NULL clutters up the code, making the driver
calls 2 lines longer than they really need to be. The goal of the
patchset is to change the calling convention to simply
if (virSecurityManagerSetHostdevLabel(driver->securityDriver,
vm, hostdev) < 0)
The first check for 'driver->securityDriver' being NULL is removed
by introducing a 'no op' security driver that will always be present
if no real driver is enabled. This guarentees driver->securityDriver
!= NULL.
The second check for 'driver->securityDriver->domainSetSecurityHostdevLabel'
being non-NULL is hidden in a new abstraction called virSecurityManager.
This separates the driver callbacks, from main internal API. The addition
of a virSecurityManager object, that is separate from the virSecurityDriver
struct also allows for security drivers to carry state / configuration
information directly. Thus the DAC/Stack drivers from src/qemu which
used to pull config from 'struct qemud_driver' can now be moved into
the 'src/security' directory and store their config directly.
* src/qemu/qemu_conf.h, src/qemu/qemu_driver.c: Update to
use new virSecurityManager APIs
* src/qemu/qemu_security_dac.c, src/qemu/qemu_security_dac.h
src/qemu/qemu_security_stacked.c, src/qemu/qemu_security_stacked.h:
Move into src/security directory
* src/security/security_stack.c, src/security/security_stack.h,
src/security/security_dac.c, src/security/security_dac.h: Generic
versions of previous QEMU specific drivers
* src/security/security_apparmor.c, src/security/security_apparmor.h,
src/security/security_driver.c, src/security/security_driver.h,
src/security/security_selinux.c, src/security/security_selinux.h:
Update to take virSecurityManagerPtr object as the first param
in all callbacks
* src/security/security_nop.c, src/security/security_nop.h: Stub
implementation of all security driver APIs.
* src/security/security_manager.h, src/security/security_manager.c:
New internal API for invoking security drivers
* src/libvirt.c: Add missing debug for security APIs
2010-11-17 20:26:30 +00:00
|
|
|
static int
|
2012-05-24 16:42:51 +01:00
|
|
|
virSecuritySELinuxSecurityDriverClose(virSecurityManagerPtr mgr)
|
Refactor the security drivers to simplify usage
The current security driver usage requires horrible code like
if (driver->securityDriver &&
driver->securityDriver->domainSetSecurityHostdevLabel &&
driver->securityDriver->domainSetSecurityHostdevLabel(driver->securityDriver,
vm, hostdev) < 0)
This pair of checks for NULL clutters up the code, making the driver
calls 2 lines longer than they really need to be. The goal of the
patchset is to change the calling convention to simply
if (virSecurityManagerSetHostdevLabel(driver->securityDriver,
vm, hostdev) < 0)
The first check for 'driver->securityDriver' being NULL is removed
by introducing a 'no op' security driver that will always be present
if no real driver is enabled. This guarentees driver->securityDriver
!= NULL.
The second check for 'driver->securityDriver->domainSetSecurityHostdevLabel'
being non-NULL is hidden in a new abstraction called virSecurityManager.
This separates the driver callbacks, from main internal API. The addition
of a virSecurityManager object, that is separate from the virSecurityDriver
struct also allows for security drivers to carry state / configuration
information directly. Thus the DAC/Stack drivers from src/qemu which
used to pull config from 'struct qemud_driver' can now be moved into
the 'src/security' directory and store their config directly.
* src/qemu/qemu_conf.h, src/qemu/qemu_driver.c: Update to
use new virSecurityManager APIs
* src/qemu/qemu_security_dac.c, src/qemu/qemu_security_dac.h
src/qemu/qemu_security_stacked.c, src/qemu/qemu_security_stacked.h:
Move into src/security directory
* src/security/security_stack.c, src/security/security_stack.h,
src/security/security_dac.c, src/security/security_dac.h: Generic
versions of previous QEMU specific drivers
* src/security/security_apparmor.c, src/security/security_apparmor.h,
src/security/security_driver.c, src/security/security_driver.h,
src/security/security_selinux.c, src/security/security_selinux.h:
Update to take virSecurityManagerPtr object as the first param
in all callbacks
* src/security/security_nop.c, src/security/security_nop.h: Stub
implementation of all security driver APIs.
* src/security/security_manager.h, src/security/security_manager.c:
New internal API for invoking security drivers
* src/libvirt.c: Add missing debug for security APIs
2010-11-17 20:26:30 +00:00
|
|
|
{
|
2012-05-11 10:43:30 +01:00
|
|
|
virSecuritySELinuxDataPtr data = virSecurityManagerGetPrivateData(mgr);
|
|
|
|
|
|
|
|
if (!data)
|
|
|
|
return 0;
|
|
|
|
|
2012-05-24 17:22:29 +01:00
|
|
|
virHashFree(data->mcs);
|
|
|
|
|
2012-05-11 10:43:30 +01:00
|
|
|
VIR_FREE(data->domain_context);
|
2012-12-12 11:47:19 +00:00
|
|
|
VIR_FREE(data->alt_domain_context);
|
2012-05-11 10:43:30 +01:00
|
|
|
VIR_FREE(data->file_context);
|
|
|
|
VIR_FREE(data->content_context);
|
|
|
|
|
Refactor the security drivers to simplify usage
The current security driver usage requires horrible code like
if (driver->securityDriver &&
driver->securityDriver->domainSetSecurityHostdevLabel &&
driver->securityDriver->domainSetSecurityHostdevLabel(driver->securityDriver,
vm, hostdev) < 0)
This pair of checks for NULL clutters up the code, making the driver
calls 2 lines longer than they really need to be. The goal of the
patchset is to change the calling convention to simply
if (virSecurityManagerSetHostdevLabel(driver->securityDriver,
vm, hostdev) < 0)
The first check for 'driver->securityDriver' being NULL is removed
by introducing a 'no op' security driver that will always be present
if no real driver is enabled. This guarentees driver->securityDriver
!= NULL.
The second check for 'driver->securityDriver->domainSetSecurityHostdevLabel'
being non-NULL is hidden in a new abstraction called virSecurityManager.
This separates the driver callbacks, from main internal API. The addition
of a virSecurityManager object, that is separate from the virSecurityDriver
struct also allows for security drivers to carry state / configuration
information directly. Thus the DAC/Stack drivers from src/qemu which
used to pull config from 'struct qemud_driver' can now be moved into
the 'src/security' directory and store their config directly.
* src/qemu/qemu_conf.h, src/qemu/qemu_driver.c: Update to
use new virSecurityManager APIs
* src/qemu/qemu_security_dac.c, src/qemu/qemu_security_dac.h
src/qemu/qemu_security_stacked.c, src/qemu/qemu_security_stacked.h:
Move into src/security directory
* src/security/security_stack.c, src/security/security_stack.h,
src/security/security_dac.c, src/security/security_dac.h: Generic
versions of previous QEMU specific drivers
* src/security/security_apparmor.c, src/security/security_apparmor.h,
src/security/security_driver.c, src/security/security_driver.h,
src/security/security_selinux.c, src/security/security_selinux.h:
Update to take virSecurityManagerPtr object as the first param
in all callbacks
* src/security/security_nop.c, src/security/security_nop.h: Stub
implementation of all security driver APIs.
* src/security/security_manager.h, src/security/security_manager.c:
New internal API for invoking security drivers
* src/libvirt.c: Add missing debug for security APIs
2010-11-17 20:26:30 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2012-05-24 16:42:51 +01:00
|
|
|
static const char *
|
|
|
|
virSecuritySELinuxSecurityGetModel(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED)
|
Refactor the security drivers to simplify usage
The current security driver usage requires horrible code like
if (driver->securityDriver &&
driver->securityDriver->domainSetSecurityHostdevLabel &&
driver->securityDriver->domainSetSecurityHostdevLabel(driver->securityDriver,
vm, hostdev) < 0)
This pair of checks for NULL clutters up the code, making the driver
calls 2 lines longer than they really need to be. The goal of the
patchset is to change the calling convention to simply
if (virSecurityManagerSetHostdevLabel(driver->securityDriver,
vm, hostdev) < 0)
The first check for 'driver->securityDriver' being NULL is removed
by introducing a 'no op' security driver that will always be present
if no real driver is enabled. This guarentees driver->securityDriver
!= NULL.
The second check for 'driver->securityDriver->domainSetSecurityHostdevLabel'
being non-NULL is hidden in a new abstraction called virSecurityManager.
This separates the driver callbacks, from main internal API. The addition
of a virSecurityManager object, that is separate from the virSecurityDriver
struct also allows for security drivers to carry state / configuration
information directly. Thus the DAC/Stack drivers from src/qemu which
used to pull config from 'struct qemud_driver' can now be moved into
the 'src/security' directory and store their config directly.
* src/qemu/qemu_conf.h, src/qemu/qemu_driver.c: Update to
use new virSecurityManager APIs
* src/qemu/qemu_security_dac.c, src/qemu/qemu_security_dac.h
src/qemu/qemu_security_stacked.c, src/qemu/qemu_security_stacked.h:
Move into src/security directory
* src/security/security_stack.c, src/security/security_stack.h,
src/security/security_dac.c, src/security/security_dac.h: Generic
versions of previous QEMU specific drivers
* src/security/security_apparmor.c, src/security/security_apparmor.h,
src/security/security_driver.c, src/security/security_driver.h,
src/security/security_selinux.c, src/security/security_selinux.h:
Update to take virSecurityManagerPtr object as the first param
in all callbacks
* src/security/security_nop.c, src/security/security_nop.h: Stub
implementation of all security driver APIs.
* src/security/security_manager.h, src/security/security_manager.c:
New internal API for invoking security drivers
* src/libvirt.c: Add missing debug for security APIs
2010-11-17 20:26:30 +00:00
|
|
|
{
|
|
|
|
return SECURITY_SELINUX_NAME;
|
|
|
|
}
|
|
|
|
|
2012-05-24 16:42:51 +01:00
|
|
|
static const char *
|
|
|
|
virSecuritySELinuxSecurityGetDOI(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED)
|
2009-03-03 10:06:49 +00:00
|
|
|
{
|
|
|
|
/*
|
|
|
|
* Where will the DOI come from? SELinux configuration, or qemu
|
|
|
|
* configuration? For the moment, we'll just set it to "0".
|
|
|
|
*/
|
Refactor the security drivers to simplify usage
The current security driver usage requires horrible code like
if (driver->securityDriver &&
driver->securityDriver->domainSetSecurityHostdevLabel &&
driver->securityDriver->domainSetSecurityHostdevLabel(driver->securityDriver,
vm, hostdev) < 0)
This pair of checks for NULL clutters up the code, making the driver
calls 2 lines longer than they really need to be. The goal of the
patchset is to change the calling convention to simply
if (virSecurityManagerSetHostdevLabel(driver->securityDriver,
vm, hostdev) < 0)
The first check for 'driver->securityDriver' being NULL is removed
by introducing a 'no op' security driver that will always be present
if no real driver is enabled. This guarentees driver->securityDriver
!= NULL.
The second check for 'driver->securityDriver->domainSetSecurityHostdevLabel'
being non-NULL is hidden in a new abstraction called virSecurityManager.
This separates the driver callbacks, from main internal API. The addition
of a virSecurityManager object, that is separate from the virSecurityDriver
struct also allows for security drivers to carry state / configuration
information directly. Thus the DAC/Stack drivers from src/qemu which
used to pull config from 'struct qemud_driver' can now be moved into
the 'src/security' directory and store their config directly.
* src/qemu/qemu_conf.h, src/qemu/qemu_driver.c: Update to
use new virSecurityManager APIs
* src/qemu/qemu_security_dac.c, src/qemu/qemu_security_dac.h
src/qemu/qemu_security_stacked.c, src/qemu/qemu_security_stacked.h:
Move into src/security directory
* src/security/security_stack.c, src/security/security_stack.h,
src/security/security_dac.c, src/security/security_dac.h: Generic
versions of previous QEMU specific drivers
* src/security/security_apparmor.c, src/security/security_apparmor.h,
src/security/security_driver.c, src/security/security_driver.h,
src/security/security_selinux.c, src/security/security_selinux.h:
Update to take virSecurityManagerPtr object as the first param
in all callbacks
* src/security/security_nop.c, src/security/security_nop.h: Stub
implementation of all security driver APIs.
* src/security/security_manager.h, src/security/security_manager.c:
New internal API for invoking security drivers
* src/libvirt.c: Add missing debug for security APIs
2010-11-17 20:26:30 +00:00
|
|
|
return SECURITY_SELINUX_VOID_DOI;
|
2009-03-03 10:06:49 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
2012-05-24 16:42:51 +01:00
|
|
|
virSecuritySELinuxGetSecurityProcessLabel(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
|
|
|
|
virDomainDefPtr def ATTRIBUTE_UNUSED,
|
|
|
|
pid_t pid,
|
|
|
|
virSecurityLabelPtr sec)
|
2009-03-03 10:06:49 +00:00
|
|
|
{
|
|
|
|
security_context_t ctx;
|
|
|
|
|
2012-10-05 16:41:22 +02:00
|
|
|
if (getpidcon_raw(pid, &ctx) == -1) {
|
2010-02-04 21:02:58 +01:00
|
|
|
virReportSystemError(errno,
|
2009-08-28 18:44:43 +01:00
|
|
|
_("unable to get PID %d security context"),
|
Change security driver APIs to use virDomainDefPtr instead of virDomainObjPtr
When sVirt is integrated with the LXC driver, it will be neccessary
to invoke the security driver APIs using only a virDomainDefPtr
since the lxc_container.c code has no virDomainObjPtr available.
Aside from two functions which want obj->pid, every bit of the
security driver code only touches obj->def. So we don't need to
pass a virDomainObjPtr into the security drivers, a virDomainDefPtr
is sufficient. Two functions also gain a 'pid_t pid' argument.
* src/qemu/qemu_driver.c, src/qemu/qemu_hotplug.c,
src/qemu/qemu_migration.c, src/qemu/qemu_process.c,
src/security/security_apparmor.c,
src/security/security_dac.c,
src/security/security_driver.h,
src/security/security_manager.c,
src/security/security_manager.h,
src/security/security_nop.c,
src/security/security_selinux.c,
src/security/security_stack.c: Change all security APIs to use a
virDomainDefPtr instead of virDomainObjPtr
2011-07-14 14:32:06 +01:00
|
|
|
pid);
|
2009-03-03 10:06:49 +00:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (strlen((char *) ctx) >= VIR_SECURITY_LABEL_BUFLEN) {
|
2012-07-18 15:39:18 +01:00
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
|
_("security label exceeds "
|
|
|
|
"maximum length: %d"),
|
|
|
|
VIR_SECURITY_LABEL_BUFLEN - 1);
|
2010-11-24 14:09:58 -07:00
|
|
|
freecon(ctx);
|
2009-03-03 10:06:49 +00:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
strcpy(sec->label, (char *) ctx);
|
2010-11-24 14:09:58 -07:00
|
|
|
freecon(ctx);
|
2009-03-03 10:06:49 +00:00
|
|
|
|
2012-05-24 16:42:51 +01:00
|
|
|
VIR_DEBUG("label=%s", sec->label);
|
2009-03-03 10:06:49 +00:00
|
|
|
sec->enforcing = security_getenforce();
|
|
|
|
if (sec->enforcing == -1) {
|
2010-02-04 21:02:58 +01:00
|
|
|
virReportSystemError(errno, "%s",
|
2009-08-28 18:44:43 +01:00
|
|
|
_("error calling security_getenforce()"));
|
2009-03-03 10:06:49 +00:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2011-12-23 08:31:51 -07:00
|
|
|
/* Attempt to change the label of PATH to TCON. If OPTIONAL is true,
|
|
|
|
* return 1 if labelling was not possible. Otherwise, require a label
|
|
|
|
* change, and return 0 for success, -1 for failure. */
|
2009-03-03 10:06:49 +00:00
|
|
|
static int
|
2012-05-24 16:42:51 +01:00
|
|
|
virSecuritySELinuxSetFileconHelper(const char *path, char *tcon, bool optional)
|
2009-03-03 10:06:49 +00:00
|
|
|
{
|
2009-07-03 10:27:46 +00:00
|
|
|
security_context_t econ;
|
2009-03-03 10:06:49 +00:00
|
|
|
|
2009-07-03 10:26:37 +00:00
|
|
|
VIR_INFO("Setting SELinux context on '%s' to '%s'", path, tcon);
|
|
|
|
|
2012-10-05 16:41:22 +02:00
|
|
|
if (setfilecon_raw(path, tcon) < 0) {
|
2009-08-21 16:57:29 +02:00
|
|
|
int setfilecon_errno = errno;
|
|
|
|
|
2012-10-05 16:41:22 +02:00
|
|
|
if (getfilecon_raw(path, &econ) >= 0) {
|
2009-07-03 10:27:46 +00:00
|
|
|
if (STREQ(tcon, econ)) {
|
|
|
|
freecon(econ);
|
|
|
|
/* It's alright, there's nothing to change anyway. */
|
2011-12-23 08:31:51 -07:00
|
|
|
return optional ? 1 : 0;
|
2009-07-03 10:27:46 +00:00
|
|
|
}
|
|
|
|
freecon(econ);
|
|
|
|
}
|
2009-08-21 16:57:29 +02:00
|
|
|
|
|
|
|
/* if the error complaint is related to an image hosted on
|
2009-08-14 14:23:11 +01:00
|
|
|
* an nfs mount, or a usbfs/sysfs filesystem not supporting
|
|
|
|
* labelling, then just ignore it & hope for the best.
|
2009-09-22 11:42:06 +02:00
|
|
|
* The user hopefully set one of the necessary SELinux
|
2009-08-14 14:23:11 +01:00
|
|
|
* virt_use_{nfs,usb,pci} boolean tunables to allow it...
|
2009-08-21 16:57:29 +02:00
|
|
|
*/
|
2011-09-22 10:57:24 +02:00
|
|
|
if (setfilecon_errno != EOPNOTSUPP && setfilecon_errno != ENOTSUP) {
|
2010-02-04 21:02:58 +01:00
|
|
|
virReportSystemError(setfilecon_errno,
|
2011-09-22 10:57:24 +02:00
|
|
|
_("unable to set security context '%s' on '%s'"),
|
2009-08-28 18:44:43 +01:00
|
|
|
tcon, path);
|
2009-08-21 16:57:29 +02:00
|
|
|
if (security_getenforce() == 1)
|
|
|
|
return -1;
|
2009-08-28 18:44:43 +01:00
|
|
|
} else {
|
2011-09-22 10:57:24 +02:00
|
|
|
const char *msg;
|
|
|
|
if ((virStorageFileIsSharedFSType(path,
|
|
|
|
VIR_STORAGE_FILE_SHFS_NFS) == 1) &&
|
|
|
|
security_get_boolean_active("virt_use_nfs") != 1) {
|
|
|
|
msg = _("Setting security context '%s' on '%s' not supported. "
|
|
|
|
"Consider setting virt_use_nfs");
|
|
|
|
if (security_getenforce() == 1)
|
|
|
|
VIR_WARN(msg, tcon, path);
|
|
|
|
else
|
|
|
|
VIR_INFO(msg, tcon, path);
|
|
|
|
} else {
|
|
|
|
VIR_INFO("Setting security context '%s' on '%s' not supported",
|
|
|
|
tcon, path);
|
|
|
|
}
|
2011-12-23 08:31:51 -07:00
|
|
|
if (optional)
|
|
|
|
return 1;
|
2009-08-21 16:57:29 +02:00
|
|
|
}
|
2009-03-03 10:06:49 +00:00
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2011-12-23 08:31:51 -07:00
|
|
|
static int
|
2012-05-24 16:42:51 +01:00
|
|
|
virSecuritySELinuxSetFileconOptional(const char *path, char *tcon)
|
2011-12-23 08:31:51 -07:00
|
|
|
{
|
2012-05-24 16:42:51 +01:00
|
|
|
return virSecuritySELinuxSetFileconHelper(path, tcon, true);
|
2011-12-23 08:31:51 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
2012-05-24 16:42:51 +01:00
|
|
|
virSecuritySELinuxSetFilecon(const char *path, char *tcon)
|
2011-12-23 08:31:51 -07:00
|
|
|
{
|
2012-05-24 16:42:51 +01:00
|
|
|
return virSecuritySELinuxSetFileconHelper(path, tcon, false);
|
2011-12-23 08:31:51 -07:00
|
|
|
}
|
|
|
|
|
2011-01-23 16:02:42 -05:00
|
|
|
static int
|
2012-05-24 16:42:51 +01:00
|
|
|
virSecuritySELinuxFSetFilecon(int fd, char *tcon)
|
2011-01-23 16:02:42 -05:00
|
|
|
{
|
|
|
|
security_context_t econ;
|
|
|
|
|
|
|
|
VIR_INFO("Setting SELinux context on fd %d to '%s'", fd, tcon);
|
|
|
|
|
2012-10-05 16:41:22 +02:00
|
|
|
if (fsetfilecon_raw(fd, tcon) < 0) {
|
2011-01-23 16:02:42 -05:00
|
|
|
int fsetfilecon_errno = errno;
|
|
|
|
|
2012-10-05 16:41:22 +02:00
|
|
|
if (fgetfilecon_raw(fd, &econ) >= 0) {
|
2011-01-23 16:02:42 -05:00
|
|
|
if (STREQ(tcon, econ)) {
|
|
|
|
freecon(econ);
|
|
|
|
/* It's alright, there's nothing to change anyway. */
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
freecon(econ);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* if the error complaint is related to an image hosted on
|
|
|
|
* an nfs mount, or a usbfs/sysfs filesystem not supporting
|
|
|
|
* labelling, then just ignore it & hope for the best.
|
|
|
|
* The user hopefully set one of the necessary SELinux
|
|
|
|
* virt_use_{nfs,usb,pci} boolean tunables to allow it...
|
|
|
|
*/
|
|
|
|
if (fsetfilecon_errno != EOPNOTSUPP) {
|
|
|
|
virReportSystemError(fsetfilecon_errno,
|
|
|
|
_("unable to set security context '%s' on fd %d"),
|
|
|
|
tcon, fd);
|
|
|
|
if (security_getenforce() == 1)
|
|
|
|
return -1;
|
|
|
|
} else {
|
|
|
|
VIR_INFO("Setting security context '%s' on fd %d not supported",
|
|
|
|
tcon, fd);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2010-12-14 17:07:52 -07:00
|
|
|
/* Set fcon to the appropriate label for path and mode, or return -1. */
|
|
|
|
static int
|
|
|
|
getContext(const char *newpath, mode_t mode, security_context_t *fcon)
|
|
|
|
{
|
|
|
|
#if HAVE_SELINUX_LABEL_H
|
|
|
|
struct selabel_handle *handle = selabel_open(SELABEL_CTX_FILE, NULL, 0);
|
|
|
|
int ret;
|
|
|
|
|
|
|
|
if (handle == NULL)
|
|
|
|
return -1;
|
|
|
|
|
2012-10-15 14:04:36 +02:00
|
|
|
ret = selabel_lookup_raw(handle, fcon, newpath, mode);
|
2010-12-14 17:07:52 -07:00
|
|
|
selabel_close(handle);
|
|
|
|
return ret;
|
|
|
|
#else
|
|
|
|
return matchpathcon(newpath, mode, fcon);
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2010-05-28 12:19:13 +01:00
|
|
|
|
|
|
|
/* This method shouldn't raise errors, since they'll overwrite
|
|
|
|
* errors that the caller(s) are already dealing with */
|
2009-03-03 10:06:49 +00:00
|
|
|
static int
|
2012-05-24 16:42:51 +01:00
|
|
|
virSecuritySELinuxRestoreSecurityFileLabel(const char *path)
|
2009-03-03 10:06:49 +00:00
|
|
|
{
|
2009-03-17 11:35:40 +00:00
|
|
|
struct stat buf;
|
|
|
|
security_context_t fcon = NULL;
|
|
|
|
int rc = -1;
|
|
|
|
char *newpath = NULL;
|
2010-05-28 12:19:13 +01:00
|
|
|
char ebuf[1024];
|
2009-07-15 12:45:13 +01:00
|
|
|
|
2009-08-28 18:44:43 +01:00
|
|
|
VIR_INFO("Restoring SELinux context on '%s'", path);
|
|
|
|
|
2010-05-14 14:50:27 -06:00
|
|
|
if (virFileResolveLink(path, &newpath) < 0) {
|
2010-05-28 12:19:13 +01:00
|
|
|
VIR_WARN("cannot resolve symlink %s: %s", path,
|
|
|
|
virStrerror(errno, ebuf, sizeof(ebuf)));
|
2009-04-01 10:26:22 +00:00
|
|
|
goto err;
|
2009-03-03 10:06:49 +00:00
|
|
|
}
|
2009-03-17 11:35:40 +00:00
|
|
|
|
2010-04-30 13:35:15 +02:00
|
|
|
if (stat(newpath, &buf) != 0) {
|
2010-05-28 12:19:13 +01:00
|
|
|
VIR_WARN("cannot stat %s: %s", newpath,
|
|
|
|
virStrerror(errno, ebuf, sizeof(ebuf)));
|
2009-04-01 10:26:22 +00:00
|
|
|
goto err;
|
2010-04-30 13:35:15 +02:00
|
|
|
}
|
2009-04-01 10:26:22 +00:00
|
|
|
|
2010-12-14 17:07:52 -07:00
|
|
|
if (getContext(newpath, buf.st_mode, &fcon) < 0) {
|
2012-10-20 15:57:28 -04:00
|
|
|
/* Any user created path likely does not have a default label,
|
|
|
|
* which makes this an expected non error
|
|
|
|
*/
|
2010-11-30 18:22:54 -07:00
|
|
|
VIR_WARN("cannot lookup default selinux label for %s", newpath);
|
2012-10-20 15:57:28 -04:00
|
|
|
rc = 0;
|
2010-04-30 13:35:15 +02:00
|
|
|
} else {
|
2012-05-24 16:42:51 +01:00
|
|
|
rc = virSecuritySELinuxSetFilecon(newpath, fcon);
|
2009-03-17 11:35:40 +00:00
|
|
|
}
|
2010-04-30 13:35:15 +02:00
|
|
|
|
2009-03-17 11:35:40 +00:00
|
|
|
err:
|
2010-11-24 14:09:58 -07:00
|
|
|
freecon(fcon);
|
2009-03-17 11:35:40 +00:00
|
|
|
VIR_FREE(newpath);
|
|
|
|
return rc;
|
2009-03-03 10:06:49 +00:00
|
|
|
}
|
|
|
|
|
2009-08-14 14:23:11 +01:00
|
|
|
static int
|
2012-05-24 16:42:51 +01:00
|
|
|
virSecuritySELinuxRestoreSecurityImageLabelInt(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
|
|
|
|
virDomainDefPtr def,
|
|
|
|
virDomainDiskDefPtr disk,
|
|
|
|
int migrated)
|
2009-08-14 14:23:11 +01:00
|
|
|
{
|
2012-08-15 19:10:37 -03:00
|
|
|
virSecurityLabelDefPtr seclabel;
|
|
|
|
virSecurityDeviceLabelDefPtr disk_seclabel;
|
|
|
|
|
|
|
|
seclabel = virDomainDefGetSecurityLabelDef(def, SECURITY_SELINUX_NAME);
|
|
|
|
if (seclabel == NULL)
|
|
|
|
return -1;
|
2010-01-13 14:03:04 +00:00
|
|
|
|
2012-08-15 19:10:37 -03:00
|
|
|
disk_seclabel = virDomainDiskDefGetSecurityLabelDef(disk,
|
|
|
|
SECURITY_SELINUX_NAME);
|
|
|
|
if (seclabel->norelabel || (disk_seclabel && disk_seclabel->norelabel))
|
2010-01-13 14:03:04 +00:00
|
|
|
return 0;
|
|
|
|
|
2009-08-14 14:23:11 +01:00
|
|
|
/* Don't restore labels on readoly/shared disks, because
|
|
|
|
* other VMs may still be accessing these
|
|
|
|
* Alternatively we could iterate over all running
|
|
|
|
* domains and try to figure out if it is in use, but
|
|
|
|
* this would not work for clustered filesystems, since
|
|
|
|
* we can't see running VMs using the file on other nodes
|
|
|
|
* Safest bet is thus to skip the restore step.
|
|
|
|
*/
|
|
|
|
if (disk->readonly || disk->shared)
|
|
|
|
return 0;
|
|
|
|
|
2010-12-20 18:30:58 -08:00
|
|
|
if (!disk->src || disk->type == VIR_DOMAIN_DISK_TYPE_NETWORK)
|
2009-08-14 14:23:11 +01:00
|
|
|
return 0;
|
|
|
|
|
Don't reset user/group/security label on shared filesystems during migrate
When QEMU runs with its disk on NFS, and as a non-root user, the
disk is chownd to that non-root user. When migration completes
the last step is shutting down the QEMU on the source host. THis
normally resets user/group/security label. This is bad when the
VM was just migrated because the file is still in use on the dest
host. It is thus neccessary to skip the reset step for any files
found to be on a shared filesystem
* src/libvirt_private.syms: Export virStorageFileIsSharedFS
* src/util/storage_file.c, src/util/storage_file.h: Add a new
method virStorageFileIsSharedFS() to determine if a file is
on a shared filesystem (NFS, GFS, OCFS2, etc)
* src/qemu/qemu_driver.c: Tell security driver not to reset
disk labels on migration completion
* src/qemu/qemu_security_dac.c, src/qemu/qemu_security_stacked.c,
src/security/security_selinux.c, src/security/security_driver.h,
src/security/security_apparmor.c: Add ability to skip disk
restore step for files on shared filesystems.
2010-05-13 11:49:22 -04:00
|
|
|
/* If we have a shared FS & doing migrated, we must not
|
|
|
|
* change ownership, because that kills access on the
|
|
|
|
* destination host which is sub-optimal for the guest
|
|
|
|
* VM's I/O attempts :-)
|
|
|
|
*/
|
|
|
|
if (migrated) {
|
|
|
|
int rc = virStorageFileIsSharedFS(disk->src);
|
|
|
|
if (rc < 0)
|
|
|
|
return -1;
|
|
|
|
if (rc == 1) {
|
|
|
|
VIR_DEBUG("Skipping image label restore on %s because FS is shared",
|
|
|
|
disk->src);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-05-24 16:42:51 +01:00
|
|
|
return virSecuritySELinuxRestoreSecurityFileLabel(disk->src);
|
2009-08-14 14:23:11 +01:00
|
|
|
}
|
|
|
|
|
Don't reset user/group/security label on shared filesystems during migrate
When QEMU runs with its disk on NFS, and as a non-root user, the
disk is chownd to that non-root user. When migration completes
the last step is shutting down the QEMU on the source host. THis
normally resets user/group/security label. This is bad when the
VM was just migrated because the file is still in use on the dest
host. It is thus neccessary to skip the reset step for any files
found to be on a shared filesystem
* src/libvirt_private.syms: Export virStorageFileIsSharedFS
* src/util/storage_file.c, src/util/storage_file.h: Add a new
method virStorageFileIsSharedFS() to determine if a file is
on a shared filesystem (NFS, GFS, OCFS2, etc)
* src/qemu/qemu_driver.c: Tell security driver not to reset
disk labels on migration completion
* src/qemu/qemu_security_dac.c, src/qemu/qemu_security_stacked.c,
src/security/security_selinux.c, src/security/security_driver.h,
src/security/security_apparmor.c: Add ability to skip disk
restore step for files on shared filesystems.
2010-05-13 11:49:22 -04:00
|
|
|
|
|
|
|
static int
|
2012-05-24 16:42:51 +01:00
|
|
|
virSecuritySELinuxRestoreSecurityImageLabel(virSecurityManagerPtr mgr,
|
|
|
|
virDomainDefPtr def,
|
|
|
|
virDomainDiskDefPtr disk)
|
Don't reset user/group/security label on shared filesystems during migrate
When QEMU runs with its disk on NFS, and as a non-root user, the
disk is chownd to that non-root user. When migration completes
the last step is shutting down the QEMU on the source host. THis
normally resets user/group/security label. This is bad when the
VM was just migrated because the file is still in use on the dest
host. It is thus neccessary to skip the reset step for any files
found to be on a shared filesystem
* src/libvirt_private.syms: Export virStorageFileIsSharedFS
* src/util/storage_file.c, src/util/storage_file.h: Add a new
method virStorageFileIsSharedFS() to determine if a file is
on a shared filesystem (NFS, GFS, OCFS2, etc)
* src/qemu/qemu_driver.c: Tell security driver not to reset
disk labels on migration completion
* src/qemu/qemu_security_dac.c, src/qemu/qemu_security_stacked.c,
src/security/security_selinux.c, src/security/security_driver.h,
src/security/security_apparmor.c: Add ability to skip disk
restore step for files on shared filesystems.
2010-05-13 11:49:22 -04:00
|
|
|
{
|
2012-05-24 16:42:51 +01:00
|
|
|
return virSecuritySELinuxRestoreSecurityImageLabelInt(mgr, def, disk, 0);
|
Don't reset user/group/security label on shared filesystems during migrate
When QEMU runs with its disk on NFS, and as a non-root user, the
disk is chownd to that non-root user. When migration completes
the last step is shutting down the QEMU on the source host. THis
normally resets user/group/security label. This is bad when the
VM was just migrated because the file is still in use on the dest
host. It is thus neccessary to skip the reset step for any files
found to be on a shared filesystem
* src/libvirt_private.syms: Export virStorageFileIsSharedFS
* src/util/storage_file.c, src/util/storage_file.h: Add a new
method virStorageFileIsSharedFS() to determine if a file is
on a shared filesystem (NFS, GFS, OCFS2, etc)
* src/qemu/qemu_driver.c: Tell security driver not to reset
disk labels on migration completion
* src/qemu/qemu_security_dac.c, src/qemu/qemu_security_stacked.c,
src/security/security_selinux.c, src/security/security_driver.h,
src/security/security_apparmor.c: Add ability to skip disk
restore step for files on shared filesystems.
2010-05-13 11:49:22 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2010-06-15 16:40:47 +01:00
|
|
|
static int
|
2012-05-24 16:42:51 +01:00
|
|
|
virSecuritySELinuxSetSecurityFileLabel(virDomainDiskDefPtr disk,
|
|
|
|
const char *path,
|
|
|
|
size_t depth,
|
|
|
|
void *opaque)
|
2010-06-15 16:40:47 +01:00
|
|
|
{
|
2012-08-15 19:10:37 -03:00
|
|
|
int ret;
|
|
|
|
virSecurityDeviceLabelDefPtr disk_seclabel;
|
2012-05-11 10:43:30 +01:00
|
|
|
virSecuritySELinuxCallbackDataPtr cbdata = opaque;
|
|
|
|
const virSecurityLabelDefPtr secdef = cbdata->secdef;
|
|
|
|
virSecuritySELinuxDataPtr data = virSecurityManagerGetPrivateData(cbdata->manager);
|
2010-06-15 16:40:47 +01:00
|
|
|
|
2012-08-15 19:10:37 -03:00
|
|
|
disk_seclabel = virDomainDiskDefGetSecurityLabelDef(disk,
|
|
|
|
SECURITY_SELINUX_NAME);
|
|
|
|
|
|
|
|
if (disk_seclabel && disk_seclabel->norelabel)
|
2011-12-23 08:31:51 -07:00
|
|
|
return 0;
|
|
|
|
|
2012-08-15 19:10:37 -03:00
|
|
|
if (disk_seclabel && !disk_seclabel->norelabel &&
|
|
|
|
disk_seclabel->label) {
|
|
|
|
ret = virSecuritySELinuxSetFilecon(path, disk_seclabel->label);
|
2011-12-23 08:31:51 -07:00
|
|
|
} else if (depth == 0) {
|
2012-05-11 10:43:30 +01:00
|
|
|
|
2010-06-15 16:40:47 +01:00
|
|
|
if (disk->shared) {
|
2012-05-24 16:42:51 +01:00
|
|
|
ret = virSecuritySELinuxSetFileconOptional(path, data->file_context);
|
2010-06-15 16:40:47 +01:00
|
|
|
} else if (disk->readonly) {
|
2012-05-24 16:42:51 +01:00
|
|
|
ret = virSecuritySELinuxSetFileconOptional(path, data->content_context);
|
2010-06-15 16:40:47 +01:00
|
|
|
} else if (secdef->imagelabel) {
|
2012-05-24 16:42:51 +01:00
|
|
|
ret = virSecuritySELinuxSetFileconOptional(path, secdef->imagelabel);
|
2010-06-15 16:40:47 +01:00
|
|
|
} else {
|
2010-11-10 14:39:43 -05:00
|
|
|
ret = 0;
|
2010-06-15 16:40:47 +01:00
|
|
|
}
|
|
|
|
} else {
|
2012-05-24 16:42:51 +01:00
|
|
|
ret = virSecuritySELinuxSetFileconOptional(path, data->content_context);
|
2011-12-23 08:31:51 -07:00
|
|
|
}
|
2012-08-15 19:10:37 -03:00
|
|
|
if (ret == 1 && !disk_seclabel) {
|
2011-12-23 08:31:51 -07:00
|
|
|
/* If we failed to set a label, but virt_use_nfs let us
|
|
|
|
* proceed anyway, then we don't need to relabel later. */
|
2012-08-15 19:10:37 -03:00
|
|
|
if (VIR_ALLOC(disk_seclabel) < 0) {
|
2011-12-23 08:31:51 -07:00
|
|
|
virReportOOMError();
|
|
|
|
return -1;
|
|
|
|
}
|
2012-08-15 19:10:37 -03:00
|
|
|
disk_seclabel->norelabel = true;
|
2011-12-23 08:31:51 -07:00
|
|
|
ret = 0;
|
2010-06-15 16:40:47 +01:00
|
|
|
}
|
2010-11-10 14:39:43 -05:00
|
|
|
return ret;
|
2010-06-15 16:40:47 +01:00
|
|
|
}
|
|
|
|
|
2009-03-03 10:06:49 +00:00
|
|
|
static int
|
2012-05-24 16:42:51 +01:00
|
|
|
virSecuritySELinuxSetSecurityImageLabel(virSecurityManagerPtr mgr,
|
|
|
|
virDomainDefPtr def,
|
|
|
|
virDomainDiskDefPtr disk)
|
2009-03-03 10:06:49 +00:00
|
|
|
|
|
|
|
{
|
2012-05-11 10:43:30 +01:00
|
|
|
virSecuritySELinuxCallbackData cbdata;
|
|
|
|
cbdata.manager = mgr;
|
2012-08-15 19:10:37 -03:00
|
|
|
cbdata.secdef = virDomainDefGetSecurityLabelDef(def, SECURITY_SELINUX_NAME);
|
2012-05-11 10:43:30 +01:00
|
|
|
|
2012-08-15 19:10:37 -03:00
|
|
|
if (cbdata.secdef == NULL)
|
|
|
|
return -1;
|
2009-03-03 10:06:49 +00:00
|
|
|
|
2012-05-11 10:43:30 +01:00
|
|
|
if (cbdata.secdef->norelabel)
|
2010-01-13 14:03:04 +00:00
|
|
|
return 0;
|
|
|
|
|
2011-12-09 19:49:40 -08:00
|
|
|
if (disk->type == VIR_DOMAIN_DISK_TYPE_NETWORK)
|
|
|
|
return 0;
|
|
|
|
|
2010-06-15 16:40:47 +01:00
|
|
|
return virDomainDiskDefForeachPath(disk,
|
2010-10-29 12:23:56 +01:00
|
|
|
true,
|
2012-05-24 16:42:51 +01:00
|
|
|
virSecuritySELinuxSetSecurityFileLabel,
|
2012-05-11 10:43:30 +01:00
|
|
|
&cbdata);
|
2009-03-03 10:06:49 +00:00
|
|
|
}
|
|
|
|
|
2009-08-14 14:23:11 +01:00
|
|
|
|
|
|
|
static int
|
2012-05-24 16:42:51 +01:00
|
|
|
virSecuritySELinuxSetSecurityPCILabel(pciDevice *dev ATTRIBUTE_UNUSED,
|
|
|
|
const char *file, void *opaque)
|
2009-08-14 14:23:11 +01:00
|
|
|
{
|
2012-08-15 19:10:37 -03:00
|
|
|
virSecurityLabelDefPtr secdef;
|
Change security driver APIs to use virDomainDefPtr instead of virDomainObjPtr
When sVirt is integrated with the LXC driver, it will be neccessary
to invoke the security driver APIs using only a virDomainDefPtr
since the lxc_container.c code has no virDomainObjPtr available.
Aside from two functions which want obj->pid, every bit of the
security driver code only touches obj->def. So we don't need to
pass a virDomainObjPtr into the security drivers, a virDomainDefPtr
is sufficient. Two functions also gain a 'pid_t pid' argument.
* src/qemu/qemu_driver.c, src/qemu/qemu_hotplug.c,
src/qemu/qemu_migration.c, src/qemu/qemu_process.c,
src/security/security_apparmor.c,
src/security/security_dac.c,
src/security/security_driver.h,
src/security/security_manager.c,
src/security/security_manager.h,
src/security/security_nop.c,
src/security/security_selinux.c,
src/security/security_stack.c: Change all security APIs to use a
virDomainDefPtr instead of virDomainObjPtr
2011-07-14 14:32:06 +01:00
|
|
|
virDomainDefPtr def = opaque;
|
2009-08-14 14:23:11 +01:00
|
|
|
|
2012-08-15 19:10:37 -03:00
|
|
|
secdef = virDomainDefGetSecurityLabelDef(def, SECURITY_SELINUX_NAME);
|
|
|
|
if (secdef == NULL)
|
|
|
|
return -1;
|
2012-05-24 16:42:51 +01:00
|
|
|
return virSecuritySELinuxSetFilecon(file, secdef->imagelabel);
|
2009-08-14 14:23:11 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
2012-05-24 16:42:51 +01:00
|
|
|
virSecuritySELinuxSetSecurityUSBLabel(usbDevice *dev ATTRIBUTE_UNUSED,
|
|
|
|
const char *file, void *opaque)
|
2009-08-14 14:23:11 +01:00
|
|
|
{
|
2012-08-15 19:10:37 -03:00
|
|
|
virSecurityLabelDefPtr secdef;
|
Change security driver APIs to use virDomainDefPtr instead of virDomainObjPtr
When sVirt is integrated with the LXC driver, it will be neccessary
to invoke the security driver APIs using only a virDomainDefPtr
since the lxc_container.c code has no virDomainObjPtr available.
Aside from two functions which want obj->pid, every bit of the
security driver code only touches obj->def. So we don't need to
pass a virDomainObjPtr into the security drivers, a virDomainDefPtr
is sufficient. Two functions also gain a 'pid_t pid' argument.
* src/qemu/qemu_driver.c, src/qemu/qemu_hotplug.c,
src/qemu/qemu_migration.c, src/qemu/qemu_process.c,
src/security/security_apparmor.c,
src/security/security_dac.c,
src/security/security_driver.h,
src/security/security_manager.c,
src/security/security_manager.h,
src/security/security_nop.c,
src/security/security_selinux.c,
src/security/security_stack.c: Change all security APIs to use a
virDomainDefPtr instead of virDomainObjPtr
2011-07-14 14:32:06 +01:00
|
|
|
virDomainDefPtr def = opaque;
|
2012-08-15 19:10:37 -03:00
|
|
|
|
|
|
|
secdef = virDomainDefGetSecurityLabelDef(def, SECURITY_SELINUX_NAME);
|
|
|
|
if (secdef == NULL)
|
|
|
|
return -1;
|
2009-08-14 14:23:11 +01:00
|
|
|
|
2012-05-24 16:42:51 +01:00
|
|
|
return virSecuritySELinuxSetFilecon(file, secdef->imagelabel);
|
2009-08-14 14:23:11 +01:00
|
|
|
}
|
|
|
|
|
2012-11-28 15:54:56 +00:00
|
|
|
|
2009-08-14 14:23:11 +01:00
|
|
|
static int
|
2012-11-28 15:54:56 +00:00
|
|
|
virSecuritySELinuxSetSecurityHostdevSubsysLabel(virDomainDefPtr def,
|
|
|
|
virDomainHostdevDefPtr dev,
|
|
|
|
const char *vroot)
|
2009-08-14 14:23:11 +01:00
|
|
|
|
|
|
|
{
|
|
|
|
int ret = -1;
|
|
|
|
|
|
|
|
switch (dev->source.subsys.type) {
|
|
|
|
case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB: {
|
2012-10-03 16:57:28 +02:00
|
|
|
usbDevice *usb;
|
2009-08-14 14:23:11 +01:00
|
|
|
|
2012-10-03 16:57:28 +02:00
|
|
|
if (dev->missing)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
usb = usbGetDevice(dev->source.subsys.u.usb.bus,
|
2012-11-27 16:17:47 +00:00
|
|
|
dev->source.subsys.u.usb.device,
|
|
|
|
vroot);
|
2010-01-11 11:40:46 -05:00
|
|
|
if (!usb)
|
|
|
|
goto done;
|
2009-08-14 14:23:11 +01:00
|
|
|
|
2012-05-24 16:42:51 +01:00
|
|
|
ret = usbDeviceFileIterate(usb, virSecuritySELinuxSetSecurityUSBLabel, def);
|
2010-02-05 00:25:16 +01:00
|
|
|
usbFreeDevice(usb);
|
2009-09-30 18:37:03 +01:00
|
|
|
break;
|
2009-08-14 14:23:11 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI: {
|
2010-02-05 00:16:34 +01:00
|
|
|
pciDevice *pci = pciGetDevice(dev->source.subsys.u.pci.domain,
|
2009-08-14 14:23:11 +01:00
|
|
|
dev->source.subsys.u.pci.bus,
|
|
|
|
dev->source.subsys.u.pci.slot,
|
|
|
|
dev->source.subsys.u.pci.function);
|
|
|
|
|
|
|
|
if (!pci)
|
|
|
|
goto done;
|
|
|
|
|
2012-05-24 16:42:51 +01:00
|
|
|
ret = pciDeviceFileIterate(pci, virSecuritySELinuxSetSecurityPCILabel, def);
|
2010-02-05 00:16:34 +01:00
|
|
|
pciFreeDevice(pci);
|
2009-08-14 14:23:11 +01:00
|
|
|
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
default:
|
|
|
|
ret = 0;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
done:
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2009-11-11 12:07:00 +00:00
|
|
|
|
2012-11-28 16:07:27 +00:00
|
|
|
static int
|
|
|
|
virSecuritySELinuxSetSecurityHostdevCapsLabel(virDomainDefPtr def,
|
|
|
|
virDomainHostdevDefPtr dev,
|
|
|
|
const char *vroot)
|
|
|
|
{
|
|
|
|
int ret = -1;
|
|
|
|
virSecurityLabelDefPtr secdef;
|
|
|
|
char *path;
|
|
|
|
|
|
|
|
secdef = virDomainDefGetSecurityLabelDef(def, SECURITY_SELINUX_NAME);
|
|
|
|
if (secdef == NULL)
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
switch (dev->source.caps.type) {
|
|
|
|
case VIR_DOMAIN_HOSTDEV_CAPS_TYPE_STORAGE: {
|
|
|
|
if (vroot) {
|
|
|
|
if (virAsprintf(&path, "%s/%s", vroot,
|
|
|
|
dev->source.caps.u.storage.block) < 0) {
|
|
|
|
virReportOOMError();
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
if (!(path = strdup(dev->source.caps.u.storage.block))) {
|
|
|
|
virReportOOMError();
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
ret = virSecuritySELinuxSetFilecon(path, secdef->imagelabel);
|
|
|
|
VIR_FREE(path);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
case VIR_DOMAIN_HOSTDEV_CAPS_TYPE_MISC: {
|
|
|
|
if (vroot) {
|
|
|
|
if (virAsprintf(&path, "%s/%s", vroot,
|
|
|
|
dev->source.caps.u.misc.chardev) < 0) {
|
|
|
|
virReportOOMError();
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
if (!(path = strdup(dev->source.caps.u.misc.chardev))) {
|
|
|
|
virReportOOMError();
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
ret = virSecuritySELinuxSetFilecon(path, secdef->imagelabel);
|
|
|
|
VIR_FREE(path);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
default:
|
|
|
|
ret = 0;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2012-11-28 15:54:56 +00:00
|
|
|
static int
|
|
|
|
virSecuritySELinuxSetSecurityHostdevLabel(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
|
|
|
|
virDomainDefPtr def,
|
|
|
|
virDomainHostdevDefPtr dev,
|
|
|
|
const char *vroot)
|
|
|
|
|
|
|
|
{
|
|
|
|
virSecurityLabelDefPtr secdef;
|
|
|
|
|
|
|
|
secdef = virDomainDefGetSecurityLabelDef(def, SECURITY_SELINUX_NAME);
|
|
|
|
if (secdef == NULL)
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
if (secdef->norelabel)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
switch (dev->mode) {
|
|
|
|
case VIR_DOMAIN_HOSTDEV_MODE_SUBSYS:
|
|
|
|
return virSecuritySELinuxSetSecurityHostdevSubsysLabel(def, dev, vroot);
|
|
|
|
|
2012-11-28 16:07:27 +00:00
|
|
|
case VIR_DOMAIN_HOSTDEV_MODE_CAPABILITIES:
|
|
|
|
return virSecuritySELinuxSetSecurityHostdevCapsLabel(def, dev, vroot);
|
|
|
|
|
2012-11-28 15:54:56 +00:00
|
|
|
default:
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2009-08-14 14:23:11 +01:00
|
|
|
static int
|
2012-05-24 16:42:51 +01:00
|
|
|
virSecuritySELinuxRestoreSecurityPCILabel(pciDevice *dev ATTRIBUTE_UNUSED,
|
|
|
|
const char *file,
|
|
|
|
void *opaque ATTRIBUTE_UNUSED)
|
2009-08-14 14:23:11 +01:00
|
|
|
{
|
2012-05-24 16:42:51 +01:00
|
|
|
return virSecuritySELinuxRestoreSecurityFileLabel(file);
|
2009-08-14 14:23:11 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
2012-05-24 16:42:51 +01:00
|
|
|
virSecuritySELinuxRestoreSecurityUSBLabel(usbDevice *dev ATTRIBUTE_UNUSED,
|
|
|
|
const char *file,
|
|
|
|
void *opaque ATTRIBUTE_UNUSED)
|
2009-08-14 14:23:11 +01:00
|
|
|
{
|
2012-05-24 16:42:51 +01:00
|
|
|
return virSecuritySELinuxRestoreSecurityFileLabel(file);
|
2009-08-14 14:23:11 +01:00
|
|
|
}
|
|
|
|
|
2012-11-28 15:54:56 +00:00
|
|
|
|
2009-08-14 14:23:11 +01:00
|
|
|
static int
|
2012-11-28 15:54:56 +00:00
|
|
|
virSecuritySELinuxRestoreSecurityHostdevSubsysLabel(virDomainHostdevDefPtr dev,
|
|
|
|
const char *vroot)
|
2009-08-14 14:23:11 +01:00
|
|
|
|
|
|
|
{
|
|
|
|
int ret = -1;
|
|
|
|
|
|
|
|
switch (dev->source.subsys.type) {
|
|
|
|
case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB: {
|
2012-10-03 16:57:28 +02:00
|
|
|
usbDevice *usb;
|
|
|
|
|
|
|
|
if (dev->missing)
|
|
|
|
return 0;
|
2009-08-14 14:23:11 +01:00
|
|
|
|
2012-10-03 16:57:28 +02:00
|
|
|
usb = usbGetDevice(dev->source.subsys.u.usb.bus,
|
2012-11-27 16:17:47 +00:00
|
|
|
dev->source.subsys.u.usb.device,
|
|
|
|
vroot);
|
2009-08-14 14:23:11 +01:00
|
|
|
if (!usb)
|
|
|
|
goto done;
|
|
|
|
|
2012-05-24 16:42:51 +01:00
|
|
|
ret = usbDeviceFileIterate(usb, virSecuritySELinuxRestoreSecurityUSBLabel, NULL);
|
2010-02-05 00:25:16 +01:00
|
|
|
usbFreeDevice(usb);
|
2009-08-14 14:23:11 +01:00
|
|
|
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI: {
|
2010-02-05 00:16:34 +01:00
|
|
|
pciDevice *pci = pciGetDevice(dev->source.subsys.u.pci.domain,
|
2009-08-14 14:23:11 +01:00
|
|
|
dev->source.subsys.u.pci.bus,
|
|
|
|
dev->source.subsys.u.pci.slot,
|
|
|
|
dev->source.subsys.u.pci.function);
|
|
|
|
|
|
|
|
if (!pci)
|
|
|
|
goto done;
|
|
|
|
|
2012-05-24 16:42:51 +01:00
|
|
|
ret = pciDeviceFileIterate(pci, virSecuritySELinuxRestoreSecurityPCILabel, NULL);
|
2010-02-05 00:16:34 +01:00
|
|
|
pciFreeDevice(pci);
|
2009-08-14 14:23:11 +01:00
|
|
|
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
default:
|
|
|
|
ret = 0;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
done:
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2010-06-23 16:17:15 +01:00
|
|
|
|
2012-11-28 16:07:27 +00:00
|
|
|
static int
|
|
|
|
virSecuritySELinuxRestoreSecurityHostdevCapsLabel(virDomainHostdevDefPtr dev,
|
|
|
|
const char *vroot)
|
|
|
|
{
|
|
|
|
int ret = -1;
|
|
|
|
char *path;
|
|
|
|
|
|
|
|
switch (dev->source.caps.type) {
|
|
|
|
case VIR_DOMAIN_HOSTDEV_CAPS_TYPE_STORAGE: {
|
|
|
|
if (vroot) {
|
|
|
|
if (virAsprintf(&path, "%s/%s", vroot,
|
|
|
|
dev->source.caps.u.storage.block) < 0) {
|
|
|
|
virReportOOMError();
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
if (!(path = strdup(dev->source.caps.u.storage.block))) {
|
|
|
|
virReportOOMError();
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
ret = virSecuritySELinuxRestoreSecurityFileLabel(path);
|
|
|
|
VIR_FREE(path);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
case VIR_DOMAIN_HOSTDEV_CAPS_TYPE_MISC: {
|
|
|
|
if (vroot) {
|
|
|
|
if (virAsprintf(&path, "%s/%s", vroot,
|
|
|
|
dev->source.caps.u.misc.chardev) < 0) {
|
|
|
|
virReportOOMError();
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
if (!(path = strdup(dev->source.caps.u.misc.chardev))) {
|
|
|
|
virReportOOMError();
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
ret = virSecuritySELinuxRestoreSecurityFileLabel(path);
|
|
|
|
VIR_FREE(path);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
default:
|
|
|
|
ret = 0;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2012-11-28 15:54:56 +00:00
|
|
|
static int
|
|
|
|
virSecuritySELinuxRestoreSecurityHostdevLabel(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
|
|
|
|
virDomainDefPtr def,
|
|
|
|
virDomainHostdevDefPtr dev,
|
|
|
|
const char *vroot)
|
|
|
|
|
|
|
|
{
|
|
|
|
virSecurityLabelDefPtr secdef;
|
|
|
|
|
|
|
|
secdef = virDomainDefGetSecurityLabelDef(def, SECURITY_SELINUX_NAME);
|
|
|
|
if (secdef == NULL)
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
if (secdef->norelabel)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
switch (dev->mode) {
|
|
|
|
case VIR_DOMAIN_HOSTDEV_MODE_SUBSYS:
|
|
|
|
return virSecuritySELinuxRestoreSecurityHostdevSubsysLabel(dev, vroot);
|
|
|
|
|
2012-11-28 16:07:27 +00:00
|
|
|
case VIR_DOMAIN_HOSTDEV_MODE_CAPABILITIES:
|
|
|
|
return virSecuritySELinuxRestoreSecurityHostdevCapsLabel(dev, vroot);
|
|
|
|
|
2012-11-28 15:54:56 +00:00
|
|
|
default:
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2010-06-23 16:17:15 +01:00
|
|
|
static int
|
2012-05-24 16:42:51 +01:00
|
|
|
virSecuritySELinuxSetSecurityChardevLabel(virDomainDefPtr def,
|
2012-09-20 14:16:17 +01:00
|
|
|
virDomainChrDefPtr dev,
|
|
|
|
virDomainChrSourceDefPtr dev_source)
|
2010-06-23 16:17:15 +01:00
|
|
|
|
|
|
|
{
|
2012-09-20 14:16:17 +01:00
|
|
|
virSecurityLabelDefPtr seclabel;
|
|
|
|
virSecurityDeviceLabelDefPtr chr_seclabel = NULL;
|
|
|
|
char *imagelabel = NULL;
|
2010-06-23 16:17:15 +01:00
|
|
|
char *in = NULL, *out = NULL;
|
|
|
|
int ret = -1;
|
|
|
|
|
2012-09-20 14:16:17 +01:00
|
|
|
seclabel = virDomainDefGetSecurityLabelDef(def, SECURITY_SELINUX_NAME);
|
|
|
|
if (seclabel == NULL)
|
2012-08-15 19:10:37 -03:00
|
|
|
return -1;
|
|
|
|
|
2012-09-20 14:16:17 +01:00
|
|
|
if (dev)
|
|
|
|
chr_seclabel = virDomainChrDefGetSecurityLabelDef(dev,
|
|
|
|
SECURITY_SELINUX_NAME);
|
|
|
|
|
|
|
|
if (seclabel->norelabel || (chr_seclabel && chr_seclabel->norelabel))
|
2010-06-23 16:17:15 +01:00
|
|
|
return 0;
|
|
|
|
|
2012-09-20 14:16:17 +01:00
|
|
|
if (chr_seclabel)
|
|
|
|
imagelabel = chr_seclabel->label;
|
|
|
|
if (!imagelabel)
|
|
|
|
imagelabel = seclabel->imagelabel;
|
|
|
|
|
|
|
|
switch (dev_source->type) {
|
2010-06-23 16:17:15 +01:00
|
|
|
case VIR_DOMAIN_CHR_TYPE_DEV:
|
|
|
|
case VIR_DOMAIN_CHR_TYPE_FILE:
|
2012-09-20 14:16:17 +01:00
|
|
|
ret = virSecuritySELinuxSetFilecon(dev_source->data.file.path,
|
|
|
|
imagelabel);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case VIR_DOMAIN_CHR_TYPE_UNIX:
|
|
|
|
if (!dev_source->data.nix.listen) {
|
|
|
|
if (virSecuritySELinuxSetFilecon(dev_source->data.file.path,
|
|
|
|
imagelabel) < 0)
|
|
|
|
goto done;
|
|
|
|
}
|
|
|
|
ret = 0;
|
2010-06-23 16:17:15 +01:00
|
|
|
break;
|
|
|
|
|
|
|
|
case VIR_DOMAIN_CHR_TYPE_PIPE:
|
2012-09-20 14:16:17 +01:00
|
|
|
if ((virAsprintf(&in, "%s.in", dev_source->data.file.path) < 0) ||
|
|
|
|
(virAsprintf(&out, "%s.out", dev_source->data.file.path) < 0)) {
|
2011-09-27 14:04:53 -04:00
|
|
|
virReportOOMError();
|
|
|
|
goto done;
|
|
|
|
}
|
|
|
|
if (virFileExists(in) && virFileExists(out)) {
|
2012-09-20 14:16:17 +01:00
|
|
|
if ((virSecuritySELinuxSetFilecon(in, imagelabel) < 0) ||
|
|
|
|
(virSecuritySELinuxSetFilecon(out, imagelabel) < 0)) {
|
2011-03-29 15:46:48 +01:00
|
|
|
goto done;
|
2011-09-27 14:04:53 -04:00
|
|
|
}
|
2012-09-20 14:16:17 +01:00
|
|
|
} else if (virSecuritySELinuxSetFilecon(dev_source->data.file.path,
|
|
|
|
imagelabel) < 0) {
|
2011-09-27 14:04:53 -04:00
|
|
|
goto done;
|
2010-06-23 16:17:15 +01:00
|
|
|
}
|
|
|
|
ret = 0;
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
ret = 0;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
done:
|
|
|
|
VIR_FREE(in);
|
|
|
|
VIR_FREE(out);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
2012-05-24 16:42:51 +01:00
|
|
|
virSecuritySELinuxRestoreSecurityChardevLabel(virDomainDefPtr def,
|
2012-09-20 14:16:17 +01:00
|
|
|
virDomainChrDefPtr dev,
|
|
|
|
virDomainChrSourceDefPtr dev_source)
|
2010-06-23 16:17:15 +01:00
|
|
|
|
|
|
|
{
|
2012-09-20 14:16:17 +01:00
|
|
|
virSecurityLabelDefPtr seclabel;
|
|
|
|
virSecurityDeviceLabelDefPtr chr_seclabel = NULL;
|
2010-06-23 16:17:15 +01:00
|
|
|
char *in = NULL, *out = NULL;
|
|
|
|
int ret = -1;
|
|
|
|
|
2012-09-20 14:16:17 +01:00
|
|
|
seclabel = virDomainDefGetSecurityLabelDef(def, SECURITY_SELINUX_NAME);
|
|
|
|
if (seclabel == NULL)
|
2012-08-15 19:10:37 -03:00
|
|
|
return -1;
|
|
|
|
|
2012-09-20 14:16:17 +01:00
|
|
|
if (dev)
|
|
|
|
chr_seclabel = virDomainChrDefGetSecurityLabelDef(dev,
|
|
|
|
SECURITY_SELINUX_NAME);
|
|
|
|
if (seclabel->norelabel || (chr_seclabel && chr_seclabel->norelabel))
|
2010-06-23 16:17:15 +01:00
|
|
|
return 0;
|
|
|
|
|
2012-09-20 14:16:17 +01:00
|
|
|
switch (dev_source->type) {
|
2010-06-23 16:17:15 +01:00
|
|
|
case VIR_DOMAIN_CHR_TYPE_DEV:
|
|
|
|
case VIR_DOMAIN_CHR_TYPE_FILE:
|
2012-09-20 14:16:17 +01:00
|
|
|
if (virSecuritySELinuxRestoreSecurityFileLabel(dev_source->data.file.path) < 0)
|
2010-11-18 17:55:14 +01:00
|
|
|
goto done;
|
|
|
|
ret = 0;
|
2010-06-23 16:17:15 +01:00
|
|
|
break;
|
2012-09-20 14:16:17 +01:00
|
|
|
|
|
|
|
case VIR_DOMAIN_CHR_TYPE_UNIX:
|
|
|
|
if (!dev_source->data.nix.listen) {
|
|
|
|
if (virSecuritySELinuxRestoreSecurityFileLabel(dev_source->data.file.path) < 0)
|
|
|
|
goto done;
|
|
|
|
}
|
|
|
|
ret = 0;
|
|
|
|
break;
|
|
|
|
|
2010-06-23 16:17:15 +01:00
|
|
|
case VIR_DOMAIN_CHR_TYPE_PIPE:
|
2012-09-20 14:16:17 +01:00
|
|
|
if ((virAsprintf(&out, "%s.out", dev_source->data.file.path) < 0) ||
|
|
|
|
(virAsprintf(&in, "%s.in", dev_source->data.file.path) < 0)) {
|
2010-06-23 16:17:15 +01:00
|
|
|
virReportOOMError();
|
|
|
|
goto done;
|
|
|
|
}
|
2011-09-27 14:04:53 -04:00
|
|
|
if (virFileExists(in) && virFileExists(out)) {
|
2012-05-24 16:42:51 +01:00
|
|
|
if ((virSecuritySELinuxRestoreSecurityFileLabel(out) < 0) ||
|
|
|
|
(virSecuritySELinuxRestoreSecurityFileLabel(in) < 0)) {
|
2011-09-27 14:04:53 -04:00
|
|
|
goto done;
|
|
|
|
}
|
2012-09-20 14:16:17 +01:00
|
|
|
} else if (virSecuritySELinuxRestoreSecurityFileLabel(dev_source->data.file.path) < 0) {
|
2010-06-23 16:17:15 +01:00
|
|
|
goto done;
|
2011-09-27 14:04:53 -04:00
|
|
|
}
|
2010-06-23 16:17:15 +01:00
|
|
|
ret = 0;
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
ret = 0;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
done:
|
|
|
|
VIR_FREE(in);
|
|
|
|
VIR_FREE(out);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static int
|
2012-05-24 16:42:51 +01:00
|
|
|
virSecuritySELinuxRestoreSecurityChardevCallback(virDomainDefPtr def,
|
|
|
|
virDomainChrDefPtr dev,
|
|
|
|
void *opaque ATTRIBUTE_UNUSED)
|
2010-06-23 16:17:15 +01:00
|
|
|
{
|
Allow multiple consoles per virtual guest
While Xen only has a single paravirt console, UML, and
QEMU both support multiple paravirt consoles. The LXC
driver can also be trivially made to support multiple
consoles. This patch extends the XML to allow multiple
<console> elements in the XML. It also makes the UML
and QEMU drivers support this config.
* src/conf/domain_conf.c, src/conf/domain_conf.h: Allow
multiple <console> devices
* src/lxc/lxc_driver.c, src/xen/xen_driver.c,
src/xenxs/xen_sxpr.c, src/xenxs/xen_xm.c: Update for
internal API changes
* src/security/security_selinux.c, src/security/virt-aa-helper.c:
Only label consoles that aren't a copy of the serial device
* src/qemu/qemu_command.c, src/qemu/qemu_driver.c,
src/qemu/qemu_process.c, src/uml/uml_conf.c,
src/uml/uml_driver.c: Support multiple console devices
* tests/qemuxml2xmltest.c, tests/qemuxml2argvtest.c: Extra
tests for multiple virtio consoles. Set QEMU_CAPS_CHARDEV
for all console /channel tests
* tests/qemuxml2argvdata/qemuxml2argv-channel-virtio-auto.args,
tests/qemuxml2argvdata/qemuxml2argv-channel-virtio.args
tests/qemuxml2argvdata/qemuxml2argv-console-virtio.args: Update
for correct chardev syntax
* tests/qemuxml2argvdata/qemuxml2argv-console-virtio-many.args,
tests/qemuxml2argvdata/qemuxml2argv-console-virtio-many.xml: New
test file
2011-02-23 18:27:23 +00:00
|
|
|
/* This is taken care of by processing of def->serials */
|
|
|
|
if (dev->deviceType == VIR_DOMAIN_CHR_DEVICE_TYPE_CONSOLE &&
|
|
|
|
dev->targetType == VIR_DOMAIN_CHR_CONSOLE_TARGET_TYPE_SERIAL)
|
|
|
|
return 0;
|
|
|
|
|
2012-09-20 14:16:17 +01:00
|
|
|
return virSecuritySELinuxRestoreSecurityChardevLabel(def, dev,
|
|
|
|
&dev->source);
|
2010-06-23 16:17:15 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2011-01-14 12:17:17 -07:00
|
|
|
static int
|
2012-05-24 16:42:51 +01:00
|
|
|
virSecuritySELinuxRestoreSecuritySmartcardCallback(virDomainDefPtr def,
|
|
|
|
virDomainSmartcardDefPtr dev,
|
|
|
|
void *opaque ATTRIBUTE_UNUSED)
|
2011-01-14 12:17:17 -07:00
|
|
|
{
|
|
|
|
const char *database;
|
|
|
|
|
|
|
|
switch (dev->type) {
|
|
|
|
case VIR_DOMAIN_SMARTCARD_TYPE_HOST:
|
|
|
|
break;
|
|
|
|
|
|
|
|
case VIR_DOMAIN_SMARTCARD_TYPE_HOST_CERTIFICATES:
|
|
|
|
database = dev->data.cert.database;
|
|
|
|
if (!database)
|
|
|
|
database = VIR_DOMAIN_SMARTCARD_DEFAULT_DATABASE;
|
2012-05-24 16:42:51 +01:00
|
|
|
return virSecuritySELinuxRestoreSecurityFileLabel(database);
|
2011-01-14 12:17:17 -07:00
|
|
|
|
|
|
|
case VIR_DOMAIN_SMARTCARD_TYPE_PASSTHROUGH:
|
2012-09-20 14:16:17 +01:00
|
|
|
return virSecuritySELinuxRestoreSecurityChardevLabel(def, NULL, &dev->data.passthru);
|
2011-01-14 12:17:17 -07:00
|
|
|
|
|
|
|
default:
|
2012-07-18 15:39:18 +01:00
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
|
_("unknown smartcard type %d"),
|
|
|
|
dev->type);
|
2011-01-14 12:17:17 -07:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2009-03-03 10:06:49 +00:00
|
|
|
static int
|
2012-11-28 13:54:39 +00:00
|
|
|
virSecuritySELinuxRestoreSecurityAllLabel(virSecurityManagerPtr mgr,
|
2012-05-24 16:42:51 +01:00
|
|
|
virDomainDefPtr def,
|
|
|
|
int migrated ATTRIBUTE_UNUSED)
|
2009-03-03 10:06:49 +00:00
|
|
|
{
|
2012-08-15 19:10:37 -03:00
|
|
|
virSecurityLabelDefPtr secdef;
|
2012-11-28 13:54:39 +00:00
|
|
|
virSecuritySELinuxDataPtr data = virSecurityManagerGetPrivateData(mgr);
|
2009-03-03 10:06:49 +00:00
|
|
|
int i;
|
|
|
|
int rc = 0;
|
2009-08-28 18:44:43 +01:00
|
|
|
|
Change security driver APIs to use virDomainDefPtr instead of virDomainObjPtr
When sVirt is integrated with the LXC driver, it will be neccessary
to invoke the security driver APIs using only a virDomainDefPtr
since the lxc_container.c code has no virDomainObjPtr available.
Aside from two functions which want obj->pid, every bit of the
security driver code only touches obj->def. So we don't need to
pass a virDomainObjPtr into the security drivers, a virDomainDefPtr
is sufficient. Two functions also gain a 'pid_t pid' argument.
* src/qemu/qemu_driver.c, src/qemu/qemu_hotplug.c,
src/qemu/qemu_migration.c, src/qemu/qemu_process.c,
src/security/security_apparmor.c,
src/security/security_dac.c,
src/security/security_driver.h,
src/security/security_manager.c,
src/security/security_manager.h,
src/security/security_nop.c,
src/security/security_selinux.c,
src/security/security_stack.c: Change all security APIs to use a
virDomainDefPtr instead of virDomainObjPtr
2011-07-14 14:32:06 +01:00
|
|
|
VIR_DEBUG("Restoring security label on %s", def->name);
|
2009-08-28 18:44:43 +01:00
|
|
|
|
2012-08-15 19:10:37 -03:00
|
|
|
secdef = virDomainDefGetSecurityLabelDef(def, SECURITY_SELINUX_NAME);
|
|
|
|
if (secdef == NULL)
|
|
|
|
return -1;
|
|
|
|
|
2012-11-28 13:54:39 +00:00
|
|
|
if (secdef->norelabel || data->skipAllLabel)
|
2010-01-13 14:03:04 +00:00
|
|
|
return 0;
|
|
|
|
|
Change security driver APIs to use virDomainDefPtr instead of virDomainObjPtr
When sVirt is integrated with the LXC driver, it will be neccessary
to invoke the security driver APIs using only a virDomainDefPtr
since the lxc_container.c code has no virDomainObjPtr available.
Aside from two functions which want obj->pid, every bit of the
security driver code only touches obj->def. So we don't need to
pass a virDomainObjPtr into the security drivers, a virDomainDefPtr
is sufficient. Two functions also gain a 'pid_t pid' argument.
* src/qemu/qemu_driver.c, src/qemu/qemu_hotplug.c,
src/qemu/qemu_migration.c, src/qemu/qemu_process.c,
src/security/security_apparmor.c,
src/security/security_dac.c,
src/security/security_driver.h,
src/security/security_manager.c,
src/security/security_manager.h,
src/security/security_nop.c,
src/security/security_selinux.c,
src/security/security_stack.c: Change all security APIs to use a
virDomainDefPtr instead of virDomainObjPtr
2011-07-14 14:32:06 +01:00
|
|
|
for (i = 0 ; i < def->nhostdevs ; i++) {
|
2012-05-24 16:42:51 +01:00
|
|
|
if (virSecuritySELinuxRestoreSecurityHostdevLabel(mgr,
|
|
|
|
def,
|
2012-11-27 16:17:47 +00:00
|
|
|
def->hostdevs[i],
|
|
|
|
NULL) < 0)
|
2010-01-13 14:03:04 +00:00
|
|
|
rc = -1;
|
2009-03-03 10:06:49 +00:00
|
|
|
}
|
Change security driver APIs to use virDomainDefPtr instead of virDomainObjPtr
When sVirt is integrated with the LXC driver, it will be neccessary
to invoke the security driver APIs using only a virDomainDefPtr
since the lxc_container.c code has no virDomainObjPtr available.
Aside from two functions which want obj->pid, every bit of the
security driver code only touches obj->def. So we don't need to
pass a virDomainObjPtr into the security drivers, a virDomainDefPtr
is sufficient. Two functions also gain a 'pid_t pid' argument.
* src/qemu/qemu_driver.c, src/qemu/qemu_hotplug.c,
src/qemu/qemu_migration.c, src/qemu/qemu_process.c,
src/security/security_apparmor.c,
src/security/security_dac.c,
src/security/security_driver.h,
src/security/security_manager.c,
src/security/security_manager.h,
src/security/security_nop.c,
src/security/security_selinux.c,
src/security/security_stack.c: Change all security APIs to use a
virDomainDefPtr instead of virDomainObjPtr
2011-07-14 14:32:06 +01:00
|
|
|
for (i = 0 ; i < def->ndisks ; i++) {
|
2012-05-24 16:42:51 +01:00
|
|
|
if (virSecuritySELinuxRestoreSecurityImageLabelInt(mgr,
|
|
|
|
def,
|
|
|
|
def->disks[i],
|
|
|
|
migrated) < 0)
|
2010-01-13 14:03:04 +00:00
|
|
|
rc = -1;
|
|
|
|
}
|
2010-01-11 11:04:40 +00:00
|
|
|
|
Change security driver APIs to use virDomainDefPtr instead of virDomainObjPtr
When sVirt is integrated with the LXC driver, it will be neccessary
to invoke the security driver APIs using only a virDomainDefPtr
since the lxc_container.c code has no virDomainObjPtr available.
Aside from two functions which want obj->pid, every bit of the
security driver code only touches obj->def. So we don't need to
pass a virDomainObjPtr into the security drivers, a virDomainDefPtr
is sufficient. Two functions also gain a 'pid_t pid' argument.
* src/qemu/qemu_driver.c, src/qemu/qemu_hotplug.c,
src/qemu/qemu_migration.c, src/qemu/qemu_process.c,
src/security/security_apparmor.c,
src/security/security_dac.c,
src/security/security_driver.h,
src/security/security_manager.c,
src/security/security_manager.h,
src/security/security_nop.c,
src/security/security_selinux.c,
src/security/security_stack.c: Change all security APIs to use a
virDomainDefPtr instead of virDomainObjPtr
2011-07-14 14:32:06 +01:00
|
|
|
if (virDomainChrDefForeach(def,
|
2010-06-23 16:17:15 +01:00
|
|
|
false,
|
2012-05-24 16:42:51 +01:00
|
|
|
virSecuritySELinuxRestoreSecurityChardevCallback,
|
Change security driver APIs to use virDomainDefPtr instead of virDomainObjPtr
When sVirt is integrated with the LXC driver, it will be neccessary
to invoke the security driver APIs using only a virDomainDefPtr
since the lxc_container.c code has no virDomainObjPtr available.
Aside from two functions which want obj->pid, every bit of the
security driver code only touches obj->def. So we don't need to
pass a virDomainObjPtr into the security drivers, a virDomainDefPtr
is sufficient. Two functions also gain a 'pid_t pid' argument.
* src/qemu/qemu_driver.c, src/qemu/qemu_hotplug.c,
src/qemu/qemu_migration.c, src/qemu/qemu_process.c,
src/security/security_apparmor.c,
src/security/security_dac.c,
src/security/security_driver.h,
src/security/security_manager.c,
src/security/security_manager.h,
src/security/security_nop.c,
src/security/security_selinux.c,
src/security/security_stack.c: Change all security APIs to use a
virDomainDefPtr instead of virDomainObjPtr
2011-07-14 14:32:06 +01:00
|
|
|
NULL) < 0)
|
2010-06-23 16:17:15 +01:00
|
|
|
rc = -1;
|
|
|
|
|
Change security driver APIs to use virDomainDefPtr instead of virDomainObjPtr
When sVirt is integrated with the LXC driver, it will be neccessary
to invoke the security driver APIs using only a virDomainDefPtr
since the lxc_container.c code has no virDomainObjPtr available.
Aside from two functions which want obj->pid, every bit of the
security driver code only touches obj->def. So we don't need to
pass a virDomainObjPtr into the security drivers, a virDomainDefPtr
is sufficient. Two functions also gain a 'pid_t pid' argument.
* src/qemu/qemu_driver.c, src/qemu/qemu_hotplug.c,
src/qemu/qemu_migration.c, src/qemu/qemu_process.c,
src/security/security_apparmor.c,
src/security/security_dac.c,
src/security/security_driver.h,
src/security/security_manager.c,
src/security/security_manager.h,
src/security/security_nop.c,
src/security/security_selinux.c,
src/security/security_stack.c: Change all security APIs to use a
virDomainDefPtr instead of virDomainObjPtr
2011-07-14 14:32:06 +01:00
|
|
|
if (virDomainSmartcardDefForeach(def,
|
2011-01-14 12:17:17 -07:00
|
|
|
false,
|
2012-05-24 16:42:51 +01:00
|
|
|
virSecuritySELinuxRestoreSecuritySmartcardCallback,
|
Change security driver APIs to use virDomainDefPtr instead of virDomainObjPtr
When sVirt is integrated with the LXC driver, it will be neccessary
to invoke the security driver APIs using only a virDomainDefPtr
since the lxc_container.c code has no virDomainObjPtr available.
Aside from two functions which want obj->pid, every bit of the
security driver code only touches obj->def. So we don't need to
pass a virDomainObjPtr into the security drivers, a virDomainDefPtr
is sufficient. Two functions also gain a 'pid_t pid' argument.
* src/qemu/qemu_driver.c, src/qemu/qemu_hotplug.c,
src/qemu/qemu_migration.c, src/qemu/qemu_process.c,
src/security/security_apparmor.c,
src/security/security_dac.c,
src/security/security_driver.h,
src/security/security_manager.c,
src/security/security_manager.h,
src/security/security_nop.c,
src/security/security_selinux.c,
src/security/security_stack.c: Change all security APIs to use a
virDomainDefPtr instead of virDomainObjPtr
2011-07-14 14:32:06 +01:00
|
|
|
NULL) < 0)
|
2011-01-14 12:17:17 -07:00
|
|
|
rc = -1;
|
|
|
|
|
Change security driver APIs to use virDomainDefPtr instead of virDomainObjPtr
When sVirt is integrated with the LXC driver, it will be neccessary
to invoke the security driver APIs using only a virDomainDefPtr
since the lxc_container.c code has no virDomainObjPtr available.
Aside from two functions which want obj->pid, every bit of the
security driver code only touches obj->def. So we don't need to
pass a virDomainObjPtr into the security drivers, a virDomainDefPtr
is sufficient. Two functions also gain a 'pid_t pid' argument.
* src/qemu/qemu_driver.c, src/qemu/qemu_hotplug.c,
src/qemu/qemu_migration.c, src/qemu/qemu_process.c,
src/security/security_apparmor.c,
src/security/security_dac.c,
src/security/security_driver.h,
src/security/security_manager.c,
src/security/security_manager.h,
src/security/security_nop.c,
src/security/security_selinux.c,
src/security/security_stack.c: Change all security APIs to use a
virDomainDefPtr instead of virDomainObjPtr
2011-07-14 14:32:06 +01:00
|
|
|
if (def->os.kernel &&
|
2012-05-24 16:42:51 +01:00
|
|
|
virSecuritySELinuxRestoreSecurityFileLabel(def->os.kernel) < 0)
|
2010-03-12 13:38:39 -05:00
|
|
|
rc = -1;
|
|
|
|
|
Change security driver APIs to use virDomainDefPtr instead of virDomainObjPtr
When sVirt is integrated with the LXC driver, it will be neccessary
to invoke the security driver APIs using only a virDomainDefPtr
since the lxc_container.c code has no virDomainObjPtr available.
Aside from two functions which want obj->pid, every bit of the
security driver code only touches obj->def. So we don't need to
pass a virDomainObjPtr into the security drivers, a virDomainDefPtr
is sufficient. Two functions also gain a 'pid_t pid' argument.
* src/qemu/qemu_driver.c, src/qemu/qemu_hotplug.c,
src/qemu/qemu_migration.c, src/qemu/qemu_process.c,
src/security/security_apparmor.c,
src/security/security_dac.c,
src/security/security_driver.h,
src/security/security_manager.c,
src/security/security_manager.h,
src/security/security_nop.c,
src/security/security_selinux.c,
src/security/security_stack.c: Change all security APIs to use a
virDomainDefPtr instead of virDomainObjPtr
2011-07-14 14:32:06 +01:00
|
|
|
if (def->os.initrd &&
|
2012-05-24 16:42:51 +01:00
|
|
|
virSecuritySELinuxRestoreSecurityFileLabel(def->os.initrd) < 0)
|
2010-03-12 13:38:39 -05:00
|
|
|
rc = -1;
|
|
|
|
|
2010-01-11 11:04:40 +00:00
|
|
|
return rc;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
2012-05-24 17:22:29 +01:00
|
|
|
virSecuritySELinuxReleaseSecurityLabel(virSecurityManagerPtr mgr,
|
2012-05-24 16:42:51 +01:00
|
|
|
virDomainDefPtr def)
|
2010-01-11 11:04:40 +00:00
|
|
|
{
|
2012-08-15 19:10:37 -03:00
|
|
|
virSecurityLabelDefPtr secdef;
|
|
|
|
|
|
|
|
secdef = virDomainDefGetSecurityLabelDef(def, SECURITY_SELINUX_NAME);
|
|
|
|
if (secdef == NULL)
|
|
|
|
return -1;
|
2010-01-11 11:04:40 +00:00
|
|
|
|
2011-06-24 10:21:33 +01:00
|
|
|
if (secdef->type == VIR_DOMAIN_SECLABEL_DYNAMIC) {
|
|
|
|
if (secdef->label != NULL) {
|
|
|
|
context_t con = context_new(secdef->label);
|
|
|
|
if (con) {
|
2012-05-24 17:22:29 +01:00
|
|
|
virSecuritySELinuxMCSRemove(mgr, context_range_get(con));
|
2011-06-24 10:21:33 +01:00
|
|
|
context_free(con);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
VIR_FREE(secdef->label);
|
|
|
|
if (!secdef->baselabel)
|
|
|
|
VIR_FREE(secdef->model);
|
2010-01-13 14:03:04 +00:00
|
|
|
}
|
|
|
|
VIR_FREE(secdef->imagelabel);
|
|
|
|
|
2010-01-11 11:04:40 +00:00
|
|
|
return 0;
|
2009-03-03 10:06:49 +00:00
|
|
|
}
|
|
|
|
|
2009-11-11 12:07:00 +00:00
|
|
|
|
|
|
|
static int
|
2012-05-24 16:42:51 +01:00
|
|
|
virSecuritySELinuxSetSavedStateLabel(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
|
|
|
|
virDomainDefPtr def,
|
|
|
|
const char *savefile)
|
2009-11-11 12:07:00 +00:00
|
|
|
{
|
2012-08-15 19:10:37 -03:00
|
|
|
virSecurityLabelDefPtr secdef;
|
|
|
|
|
|
|
|
secdef = virDomainDefGetSecurityLabelDef(def, SECURITY_SELINUX_NAME);
|
|
|
|
if (secdef == NULL)
|
|
|
|
return -1;
|
2009-11-11 12:07:00 +00:00
|
|
|
|
2011-07-05 10:49:51 +01:00
|
|
|
if (secdef->norelabel)
|
2010-01-13 14:03:04 +00:00
|
|
|
return 0;
|
|
|
|
|
2012-05-24 16:42:51 +01:00
|
|
|
return virSecuritySELinuxSetFilecon(savefile, secdef->imagelabel);
|
2009-11-11 12:07:00 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static int
|
2012-05-24 16:42:51 +01:00
|
|
|
virSecuritySELinuxRestoreSavedStateLabel(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
|
|
|
|
virDomainDefPtr def,
|
|
|
|
const char *savefile)
|
2009-11-11 12:07:00 +00:00
|
|
|
{
|
2012-08-15 19:10:37 -03:00
|
|
|
virSecurityLabelDefPtr secdef;
|
|
|
|
|
|
|
|
secdef = virDomainDefGetSecurityLabelDef(def, SECURITY_SELINUX_NAME);
|
|
|
|
if (secdef == NULL)
|
|
|
|
return -1;
|
2010-01-13 14:03:04 +00:00
|
|
|
|
2011-07-05 10:49:51 +01:00
|
|
|
if (secdef->norelabel)
|
2010-01-13 14:03:04 +00:00
|
|
|
return 0;
|
|
|
|
|
2012-05-24 16:42:51 +01:00
|
|
|
return virSecuritySELinuxRestoreSecurityFileLabel(savefile);
|
2009-11-11 12:07:00 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2009-04-03 10:55:51 +00:00
|
|
|
static int
|
2012-05-24 16:42:51 +01:00
|
|
|
virSecuritySELinuxSecurityVerify(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
|
|
|
|
virDomainDefPtr def)
|
2009-04-03 10:55:51 +00:00
|
|
|
{
|
2012-08-15 19:10:37 -03:00
|
|
|
virSecurityLabelDefPtr secdef;
|
|
|
|
|
|
|
|
secdef = virDomainDefGetSecurityLabelDef(def, SECURITY_SELINUX_NAME);
|
|
|
|
if (secdef == NULL)
|
|
|
|
return -1;
|
|
|
|
|
Refactor the security drivers to simplify usage
The current security driver usage requires horrible code like
if (driver->securityDriver &&
driver->securityDriver->domainSetSecurityHostdevLabel &&
driver->securityDriver->domainSetSecurityHostdevLabel(driver->securityDriver,
vm, hostdev) < 0)
This pair of checks for NULL clutters up the code, making the driver
calls 2 lines longer than they really need to be. The goal of the
patchset is to change the calling convention to simply
if (virSecurityManagerSetHostdevLabel(driver->securityDriver,
vm, hostdev) < 0)
The first check for 'driver->securityDriver' being NULL is removed
by introducing a 'no op' security driver that will always be present
if no real driver is enabled. This guarentees driver->securityDriver
!= NULL.
The second check for 'driver->securityDriver->domainSetSecurityHostdevLabel'
being non-NULL is hidden in a new abstraction called virSecurityManager.
This separates the driver callbacks, from main internal API. The addition
of a virSecurityManager object, that is separate from the virSecurityDriver
struct also allows for security drivers to carry state / configuration
information directly. Thus the DAC/Stack drivers from src/qemu which
used to pull config from 'struct qemud_driver' can now be moved into
the 'src/security' directory and store their config directly.
* src/qemu/qemu_conf.h, src/qemu/qemu_driver.c: Update to
use new virSecurityManager APIs
* src/qemu/qemu_security_dac.c, src/qemu/qemu_security_dac.h
src/qemu/qemu_security_stacked.c, src/qemu/qemu_security_stacked.h:
Move into src/security directory
* src/security/security_stack.c, src/security/security_stack.h,
src/security/security_dac.c, src/security/security_dac.h: Generic
versions of previous QEMU specific drivers
* src/security/security_apparmor.c, src/security/security_apparmor.h,
src/security/security_driver.c, src/security/security_driver.h,
src/security/security_selinux.c, src/security/security_selinux.h:
Update to take virSecurityManagerPtr object as the first param
in all callbacks
* src/security/security_nop.c, src/security/security_nop.h: Stub
implementation of all security driver APIs.
* src/security/security_manager.h, src/security/security_manager.c:
New internal API for invoking security drivers
* src/libvirt.c: Add missing debug for security APIs
2010-11-17 20:26:30 +00:00
|
|
|
if (!STREQ(virSecurityManagerGetModel(mgr), secdef->model)) {
|
2012-07-18 15:39:18 +01:00
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
|
_("security label driver mismatch: "
|
|
|
|
"'%s' model configured for domain, but "
|
|
|
|
"hypervisor driver is '%s'."),
|
|
|
|
secdef->model, virSecurityManagerGetModel(mgr));
|
Refactor the security drivers to simplify usage
The current security driver usage requires horrible code like
if (driver->securityDriver &&
driver->securityDriver->domainSetSecurityHostdevLabel &&
driver->securityDriver->domainSetSecurityHostdevLabel(driver->securityDriver,
vm, hostdev) < 0)
This pair of checks for NULL clutters up the code, making the driver
calls 2 lines longer than they really need to be. The goal of the
patchset is to change the calling convention to simply
if (virSecurityManagerSetHostdevLabel(driver->securityDriver,
vm, hostdev) < 0)
The first check for 'driver->securityDriver' being NULL is removed
by introducing a 'no op' security driver that will always be present
if no real driver is enabled. This guarentees driver->securityDriver
!= NULL.
The second check for 'driver->securityDriver->domainSetSecurityHostdevLabel'
being non-NULL is hidden in a new abstraction called virSecurityManager.
This separates the driver callbacks, from main internal API. The addition
of a virSecurityManager object, that is separate from the virSecurityDriver
struct also allows for security drivers to carry state / configuration
information directly. Thus the DAC/Stack drivers from src/qemu which
used to pull config from 'struct qemud_driver' can now be moved into
the 'src/security' directory and store their config directly.
* src/qemu/qemu_conf.h, src/qemu/qemu_driver.c: Update to
use new virSecurityManager APIs
* src/qemu/qemu_security_dac.c, src/qemu/qemu_security_dac.h
src/qemu/qemu_security_stacked.c, src/qemu/qemu_security_stacked.h:
Move into src/security directory
* src/security/security_stack.c, src/security/security_stack.h,
src/security/security_dac.c, src/security/security_dac.h: Generic
versions of previous QEMU specific drivers
* src/security/security_apparmor.c, src/security/security_apparmor.h,
src/security/security_driver.c, src/security/security_driver.h,
src/security/security_selinux.c, src/security/security_selinux.h:
Update to take virSecurityManagerPtr object as the first param
in all callbacks
* src/security/security_nop.c, src/security/security_nop.h: Stub
implementation of all security driver APIs.
* src/security/security_manager.h, src/security/security_manager.c:
New internal API for invoking security drivers
* src/libvirt.c: Add missing debug for security APIs
2010-11-17 20:26:30 +00:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2009-04-03 10:55:51 +00:00
|
|
|
if (secdef->type == VIR_DOMAIN_SECLABEL_STATIC) {
|
|
|
|
if (security_check_context(secdef->label) != 0) {
|
2012-07-18 15:39:18 +01:00
|
|
|
virReportError(VIR_ERR_XML_ERROR,
|
|
|
|
_("Invalid security label %s"), secdef->label);
|
2009-04-03 10:55:51 +00:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2009-03-03 10:06:49 +00:00
|
|
|
static int
|
2012-05-24 16:42:51 +01:00
|
|
|
virSecuritySELinuxSetSecurityProcessLabel(virSecurityManagerPtr mgr,
|
|
|
|
virDomainDefPtr def)
|
2009-03-03 10:06:49 +00:00
|
|
|
{
|
|
|
|
/* TODO: verify DOI */
|
2012-08-15 19:10:37 -03:00
|
|
|
virSecurityLabelDefPtr secdef;
|
|
|
|
|
|
|
|
secdef = virDomainDefGetSecurityLabelDef(def, SECURITY_SELINUX_NAME);
|
|
|
|
if (secdef == NULL)
|
|
|
|
return -1;
|
2009-03-03 10:06:49 +00:00
|
|
|
|
2012-08-15 19:10:37 -03:00
|
|
|
if (secdef->label == NULL)
|
2010-01-13 14:03:04 +00:00
|
|
|
return 0;
|
|
|
|
|
2012-08-15 19:10:37 -03:00
|
|
|
VIR_DEBUG("label=%s", secdef->label);
|
Refactor the security drivers to simplify usage
The current security driver usage requires horrible code like
if (driver->securityDriver &&
driver->securityDriver->domainSetSecurityHostdevLabel &&
driver->securityDriver->domainSetSecurityHostdevLabel(driver->securityDriver,
vm, hostdev) < 0)
This pair of checks for NULL clutters up the code, making the driver
calls 2 lines longer than they really need to be. The goal of the
patchset is to change the calling convention to simply
if (virSecurityManagerSetHostdevLabel(driver->securityDriver,
vm, hostdev) < 0)
The first check for 'driver->securityDriver' being NULL is removed
by introducing a 'no op' security driver that will always be present
if no real driver is enabled. This guarentees driver->securityDriver
!= NULL.
The second check for 'driver->securityDriver->domainSetSecurityHostdevLabel'
being non-NULL is hidden in a new abstraction called virSecurityManager.
This separates the driver callbacks, from main internal API. The addition
of a virSecurityManager object, that is separate from the virSecurityDriver
struct also allows for security drivers to carry state / configuration
information directly. Thus the DAC/Stack drivers from src/qemu which
used to pull config from 'struct qemud_driver' can now be moved into
the 'src/security' directory and store their config directly.
* src/qemu/qemu_conf.h, src/qemu/qemu_driver.c: Update to
use new virSecurityManager APIs
* src/qemu/qemu_security_dac.c, src/qemu/qemu_security_dac.h
src/qemu/qemu_security_stacked.c, src/qemu/qemu_security_stacked.h:
Move into src/security directory
* src/security/security_stack.c, src/security/security_stack.h,
src/security/security_dac.c, src/security/security_dac.h: Generic
versions of previous QEMU specific drivers
* src/security/security_apparmor.c, src/security/security_apparmor.h,
src/security/security_driver.c, src/security/security_driver.h,
src/security/security_selinux.c, src/security/security_selinux.h:
Update to take virSecurityManagerPtr object as the first param
in all callbacks
* src/security/security_nop.c, src/security/security_nop.h: Stub
implementation of all security driver APIs.
* src/security/security_manager.h, src/security/security_manager.c:
New internal API for invoking security drivers
* src/libvirt.c: Add missing debug for security APIs
2010-11-17 20:26:30 +00:00
|
|
|
if (!STREQ(virSecurityManagerGetModel(mgr), secdef->model)) {
|
2012-07-18 15:39:18 +01:00
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
|
_("security label driver mismatch: "
|
|
|
|
"'%s' model configured for domain, but "
|
|
|
|
"hypervisor driver is '%s'."),
|
|
|
|
secdef->model, virSecurityManagerGetModel(mgr));
|
2009-03-03 10:06:49 +00:00
|
|
|
if (security_getenforce() == 1)
|
2009-08-28 18:44:43 +01:00
|
|
|
return -1;
|
2009-03-03 10:06:49 +00:00
|
|
|
}
|
|
|
|
|
2012-10-05 16:41:22 +02:00
|
|
|
if (setexeccon_raw(secdef->label) == -1) {
|
2010-02-04 21:02:58 +01:00
|
|
|
virReportSystemError(errno,
|
2009-08-28 18:44:43 +01:00
|
|
|
_("unable to set security context '%s'"),
|
|
|
|
secdef->label);
|
2009-03-03 10:06:49 +00:00
|
|
|
if (security_getenforce() == 1)
|
2009-08-28 18:44:43 +01:00
|
|
|
return -1;
|
2009-03-03 10:06:49 +00:00
|
|
|
}
|
|
|
|
|
2010-01-11 11:04:40 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2010-05-27 16:44:47 +01:00
|
|
|
static int
|
2012-05-24 16:42:51 +01:00
|
|
|
virSecuritySELinuxSetSecurityDaemonSocketLabel(virSecurityManagerPtr mgr,
|
|
|
|
virDomainDefPtr def)
|
2010-05-27 16:44:47 +01:00
|
|
|
{
|
|
|
|
/* TODO: verify DOI */
|
2012-08-15 19:10:37 -03:00
|
|
|
virSecurityLabelDefPtr secdef;
|
2010-05-27 16:44:47 +01:00
|
|
|
security_context_t scon = NULL;
|
2012-10-15 17:03:49 +08:00
|
|
|
char *str = NULL;
|
2010-05-27 16:44:47 +01:00
|
|
|
int rc = -1;
|
|
|
|
|
2012-08-15 19:10:37 -03:00
|
|
|
secdef = virDomainDefGetSecurityLabelDef(def, SECURITY_SELINUX_NAME);
|
|
|
|
if (secdef == NULL)
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
if (secdef->label == NULL)
|
2010-05-27 16:44:47 +01:00
|
|
|
return 0;
|
|
|
|
|
Refactor the security drivers to simplify usage
The current security driver usage requires horrible code like
if (driver->securityDriver &&
driver->securityDriver->domainSetSecurityHostdevLabel &&
driver->securityDriver->domainSetSecurityHostdevLabel(driver->securityDriver,
vm, hostdev) < 0)
This pair of checks for NULL clutters up the code, making the driver
calls 2 lines longer than they really need to be. The goal of the
patchset is to change the calling convention to simply
if (virSecurityManagerSetHostdevLabel(driver->securityDriver,
vm, hostdev) < 0)
The first check for 'driver->securityDriver' being NULL is removed
by introducing a 'no op' security driver that will always be present
if no real driver is enabled. This guarentees driver->securityDriver
!= NULL.
The second check for 'driver->securityDriver->domainSetSecurityHostdevLabel'
being non-NULL is hidden in a new abstraction called virSecurityManager.
This separates the driver callbacks, from main internal API. The addition
of a virSecurityManager object, that is separate from the virSecurityDriver
struct also allows for security drivers to carry state / configuration
information directly. Thus the DAC/Stack drivers from src/qemu which
used to pull config from 'struct qemud_driver' can now be moved into
the 'src/security' directory and store their config directly.
* src/qemu/qemu_conf.h, src/qemu/qemu_driver.c: Update to
use new virSecurityManager APIs
* src/qemu/qemu_security_dac.c, src/qemu/qemu_security_dac.h
src/qemu/qemu_security_stacked.c, src/qemu/qemu_security_stacked.h:
Move into src/security directory
* src/security/security_stack.c, src/security/security_stack.h,
src/security/security_dac.c, src/security/security_dac.h: Generic
versions of previous QEMU specific drivers
* src/security/security_apparmor.c, src/security/security_apparmor.h,
src/security/security_driver.c, src/security/security_driver.h,
src/security/security_selinux.c, src/security/security_selinux.h:
Update to take virSecurityManagerPtr object as the first param
in all callbacks
* src/security/security_nop.c, src/security/security_nop.h: Stub
implementation of all security driver APIs.
* src/security/security_manager.h, src/security/security_manager.c:
New internal API for invoking security drivers
* src/libvirt.c: Add missing debug for security APIs
2010-11-17 20:26:30 +00:00
|
|
|
if (!STREQ(virSecurityManagerGetModel(mgr), secdef->model)) {
|
2012-07-18 15:39:18 +01:00
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
|
_("security label driver mismatch: "
|
|
|
|
"'%s' model configured for domain, but "
|
|
|
|
"hypervisor driver is '%s'."),
|
|
|
|
secdef->model, virSecurityManagerGetModel(mgr));
|
2010-05-27 16:44:47 +01:00
|
|
|
goto done;
|
|
|
|
}
|
|
|
|
|
2012-10-05 16:41:22 +02:00
|
|
|
if (getcon_raw(&scon) == -1) {
|
2010-05-27 16:44:47 +01:00
|
|
|
virReportSystemError(errno,
|
|
|
|
_("unable to get current process context '%s'"),
|
|
|
|
secdef->label);
|
|
|
|
goto done;
|
|
|
|
}
|
|
|
|
|
2012-10-15 17:03:49 +08:00
|
|
|
if (!(str = virSecuritySELinuxContextAddRange(secdef->label, scon)))
|
2010-05-27 16:44:47 +01:00
|
|
|
goto done;
|
|
|
|
|
2012-10-15 17:03:49 +08:00
|
|
|
VIR_DEBUG("Setting VM %s socket context %s", def->name, str);
|
|
|
|
if (setsockcreatecon_raw(str) == -1) {
|
2010-05-27 16:44:47 +01:00
|
|
|
virReportSystemError(errno,
|
2012-10-15 17:03:49 +08:00
|
|
|
_("unable to set socket security context '%s'"), str);
|
2010-05-27 16:44:47 +01:00
|
|
|
goto done;
|
|
|
|
}
|
|
|
|
|
|
|
|
rc = 0;
|
|
|
|
done:
|
|
|
|
|
|
|
|
if (security_getenforce() != 1)
|
|
|
|
rc = 0;
|
|
|
|
freecon(scon);
|
2012-10-15 17:03:49 +08:00
|
|
|
VIR_FREE(str);
|
2010-05-27 16:44:47 +01:00
|
|
|
return rc;
|
|
|
|
}
|
|
|
|
|
2011-08-26 09:39:32 +02:00
|
|
|
static int
|
2012-05-24 16:42:51 +01:00
|
|
|
virSecuritySELinuxSetSecuritySocketLabel(virSecurityManagerPtr mgr,
|
|
|
|
virDomainDefPtr vm)
|
2011-08-26 09:39:32 +02:00
|
|
|
{
|
2012-08-15 19:10:37 -03:00
|
|
|
virSecurityLabelDefPtr secdef;
|
2011-08-26 09:39:32 +02:00
|
|
|
int rc = -1;
|
|
|
|
|
2012-08-15 19:10:37 -03:00
|
|
|
secdef = virDomainDefGetSecurityLabelDef(vm, SECURITY_SELINUX_NAME);
|
|
|
|
if (secdef == NULL)
|
|
|
|
return -1;
|
|
|
|
|
2011-08-26 09:39:32 +02:00
|
|
|
if (secdef->label == NULL)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
if (!STREQ(virSecurityManagerGetModel(mgr), secdef->model)) {
|
2012-07-18 15:39:18 +01:00
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
|
_("security label driver mismatch: "
|
|
|
|
"'%s' model configured for domain, but "
|
|
|
|
"hypervisor driver is '%s'."),
|
|
|
|
secdef->model, virSecurityManagerGetModel(mgr));
|
2011-08-26 09:39:32 +02:00
|
|
|
goto done;
|
|
|
|
}
|
|
|
|
|
|
|
|
VIR_DEBUG("Setting VM %s socket context %s",
|
Change security driver APIs to use virDomainDefPtr instead of virDomainObjPtr
When sVirt is integrated with the LXC driver, it will be neccessary
to invoke the security driver APIs using only a virDomainDefPtr
since the lxc_container.c code has no virDomainObjPtr available.
Aside from two functions which want obj->pid, every bit of the
security driver code only touches obj->def. So we don't need to
pass a virDomainObjPtr into the security drivers, a virDomainDefPtr
is sufficient. Two functions also gain a 'pid_t pid' argument.
* src/qemu/qemu_driver.c, src/qemu/qemu_hotplug.c,
src/qemu/qemu_migration.c, src/qemu/qemu_process.c,
src/security/security_apparmor.c,
src/security/security_dac.c,
src/security/security_driver.h,
src/security/security_manager.c,
src/security/security_manager.h,
src/security/security_nop.c,
src/security/security_selinux.c,
src/security/security_stack.c: Change all security APIs to use a
virDomainDefPtr instead of virDomainObjPtr
2011-07-14 14:32:06 +01:00
|
|
|
vm->name, secdef->label);
|
2012-10-05 16:41:22 +02:00
|
|
|
if (setsockcreatecon_raw(secdef->label) == -1) {
|
2011-08-26 09:39:32 +02:00
|
|
|
virReportSystemError(errno,
|
|
|
|
_("unable to set socket security context '%s'"),
|
|
|
|
secdef->label);
|
|
|
|
goto done;
|
|
|
|
}
|
|
|
|
|
|
|
|
rc = 0;
|
|
|
|
|
|
|
|
done:
|
|
|
|
if (security_getenforce() != 1)
|
|
|
|
rc = 0;
|
|
|
|
|
|
|
|
return rc;
|
|
|
|
}
|
|
|
|
|
2010-05-27 16:44:47 +01:00
|
|
|
static int
|
2012-05-24 16:42:51 +01:00
|
|
|
virSecuritySELinuxClearSecuritySocketLabel(virSecurityManagerPtr mgr,
|
|
|
|
virDomainDefPtr def)
|
2010-05-27 16:44:47 +01:00
|
|
|
{
|
|
|
|
/* TODO: verify DOI */
|
2012-08-15 19:10:37 -03:00
|
|
|
virSecurityLabelDefPtr secdef;
|
|
|
|
|
|
|
|
secdef = virDomainDefGetSecurityLabelDef(def, SECURITY_SELINUX_NAME);
|
|
|
|
if (secdef == NULL)
|
|
|
|
return -1;
|
2010-05-27 16:44:47 +01:00
|
|
|
|
2012-08-15 19:10:37 -03:00
|
|
|
if (secdef->label == NULL)
|
2010-05-27 16:44:47 +01:00
|
|
|
return 0;
|
|
|
|
|
Refactor the security drivers to simplify usage
The current security driver usage requires horrible code like
if (driver->securityDriver &&
driver->securityDriver->domainSetSecurityHostdevLabel &&
driver->securityDriver->domainSetSecurityHostdevLabel(driver->securityDriver,
vm, hostdev) < 0)
This pair of checks for NULL clutters up the code, making the driver
calls 2 lines longer than they really need to be. The goal of the
patchset is to change the calling convention to simply
if (virSecurityManagerSetHostdevLabel(driver->securityDriver,
vm, hostdev) < 0)
The first check for 'driver->securityDriver' being NULL is removed
by introducing a 'no op' security driver that will always be present
if no real driver is enabled. This guarentees driver->securityDriver
!= NULL.
The second check for 'driver->securityDriver->domainSetSecurityHostdevLabel'
being non-NULL is hidden in a new abstraction called virSecurityManager.
This separates the driver callbacks, from main internal API. The addition
of a virSecurityManager object, that is separate from the virSecurityDriver
struct also allows for security drivers to carry state / configuration
information directly. Thus the DAC/Stack drivers from src/qemu which
used to pull config from 'struct qemud_driver' can now be moved into
the 'src/security' directory and store their config directly.
* src/qemu/qemu_conf.h, src/qemu/qemu_driver.c: Update to
use new virSecurityManager APIs
* src/qemu/qemu_security_dac.c, src/qemu/qemu_security_dac.h
src/qemu/qemu_security_stacked.c, src/qemu/qemu_security_stacked.h:
Move into src/security directory
* src/security/security_stack.c, src/security/security_stack.h,
src/security/security_dac.c, src/security/security_dac.h: Generic
versions of previous QEMU specific drivers
* src/security/security_apparmor.c, src/security/security_apparmor.h,
src/security/security_driver.c, src/security/security_driver.h,
src/security/security_selinux.c, src/security/security_selinux.h:
Update to take virSecurityManagerPtr object as the first param
in all callbacks
* src/security/security_nop.c, src/security/security_nop.h: Stub
implementation of all security driver APIs.
* src/security/security_manager.h, src/security/security_manager.c:
New internal API for invoking security drivers
* src/libvirt.c: Add missing debug for security APIs
2010-11-17 20:26:30 +00:00
|
|
|
if (!STREQ(virSecurityManagerGetModel(mgr), secdef->model)) {
|
2012-07-18 15:39:18 +01:00
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
|
_("security label driver mismatch: "
|
|
|
|
"'%s' model configured for domain, but "
|
|
|
|
"hypervisor driver is '%s'."),
|
|
|
|
secdef->model, virSecurityManagerGetModel(mgr));
|
2010-05-27 16:44:47 +01:00
|
|
|
if (security_getenforce() == 1)
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2012-10-05 16:41:22 +02:00
|
|
|
if (setsockcreatecon_raw(NULL) == -1) {
|
2010-05-27 16:44:47 +01:00
|
|
|
virReportSystemError(errno,
|
|
|
|
_("unable to clear socket security context '%s'"),
|
|
|
|
secdef->label);
|
|
|
|
if (security_getenforce() == 1)
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2010-06-23 16:17:15 +01:00
|
|
|
|
|
|
|
static int
|
2012-05-24 16:42:51 +01:00
|
|
|
virSecuritySELinuxSetSecurityChardevCallback(virDomainDefPtr def,
|
|
|
|
virDomainChrDefPtr dev,
|
|
|
|
void *opaque ATTRIBUTE_UNUSED)
|
2010-06-23 16:17:15 +01:00
|
|
|
{
|
Allow multiple consoles per virtual guest
While Xen only has a single paravirt console, UML, and
QEMU both support multiple paravirt consoles. The LXC
driver can also be trivially made to support multiple
consoles. This patch extends the XML to allow multiple
<console> elements in the XML. It also makes the UML
and QEMU drivers support this config.
* src/conf/domain_conf.c, src/conf/domain_conf.h: Allow
multiple <console> devices
* src/lxc/lxc_driver.c, src/xen/xen_driver.c,
src/xenxs/xen_sxpr.c, src/xenxs/xen_xm.c: Update for
internal API changes
* src/security/security_selinux.c, src/security/virt-aa-helper.c:
Only label consoles that aren't a copy of the serial device
* src/qemu/qemu_command.c, src/qemu/qemu_driver.c,
src/qemu/qemu_process.c, src/uml/uml_conf.c,
src/uml/uml_driver.c: Support multiple console devices
* tests/qemuxml2xmltest.c, tests/qemuxml2argvtest.c: Extra
tests for multiple virtio consoles. Set QEMU_CAPS_CHARDEV
for all console /channel tests
* tests/qemuxml2argvdata/qemuxml2argv-channel-virtio-auto.args,
tests/qemuxml2argvdata/qemuxml2argv-channel-virtio.args
tests/qemuxml2argvdata/qemuxml2argv-console-virtio.args: Update
for correct chardev syntax
* tests/qemuxml2argvdata/qemuxml2argv-console-virtio-many.args,
tests/qemuxml2argvdata/qemuxml2argv-console-virtio-many.xml: New
test file
2011-02-23 18:27:23 +00:00
|
|
|
/* This is taken care of by processing of def->serials */
|
|
|
|
if (dev->deviceType == VIR_DOMAIN_CHR_DEVICE_TYPE_CONSOLE &&
|
|
|
|
dev->targetType == VIR_DOMAIN_CHR_CONSOLE_TARGET_TYPE_SERIAL)
|
|
|
|
return 0;
|
|
|
|
|
2012-09-20 14:16:17 +01:00
|
|
|
return virSecuritySELinuxSetSecurityChardevLabel(def, dev, &dev->source);
|
2010-06-23 16:17:15 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2011-01-14 12:17:17 -07:00
|
|
|
static int
|
2012-05-24 16:42:51 +01:00
|
|
|
virSecuritySELinuxSetSecuritySmartcardCallback(virDomainDefPtr def,
|
|
|
|
virDomainSmartcardDefPtr dev,
|
|
|
|
void *opaque)
|
2011-01-14 12:17:17 -07:00
|
|
|
{
|
|
|
|
const char *database;
|
2012-05-11 10:43:30 +01:00
|
|
|
virSecurityManagerPtr mgr = opaque;
|
|
|
|
virSecuritySELinuxDataPtr data = virSecurityManagerGetPrivateData(mgr);
|
2011-01-14 12:17:17 -07:00
|
|
|
|
|
|
|
switch (dev->type) {
|
|
|
|
case VIR_DOMAIN_SMARTCARD_TYPE_HOST:
|
|
|
|
break;
|
|
|
|
|
|
|
|
case VIR_DOMAIN_SMARTCARD_TYPE_HOST_CERTIFICATES:
|
|
|
|
database = dev->data.cert.database;
|
|
|
|
if (!database)
|
|
|
|
database = VIR_DOMAIN_SMARTCARD_DEFAULT_DATABASE;
|
2012-05-24 16:42:51 +01:00
|
|
|
return virSecuritySELinuxSetFilecon(database, data->content_context);
|
2011-01-14 12:17:17 -07:00
|
|
|
|
|
|
|
case VIR_DOMAIN_SMARTCARD_TYPE_PASSTHROUGH:
|
2012-09-20 14:16:17 +01:00
|
|
|
return virSecuritySELinuxSetSecurityChardevLabel(def, NULL, &dev->data.passthru);
|
2011-01-14 12:17:17 -07:00
|
|
|
|
|
|
|
default:
|
2012-07-18 15:39:18 +01:00
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
|
_("unknown smartcard type %d"),
|
|
|
|
dev->type);
|
2011-01-14 12:17:17 -07:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2010-01-11 11:04:40 +00:00
|
|
|
static int
|
2012-05-24 16:42:51 +01:00
|
|
|
virSecuritySELinuxSetSecurityAllLabel(virSecurityManagerPtr mgr,
|
|
|
|
virDomainDefPtr def,
|
|
|
|
const char *stdin_path)
|
2010-01-11 11:04:40 +00:00
|
|
|
{
|
|
|
|
int i;
|
2012-08-15 19:10:37 -03:00
|
|
|
virSecuritySELinuxDataPtr data = virSecurityManagerGetPrivateData(mgr);
|
|
|
|
virSecurityLabelDefPtr secdef;
|
|
|
|
|
|
|
|
secdef = virDomainDefGetSecurityLabelDef(def, SECURITY_SELINUX_NAME);
|
|
|
|
if (secdef == NULL)
|
|
|
|
return -1;
|
2010-01-11 11:04:40 +00:00
|
|
|
|
2012-11-28 13:54:39 +00:00
|
|
|
if (secdef->norelabel || data->skipAllLabel)
|
2010-01-11 11:04:40 +00:00
|
|
|
return 0;
|
|
|
|
|
Change security driver APIs to use virDomainDefPtr instead of virDomainObjPtr
When sVirt is integrated with the LXC driver, it will be neccessary
to invoke the security driver APIs using only a virDomainDefPtr
since the lxc_container.c code has no virDomainObjPtr available.
Aside from two functions which want obj->pid, every bit of the
security driver code only touches obj->def. So we don't need to
pass a virDomainObjPtr into the security drivers, a virDomainDefPtr
is sufficient. Two functions also gain a 'pid_t pid' argument.
* src/qemu/qemu_driver.c, src/qemu/qemu_hotplug.c,
src/qemu/qemu_migration.c, src/qemu/qemu_process.c,
src/security/security_apparmor.c,
src/security/security_dac.c,
src/security/security_driver.h,
src/security/security_manager.c,
src/security/security_manager.h,
src/security/security_nop.c,
src/security/security_selinux.c,
src/security/security_stack.c: Change all security APIs to use a
virDomainDefPtr instead of virDomainObjPtr
2011-07-14 14:32:06 +01:00
|
|
|
for (i = 0 ; i < def->ndisks ; i++) {
|
2010-01-11 11:04:40 +00:00
|
|
|
/* XXX fixme - we need to recursively label the entire tree :-( */
|
Change security driver APIs to use virDomainDefPtr instead of virDomainObjPtr
When sVirt is integrated with the LXC driver, it will be neccessary
to invoke the security driver APIs using only a virDomainDefPtr
since the lxc_container.c code has no virDomainObjPtr available.
Aside from two functions which want obj->pid, every bit of the
security driver code only touches obj->def. So we don't need to
pass a virDomainObjPtr into the security drivers, a virDomainDefPtr
is sufficient. Two functions also gain a 'pid_t pid' argument.
* src/qemu/qemu_driver.c, src/qemu/qemu_hotplug.c,
src/qemu/qemu_migration.c, src/qemu/qemu_process.c,
src/security/security_apparmor.c,
src/security/security_dac.c,
src/security/security_driver.h,
src/security/security_manager.c,
src/security/security_manager.h,
src/security/security_nop.c,
src/security/security_selinux.c,
src/security/security_stack.c: Change all security APIs to use a
virDomainDefPtr instead of virDomainObjPtr
2011-07-14 14:32:06 +01:00
|
|
|
if (def->disks[i]->type == VIR_DOMAIN_DISK_TYPE_DIR) {
|
2010-01-11 11:04:40 +00:00
|
|
|
VIR_WARN("Unable to relabel directory tree %s for disk %s",
|
Change security driver APIs to use virDomainDefPtr instead of virDomainObjPtr
When sVirt is integrated with the LXC driver, it will be neccessary
to invoke the security driver APIs using only a virDomainDefPtr
since the lxc_container.c code has no virDomainObjPtr available.
Aside from two functions which want obj->pid, every bit of the
security driver code only touches obj->def. So we don't need to
pass a virDomainObjPtr into the security drivers, a virDomainDefPtr
is sufficient. Two functions also gain a 'pid_t pid' argument.
* src/qemu/qemu_driver.c, src/qemu/qemu_hotplug.c,
src/qemu/qemu_migration.c, src/qemu/qemu_process.c,
src/security/security_apparmor.c,
src/security/security_dac.c,
src/security/security_driver.h,
src/security/security_manager.c,
src/security/security_manager.h,
src/security/security_nop.c,
src/security/security_selinux.c,
src/security/security_stack.c: Change all security APIs to use a
virDomainDefPtr instead of virDomainObjPtr
2011-07-14 14:32:06 +01:00
|
|
|
def->disks[i]->src, def->disks[i]->dst);
|
2010-01-11 11:04:40 +00:00
|
|
|
continue;
|
2009-08-14 14:23:11 +01:00
|
|
|
}
|
2012-05-24 16:42:51 +01:00
|
|
|
if (virSecuritySELinuxSetSecurityImageLabel(mgr,
|
Change security driver APIs to use virDomainDefPtr instead of virDomainObjPtr
When sVirt is integrated with the LXC driver, it will be neccessary
to invoke the security driver APIs using only a virDomainDefPtr
since the lxc_container.c code has no virDomainObjPtr available.
Aside from two functions which want obj->pid, every bit of the
security driver code only touches obj->def. So we don't need to
pass a virDomainObjPtr into the security drivers, a virDomainDefPtr
is sufficient. Two functions also gain a 'pid_t pid' argument.
* src/qemu/qemu_driver.c, src/qemu/qemu_hotplug.c,
src/qemu/qemu_migration.c, src/qemu/qemu_process.c,
src/security/security_apparmor.c,
src/security/security_dac.c,
src/security/security_driver.h,
src/security/security_manager.c,
src/security/security_manager.h,
src/security/security_nop.c,
src/security/security_selinux.c,
src/security/security_stack.c: Change all security APIs to use a
virDomainDefPtr instead of virDomainObjPtr
2011-07-14 14:32:06 +01:00
|
|
|
def, def->disks[i]) < 0)
|
2010-01-11 11:04:40 +00:00
|
|
|
return -1;
|
|
|
|
}
|
Change security driver APIs to use virDomainDefPtr instead of virDomainObjPtr
When sVirt is integrated with the LXC driver, it will be neccessary
to invoke the security driver APIs using only a virDomainDefPtr
since the lxc_container.c code has no virDomainObjPtr available.
Aside from two functions which want obj->pid, every bit of the
security driver code only touches obj->def. So we don't need to
pass a virDomainObjPtr into the security drivers, a virDomainDefPtr
is sufficient. Two functions also gain a 'pid_t pid' argument.
* src/qemu/qemu_driver.c, src/qemu/qemu_hotplug.c,
src/qemu/qemu_migration.c, src/qemu/qemu_process.c,
src/security/security_apparmor.c,
src/security/security_dac.c,
src/security/security_driver.h,
src/security/security_manager.c,
src/security/security_manager.h,
src/security/security_nop.c,
src/security/security_selinux.c,
src/security/security_stack.c: Change all security APIs to use a
virDomainDefPtr instead of virDomainObjPtr
2011-07-14 14:32:06 +01:00
|
|
|
/* XXX fixme process def->fss if relabel == true */
|
2011-06-24 10:21:33 +01:00
|
|
|
|
Change security driver APIs to use virDomainDefPtr instead of virDomainObjPtr
When sVirt is integrated with the LXC driver, it will be neccessary
to invoke the security driver APIs using only a virDomainDefPtr
since the lxc_container.c code has no virDomainObjPtr available.
Aside from two functions which want obj->pid, every bit of the
security driver code only touches obj->def. So we don't need to
pass a virDomainObjPtr into the security drivers, a virDomainDefPtr
is sufficient. Two functions also gain a 'pid_t pid' argument.
* src/qemu/qemu_driver.c, src/qemu/qemu_hotplug.c,
src/qemu/qemu_migration.c, src/qemu/qemu_process.c,
src/security/security_apparmor.c,
src/security/security_dac.c,
src/security/security_driver.h,
src/security/security_manager.c,
src/security/security_manager.h,
src/security/security_nop.c,
src/security/security_selinux.c,
src/security/security_stack.c: Change all security APIs to use a
virDomainDefPtr instead of virDomainObjPtr
2011-07-14 14:32:06 +01:00
|
|
|
for (i = 0 ; i < def->nhostdevs ; i++) {
|
2012-05-24 16:42:51 +01:00
|
|
|
if (virSecuritySELinuxSetSecurityHostdevLabel(mgr,
|
2012-11-27 16:17:47 +00:00
|
|
|
def,
|
|
|
|
def->hostdevs[i],
|
|
|
|
NULL) < 0)
|
2010-01-11 11:04:40 +00:00
|
|
|
return -1;
|
2009-03-03 10:06:49 +00:00
|
|
|
}
|
|
|
|
|
Change security driver APIs to use virDomainDefPtr instead of virDomainObjPtr
When sVirt is integrated with the LXC driver, it will be neccessary
to invoke the security driver APIs using only a virDomainDefPtr
since the lxc_container.c code has no virDomainObjPtr available.
Aside from two functions which want obj->pid, every bit of the
security driver code only touches obj->def. So we don't need to
pass a virDomainObjPtr into the security drivers, a virDomainDefPtr
is sufficient. Two functions also gain a 'pid_t pid' argument.
* src/qemu/qemu_driver.c, src/qemu/qemu_hotplug.c,
src/qemu/qemu_migration.c, src/qemu/qemu_process.c,
src/security/security_apparmor.c,
src/security/security_dac.c,
src/security/security_driver.h,
src/security/security_manager.c,
src/security/security_manager.h,
src/security/security_nop.c,
src/security/security_selinux.c,
src/security/security_stack.c: Change all security APIs to use a
virDomainDefPtr instead of virDomainObjPtr
2011-07-14 14:32:06 +01:00
|
|
|
if (virDomainChrDefForeach(def,
|
2010-06-23 16:17:15 +01:00
|
|
|
true,
|
2012-05-24 16:42:51 +01:00
|
|
|
virSecuritySELinuxSetSecurityChardevCallback,
|
Change security driver APIs to use virDomainDefPtr instead of virDomainObjPtr
When sVirt is integrated with the LXC driver, it will be neccessary
to invoke the security driver APIs using only a virDomainDefPtr
since the lxc_container.c code has no virDomainObjPtr available.
Aside from two functions which want obj->pid, every bit of the
security driver code only touches obj->def. So we don't need to
pass a virDomainObjPtr into the security drivers, a virDomainDefPtr
is sufficient. Two functions also gain a 'pid_t pid' argument.
* src/qemu/qemu_driver.c, src/qemu/qemu_hotplug.c,
src/qemu/qemu_migration.c, src/qemu/qemu_process.c,
src/security/security_apparmor.c,
src/security/security_dac.c,
src/security/security_driver.h,
src/security/security_manager.c,
src/security/security_manager.h,
src/security/security_nop.c,
src/security/security_selinux.c,
src/security/security_stack.c: Change all security APIs to use a
virDomainDefPtr instead of virDomainObjPtr
2011-07-14 14:32:06 +01:00
|
|
|
NULL) < 0)
|
2010-06-23 16:17:15 +01:00
|
|
|
return -1;
|
|
|
|
|
Change security driver APIs to use virDomainDefPtr instead of virDomainObjPtr
When sVirt is integrated with the LXC driver, it will be neccessary
to invoke the security driver APIs using only a virDomainDefPtr
since the lxc_container.c code has no virDomainObjPtr available.
Aside from two functions which want obj->pid, every bit of the
security driver code only touches obj->def. So we don't need to
pass a virDomainObjPtr into the security drivers, a virDomainDefPtr
is sufficient. Two functions also gain a 'pid_t pid' argument.
* src/qemu/qemu_driver.c, src/qemu/qemu_hotplug.c,
src/qemu/qemu_migration.c, src/qemu/qemu_process.c,
src/security/security_apparmor.c,
src/security/security_dac.c,
src/security/security_driver.h,
src/security/security_manager.c,
src/security/security_manager.h,
src/security/security_nop.c,
src/security/security_selinux.c,
src/security/security_stack.c: Change all security APIs to use a
virDomainDefPtr instead of virDomainObjPtr
2011-07-14 14:32:06 +01:00
|
|
|
if (virDomainSmartcardDefForeach(def,
|
2011-01-14 12:17:17 -07:00
|
|
|
true,
|
2012-05-24 16:42:51 +01:00
|
|
|
virSecuritySELinuxSetSecuritySmartcardCallback,
|
2012-05-11 10:43:30 +01:00
|
|
|
mgr) < 0)
|
2011-01-14 12:17:17 -07:00
|
|
|
return -1;
|
|
|
|
|
Change security driver APIs to use virDomainDefPtr instead of virDomainObjPtr
When sVirt is integrated with the LXC driver, it will be neccessary
to invoke the security driver APIs using only a virDomainDefPtr
since the lxc_container.c code has no virDomainObjPtr available.
Aside from two functions which want obj->pid, every bit of the
security driver code only touches obj->def. So we don't need to
pass a virDomainObjPtr into the security drivers, a virDomainDefPtr
is sufficient. Two functions also gain a 'pid_t pid' argument.
* src/qemu/qemu_driver.c, src/qemu/qemu_hotplug.c,
src/qemu/qemu_migration.c, src/qemu/qemu_process.c,
src/security/security_apparmor.c,
src/security/security_dac.c,
src/security/security_driver.h,
src/security/security_manager.c,
src/security/security_manager.h,
src/security/security_nop.c,
src/security/security_selinux.c,
src/security/security_stack.c: Change all security APIs to use a
virDomainDefPtr instead of virDomainObjPtr
2011-07-14 14:32:06 +01:00
|
|
|
if (def->os.kernel &&
|
2012-05-24 16:42:51 +01:00
|
|
|
virSecuritySELinuxSetFilecon(def->os.kernel, data->content_context) < 0)
|
2010-03-12 13:38:39 -05:00
|
|
|
return -1;
|
|
|
|
|
Change security driver APIs to use virDomainDefPtr instead of virDomainObjPtr
When sVirt is integrated with the LXC driver, it will be neccessary
to invoke the security driver APIs using only a virDomainDefPtr
since the lxc_container.c code has no virDomainObjPtr available.
Aside from two functions which want obj->pid, every bit of the
security driver code only touches obj->def. So we don't need to
pass a virDomainObjPtr into the security drivers, a virDomainDefPtr
is sufficient. Two functions also gain a 'pid_t pid' argument.
* src/qemu/qemu_driver.c, src/qemu/qemu_hotplug.c,
src/qemu/qemu_migration.c, src/qemu/qemu_process.c,
src/security/security_apparmor.c,
src/security/security_dac.c,
src/security/security_driver.h,
src/security/security_manager.c,
src/security/security_manager.h,
src/security/security_nop.c,
src/security/security_selinux.c,
src/security/security_stack.c: Change all security APIs to use a
virDomainDefPtr instead of virDomainObjPtr
2011-07-14 14:32:06 +01:00
|
|
|
if (def->os.initrd &&
|
2012-05-24 16:42:51 +01:00
|
|
|
virSecuritySELinuxSetFilecon(def->os.initrd, data->content_context) < 0)
|
2010-03-12 13:38:39 -05:00
|
|
|
return -1;
|
|
|
|
|
2010-10-29 12:20:40 +01:00
|
|
|
if (stdin_path) {
|
2012-05-24 16:42:51 +01:00
|
|
|
if (virSecuritySELinuxSetFilecon(stdin_path, data->content_context) < 0 &&
|
2010-10-29 12:20:40 +01:00
|
|
|
virStorageFileIsSharedFSType(stdin_path,
|
|
|
|
VIR_STORAGE_FILE_SHFS_NFS) != 1)
|
|
|
|
return -1;
|
|
|
|
}
|
2010-06-24 17:58:59 -04:00
|
|
|
|
2009-03-03 10:06:49 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2011-01-23 16:02:42 -05:00
|
|
|
static int
|
2012-05-24 16:42:51 +01:00
|
|
|
virSecuritySELinuxSetImageFDLabel(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
|
|
|
|
virDomainDefPtr def,
|
|
|
|
int fd)
|
2011-01-23 16:02:42 -05:00
|
|
|
{
|
2012-08-15 19:10:37 -03:00
|
|
|
virSecurityLabelDefPtr secdef;
|
|
|
|
|
|
|
|
secdef = virDomainDefGetSecurityLabelDef(def, SECURITY_SELINUX_NAME);
|
|
|
|
if (secdef == NULL)
|
|
|
|
return -1;
|
2011-01-23 16:02:42 -05:00
|
|
|
|
|
|
|
if (secdef->imagelabel == NULL)
|
|
|
|
return 0;
|
|
|
|
|
2012-05-24 16:42:51 +01:00
|
|
|
return virSecuritySELinuxFSetFilecon(fd, secdef->imagelabel);
|
2011-01-23 16:02:42 -05:00
|
|
|
}
|
|
|
|
|
2012-10-15 17:03:49 +08:00
|
|
|
static int
|
|
|
|
virSecuritySELinuxSetTapFDLabel(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
|
|
|
|
virDomainDefPtr def,
|
|
|
|
int fd)
|
|
|
|
{
|
|
|
|
struct stat buf;
|
|
|
|
security_context_t fcon = NULL;
|
|
|
|
virSecurityLabelDefPtr secdef;
|
|
|
|
char *str = NULL;
|
|
|
|
int rc = -1;
|
|
|
|
|
|
|
|
secdef = virDomainDefGetSecurityLabelDef(def, SECURITY_SELINUX_NAME);
|
|
|
|
if (secdef == NULL)
|
|
|
|
return rc;
|
|
|
|
|
|
|
|
if (secdef->label == NULL)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
if (fstat(fd, &buf) < 0) {
|
|
|
|
virReportSystemError(errno, _("cannot stat tap fd %d"), fd);
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ((buf.st_mode & S_IFMT) != S_IFCHR) {
|
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
|
_("tap fd %d is not character device"), fd);
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (getContext("/dev/tap.*", buf.st_mode, &fcon) < 0) {
|
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
|
_("cannot lookup default selinux label for tap fd %d"), fd);
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!(str = virSecuritySELinuxContextAddRange(secdef->label, fcon))) {
|
|
|
|
goto cleanup;
|
|
|
|
} else {
|
|
|
|
rc = virSecuritySELinuxFSetFilecon(fd, str);
|
|
|
|
}
|
|
|
|
|
|
|
|
cleanup:
|
|
|
|
freecon(fcon);
|
|
|
|
VIR_FREE(str);
|
|
|
|
return rc;
|
|
|
|
}
|
|
|
|
|
2012-05-24 16:42:51 +01:00
|
|
|
static char *
|
|
|
|
virSecuritySELinuxGenImageLabel(virSecurityManagerPtr mgr,
|
|
|
|
virDomainDefPtr def)
|
|
|
|
{
|
2012-08-15 19:10:37 -03:00
|
|
|
virSecurityLabelDefPtr secdef;
|
2012-05-01 15:16:04 +01:00
|
|
|
virSecuritySELinuxDataPtr data = virSecurityManagerGetPrivateData(mgr);
|
|
|
|
const char *range;
|
|
|
|
context_t ctx = NULL;
|
|
|
|
char *label = NULL;
|
|
|
|
const char *mcs = NULL;
|
|
|
|
|
2012-08-15 19:10:37 -03:00
|
|
|
secdef = virDomainDefGetSecurityLabelDef(def, SECURITY_SELINUX_NAME);
|
|
|
|
if (secdef == NULL)
|
|
|
|
goto cleanup;
|
|
|
|
|
2012-05-01 15:16:04 +01:00
|
|
|
if (secdef->label) {
|
|
|
|
ctx = context_new(secdef->label);
|
|
|
|
if (!ctx) {
|
|
|
|
virReportOOMError();
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
range = context_range_get(ctx);
|
|
|
|
if (range) {
|
|
|
|
mcs = strdup(range);
|
|
|
|
if (!mcs) {
|
|
|
|
virReportOOMError();
|
|
|
|
goto cleanup;
|
|
|
|
}
|
2012-08-20 16:12:14 +02:00
|
|
|
if (!(label = virSecuritySELinuxGenNewContext(data->file_context,
|
|
|
|
mcs, true)))
|
2012-05-01 15:16:04 +01:00
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
cleanup:
|
|
|
|
context_free(ctx);
|
|
|
|
VIR_FREE(mcs);
|
|
|
|
return label;
|
|
|
|
}
|
|
|
|
|
2012-05-24 16:42:51 +01:00
|
|
|
static char *
|
|
|
|
virSecuritySELinuxGetSecurityMountOptions(virSecurityManagerPtr mgr,
|
|
|
|
virDomainDefPtr def)
|
|
|
|
{
|
2012-05-01 15:16:04 +01:00
|
|
|
char *opts = NULL;
|
2012-08-15 19:10:37 -03:00
|
|
|
virSecurityLabelDefPtr secdef;
|
|
|
|
|
2012-11-22 14:11:35 +00:00
|
|
|
if ((secdef = virDomainDefGetSecurityLabelDef(def, SECURITY_SELINUX_NAME))) {
|
|
|
|
if (!secdef->imagelabel)
|
|
|
|
secdef->imagelabel = virSecuritySELinuxGenImageLabel(mgr, def);
|
|
|
|
|
|
|
|
if (secdef->imagelabel &&
|
|
|
|
virAsprintf(&opts,
|
|
|
|
",context=\"%s\"",
|
|
|
|
(const char*) secdef->imagelabel) < 0) {
|
|
|
|
virReportOOMError();
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
}
|
2012-05-01 15:16:04 +01:00
|
|
|
|
2012-11-22 14:11:35 +00:00
|
|
|
if (!opts &&
|
|
|
|
!(opts = strdup(""))) {
|
|
|
|
virReportOOMError();
|
|
|
|
return NULL;
|
2012-05-01 15:16:04 +01:00
|
|
|
}
|
|
|
|
|
2012-12-13 11:44:37 +01:00
|
|
|
VIR_DEBUG("imageLabel=%s opts=%s",
|
|
|
|
secdef ? secdef->imagelabel : "(null)", opts);
|
2012-05-01 15:16:04 +01:00
|
|
|
return opts;
|
|
|
|
}
|
|
|
|
|
Refactor the security drivers to simplify usage
The current security driver usage requires horrible code like
if (driver->securityDriver &&
driver->securityDriver->domainSetSecurityHostdevLabel &&
driver->securityDriver->domainSetSecurityHostdevLabel(driver->securityDriver,
vm, hostdev) < 0)
This pair of checks for NULL clutters up the code, making the driver
calls 2 lines longer than they really need to be. The goal of the
patchset is to change the calling convention to simply
if (virSecurityManagerSetHostdevLabel(driver->securityDriver,
vm, hostdev) < 0)
The first check for 'driver->securityDriver' being NULL is removed
by introducing a 'no op' security driver that will always be present
if no real driver is enabled. This guarentees driver->securityDriver
!= NULL.
The second check for 'driver->securityDriver->domainSetSecurityHostdevLabel'
being non-NULL is hidden in a new abstraction called virSecurityManager.
This separates the driver callbacks, from main internal API. The addition
of a virSecurityManager object, that is separate from the virSecurityDriver
struct also allows for security drivers to carry state / configuration
information directly. Thus the DAC/Stack drivers from src/qemu which
used to pull config from 'struct qemud_driver' can now be moved into
the 'src/security' directory and store their config directly.
* src/qemu/qemu_conf.h, src/qemu/qemu_driver.c: Update to
use new virSecurityManager APIs
* src/qemu/qemu_security_dac.c, src/qemu/qemu_security_dac.h
src/qemu/qemu_security_stacked.c, src/qemu/qemu_security_stacked.h:
Move into src/security directory
* src/security/security_stack.c, src/security/security_stack.h,
src/security/security_dac.c, src/security/security_dac.h: Generic
versions of previous QEMU specific drivers
* src/security/security_apparmor.c, src/security/security_apparmor.h,
src/security/security_driver.c, src/security/security_driver.h,
src/security/security_selinux.c, src/security/security_selinux.h:
Update to take virSecurityManagerPtr object as the first param
in all callbacks
* src/security/security_nop.c, src/security/security_nop.h: Stub
implementation of all security driver APIs.
* src/security/security_manager.h, src/security/security_manager.c:
New internal API for invoking security drivers
* src/libvirt.c: Add missing debug for security APIs
2010-11-17 20:26:30 +00:00
|
|
|
virSecurityDriver virSecurityDriverSELinux = {
|
2012-05-24 15:11:26 +02:00
|
|
|
.privateDataLen = sizeof(virSecuritySELinuxData),
|
|
|
|
.name = SECURITY_SELINUX_NAME,
|
2012-05-24 16:42:51 +01:00
|
|
|
.probe = virSecuritySELinuxSecurityDriverProbe,
|
|
|
|
.open = virSecuritySELinuxSecurityDriverOpen,
|
|
|
|
.close = virSecuritySELinuxSecurityDriverClose,
|
Refactor the security drivers to simplify usage
The current security driver usage requires horrible code like
if (driver->securityDriver &&
driver->securityDriver->domainSetSecurityHostdevLabel &&
driver->securityDriver->domainSetSecurityHostdevLabel(driver->securityDriver,
vm, hostdev) < 0)
This pair of checks for NULL clutters up the code, making the driver
calls 2 lines longer than they really need to be. The goal of the
patchset is to change the calling convention to simply
if (virSecurityManagerSetHostdevLabel(driver->securityDriver,
vm, hostdev) < 0)
The first check for 'driver->securityDriver' being NULL is removed
by introducing a 'no op' security driver that will always be present
if no real driver is enabled. This guarentees driver->securityDriver
!= NULL.
The second check for 'driver->securityDriver->domainSetSecurityHostdevLabel'
being non-NULL is hidden in a new abstraction called virSecurityManager.
This separates the driver callbacks, from main internal API. The addition
of a virSecurityManager object, that is separate from the virSecurityDriver
struct also allows for security drivers to carry state / configuration
information directly. Thus the DAC/Stack drivers from src/qemu which
used to pull config from 'struct qemud_driver' can now be moved into
the 'src/security' directory and store their config directly.
* src/qemu/qemu_conf.h, src/qemu/qemu_driver.c: Update to
use new virSecurityManager APIs
* src/qemu/qemu_security_dac.c, src/qemu/qemu_security_dac.h
src/qemu/qemu_security_stacked.c, src/qemu/qemu_security_stacked.h:
Move into src/security directory
* src/security/security_stack.c, src/security/security_stack.h,
src/security/security_dac.c, src/security/security_dac.h: Generic
versions of previous QEMU specific drivers
* src/security/security_apparmor.c, src/security/security_apparmor.h,
src/security/security_driver.c, src/security/security_driver.h,
src/security/security_selinux.c, src/security/security_selinux.h:
Update to take virSecurityManagerPtr object as the first param
in all callbacks
* src/security/security_nop.c, src/security/security_nop.h: Stub
implementation of all security driver APIs.
* src/security/security_manager.h, src/security/security_manager.c:
New internal API for invoking security drivers
* src/libvirt.c: Add missing debug for security APIs
2010-11-17 20:26:30 +00:00
|
|
|
|
2012-05-24 16:42:51 +01:00
|
|
|
.getModel = virSecuritySELinuxSecurityGetModel,
|
|
|
|
.getDOI = virSecuritySELinuxSecurityGetDOI,
|
Refactor the security drivers to simplify usage
The current security driver usage requires horrible code like
if (driver->securityDriver &&
driver->securityDriver->domainSetSecurityHostdevLabel &&
driver->securityDriver->domainSetSecurityHostdevLabel(driver->securityDriver,
vm, hostdev) < 0)
This pair of checks for NULL clutters up the code, making the driver
calls 2 lines longer than they really need to be. The goal of the
patchset is to change the calling convention to simply
if (virSecurityManagerSetHostdevLabel(driver->securityDriver,
vm, hostdev) < 0)
The first check for 'driver->securityDriver' being NULL is removed
by introducing a 'no op' security driver that will always be present
if no real driver is enabled. This guarentees driver->securityDriver
!= NULL.
The second check for 'driver->securityDriver->domainSetSecurityHostdevLabel'
being non-NULL is hidden in a new abstraction called virSecurityManager.
This separates the driver callbacks, from main internal API. The addition
of a virSecurityManager object, that is separate from the virSecurityDriver
struct also allows for security drivers to carry state / configuration
information directly. Thus the DAC/Stack drivers from src/qemu which
used to pull config from 'struct qemud_driver' can now be moved into
the 'src/security' directory and store their config directly.
* src/qemu/qemu_conf.h, src/qemu/qemu_driver.c: Update to
use new virSecurityManager APIs
* src/qemu/qemu_security_dac.c, src/qemu/qemu_security_dac.h
src/qemu/qemu_security_stacked.c, src/qemu/qemu_security_stacked.h:
Move into src/security directory
* src/security/security_stack.c, src/security/security_stack.h,
src/security/security_dac.c, src/security/security_dac.h: Generic
versions of previous QEMU specific drivers
* src/security/security_apparmor.c, src/security/security_apparmor.h,
src/security/security_driver.c, src/security/security_driver.h,
src/security/security_selinux.c, src/security/security_selinux.h:
Update to take virSecurityManagerPtr object as the first param
in all callbacks
* src/security/security_nop.c, src/security/security_nop.h: Stub
implementation of all security driver APIs.
* src/security/security_manager.h, src/security/security_manager.c:
New internal API for invoking security drivers
* src/libvirt.c: Add missing debug for security APIs
2010-11-17 20:26:30 +00:00
|
|
|
|
2012-05-24 16:42:51 +01:00
|
|
|
.domainSecurityVerify = virSecuritySELinuxSecurityVerify,
|
Refactor the security drivers to simplify usage
The current security driver usage requires horrible code like
if (driver->securityDriver &&
driver->securityDriver->domainSetSecurityHostdevLabel &&
driver->securityDriver->domainSetSecurityHostdevLabel(driver->securityDriver,
vm, hostdev) < 0)
This pair of checks for NULL clutters up the code, making the driver
calls 2 lines longer than they really need to be. The goal of the
patchset is to change the calling convention to simply
if (virSecurityManagerSetHostdevLabel(driver->securityDriver,
vm, hostdev) < 0)
The first check for 'driver->securityDriver' being NULL is removed
by introducing a 'no op' security driver that will always be present
if no real driver is enabled. This guarentees driver->securityDriver
!= NULL.
The second check for 'driver->securityDriver->domainSetSecurityHostdevLabel'
being non-NULL is hidden in a new abstraction called virSecurityManager.
This separates the driver callbacks, from main internal API. The addition
of a virSecurityManager object, that is separate from the virSecurityDriver
struct also allows for security drivers to carry state / configuration
information directly. Thus the DAC/Stack drivers from src/qemu which
used to pull config from 'struct qemud_driver' can now be moved into
the 'src/security' directory and store their config directly.
* src/qemu/qemu_conf.h, src/qemu/qemu_driver.c: Update to
use new virSecurityManager APIs
* src/qemu/qemu_security_dac.c, src/qemu/qemu_security_dac.h
src/qemu/qemu_security_stacked.c, src/qemu/qemu_security_stacked.h:
Move into src/security directory
* src/security/security_stack.c, src/security/security_stack.h,
src/security/security_dac.c, src/security/security_dac.h: Generic
versions of previous QEMU specific drivers
* src/security/security_apparmor.c, src/security/security_apparmor.h,
src/security/security_driver.c, src/security/security_driver.h,
src/security/security_selinux.c, src/security/security_selinux.h:
Update to take virSecurityManagerPtr object as the first param
in all callbacks
* src/security/security_nop.c, src/security/security_nop.h: Stub
implementation of all security driver APIs.
* src/security/security_manager.h, src/security/security_manager.c:
New internal API for invoking security drivers
* src/libvirt.c: Add missing debug for security APIs
2010-11-17 20:26:30 +00:00
|
|
|
|
2012-05-24 16:42:51 +01:00
|
|
|
.domainSetSecurityImageLabel = virSecuritySELinuxSetSecurityImageLabel,
|
|
|
|
.domainRestoreSecurityImageLabel = virSecuritySELinuxRestoreSecurityImageLabel,
|
Refactor the security drivers to simplify usage
The current security driver usage requires horrible code like
if (driver->securityDriver &&
driver->securityDriver->domainSetSecurityHostdevLabel &&
driver->securityDriver->domainSetSecurityHostdevLabel(driver->securityDriver,
vm, hostdev) < 0)
This pair of checks for NULL clutters up the code, making the driver
calls 2 lines longer than they really need to be. The goal of the
patchset is to change the calling convention to simply
if (virSecurityManagerSetHostdevLabel(driver->securityDriver,
vm, hostdev) < 0)
The first check for 'driver->securityDriver' being NULL is removed
by introducing a 'no op' security driver that will always be present
if no real driver is enabled. This guarentees driver->securityDriver
!= NULL.
The second check for 'driver->securityDriver->domainSetSecurityHostdevLabel'
being non-NULL is hidden in a new abstraction called virSecurityManager.
This separates the driver callbacks, from main internal API. The addition
of a virSecurityManager object, that is separate from the virSecurityDriver
struct also allows for security drivers to carry state / configuration
information directly. Thus the DAC/Stack drivers from src/qemu which
used to pull config from 'struct qemud_driver' can now be moved into
the 'src/security' directory and store their config directly.
* src/qemu/qemu_conf.h, src/qemu/qemu_driver.c: Update to
use new virSecurityManager APIs
* src/qemu/qemu_security_dac.c, src/qemu/qemu_security_dac.h
src/qemu/qemu_security_stacked.c, src/qemu/qemu_security_stacked.h:
Move into src/security directory
* src/security/security_stack.c, src/security/security_stack.h,
src/security/security_dac.c, src/security/security_dac.h: Generic
versions of previous QEMU specific drivers
* src/security/security_apparmor.c, src/security/security_apparmor.h,
src/security/security_driver.c, src/security/security_driver.h,
src/security/security_selinux.c, src/security/security_selinux.h:
Update to take virSecurityManagerPtr object as the first param
in all callbacks
* src/security/security_nop.c, src/security/security_nop.h: Stub
implementation of all security driver APIs.
* src/security/security_manager.h, src/security/security_manager.c:
New internal API for invoking security drivers
* src/libvirt.c: Add missing debug for security APIs
2010-11-17 20:26:30 +00:00
|
|
|
|
2012-05-24 16:42:51 +01:00
|
|
|
.domainSetSecurityDaemonSocketLabel = virSecuritySELinuxSetSecurityDaemonSocketLabel,
|
|
|
|
.domainSetSecuritySocketLabel = virSecuritySELinuxSetSecuritySocketLabel,
|
|
|
|
.domainClearSecuritySocketLabel = virSecuritySELinuxClearSecuritySocketLabel,
|
Refactor the security drivers to simplify usage
The current security driver usage requires horrible code like
if (driver->securityDriver &&
driver->securityDriver->domainSetSecurityHostdevLabel &&
driver->securityDriver->domainSetSecurityHostdevLabel(driver->securityDriver,
vm, hostdev) < 0)
This pair of checks for NULL clutters up the code, making the driver
calls 2 lines longer than they really need to be. The goal of the
patchset is to change the calling convention to simply
if (virSecurityManagerSetHostdevLabel(driver->securityDriver,
vm, hostdev) < 0)
The first check for 'driver->securityDriver' being NULL is removed
by introducing a 'no op' security driver that will always be present
if no real driver is enabled. This guarentees driver->securityDriver
!= NULL.
The second check for 'driver->securityDriver->domainSetSecurityHostdevLabel'
being non-NULL is hidden in a new abstraction called virSecurityManager.
This separates the driver callbacks, from main internal API. The addition
of a virSecurityManager object, that is separate from the virSecurityDriver
struct also allows for security drivers to carry state / configuration
information directly. Thus the DAC/Stack drivers from src/qemu which
used to pull config from 'struct qemud_driver' can now be moved into
the 'src/security' directory and store their config directly.
* src/qemu/qemu_conf.h, src/qemu/qemu_driver.c: Update to
use new virSecurityManager APIs
* src/qemu/qemu_security_dac.c, src/qemu/qemu_security_dac.h
src/qemu/qemu_security_stacked.c, src/qemu/qemu_security_stacked.h:
Move into src/security directory
* src/security/security_stack.c, src/security/security_stack.h,
src/security/security_dac.c, src/security/security_dac.h: Generic
versions of previous QEMU specific drivers
* src/security/security_apparmor.c, src/security/security_apparmor.h,
src/security/security_driver.c, src/security/security_driver.h,
src/security/security_selinux.c, src/security/security_selinux.h:
Update to take virSecurityManagerPtr object as the first param
in all callbacks
* src/security/security_nop.c, src/security/security_nop.h: Stub
implementation of all security driver APIs.
* src/security/security_manager.h, src/security/security_manager.c:
New internal API for invoking security drivers
* src/libvirt.c: Add missing debug for security APIs
2010-11-17 20:26:30 +00:00
|
|
|
|
2012-05-24 16:42:51 +01:00
|
|
|
.domainGenSecurityLabel = virSecuritySELinuxGenSecurityLabel,
|
|
|
|
.domainReserveSecurityLabel = virSecuritySELinuxReserveSecurityLabel,
|
|
|
|
.domainReleaseSecurityLabel = virSecuritySELinuxReleaseSecurityLabel,
|
Refactor the security drivers to simplify usage
The current security driver usage requires horrible code like
if (driver->securityDriver &&
driver->securityDriver->domainSetSecurityHostdevLabel &&
driver->securityDriver->domainSetSecurityHostdevLabel(driver->securityDriver,
vm, hostdev) < 0)
This pair of checks for NULL clutters up the code, making the driver
calls 2 lines longer than they really need to be. The goal of the
patchset is to change the calling convention to simply
if (virSecurityManagerSetHostdevLabel(driver->securityDriver,
vm, hostdev) < 0)
The first check for 'driver->securityDriver' being NULL is removed
by introducing a 'no op' security driver that will always be present
if no real driver is enabled. This guarentees driver->securityDriver
!= NULL.
The second check for 'driver->securityDriver->domainSetSecurityHostdevLabel'
being non-NULL is hidden in a new abstraction called virSecurityManager.
This separates the driver callbacks, from main internal API. The addition
of a virSecurityManager object, that is separate from the virSecurityDriver
struct also allows for security drivers to carry state / configuration
information directly. Thus the DAC/Stack drivers from src/qemu which
used to pull config from 'struct qemud_driver' can now be moved into
the 'src/security' directory and store their config directly.
* src/qemu/qemu_conf.h, src/qemu/qemu_driver.c: Update to
use new virSecurityManager APIs
* src/qemu/qemu_security_dac.c, src/qemu/qemu_security_dac.h
src/qemu/qemu_security_stacked.c, src/qemu/qemu_security_stacked.h:
Move into src/security directory
* src/security/security_stack.c, src/security/security_stack.h,
src/security/security_dac.c, src/security/security_dac.h: Generic
versions of previous QEMU specific drivers
* src/security/security_apparmor.c, src/security/security_apparmor.h,
src/security/security_driver.c, src/security/security_driver.h,
src/security/security_selinux.c, src/security/security_selinux.h:
Update to take virSecurityManagerPtr object as the first param
in all callbacks
* src/security/security_nop.c, src/security/security_nop.h: Stub
implementation of all security driver APIs.
* src/security/security_manager.h, src/security/security_manager.c:
New internal API for invoking security drivers
* src/libvirt.c: Add missing debug for security APIs
2010-11-17 20:26:30 +00:00
|
|
|
|
2012-05-24 16:42:51 +01:00
|
|
|
.domainGetSecurityProcessLabel = virSecuritySELinuxGetSecurityProcessLabel,
|
|
|
|
.domainSetSecurityProcessLabel = virSecuritySELinuxSetSecurityProcessLabel,
|
Refactor the security drivers to simplify usage
The current security driver usage requires horrible code like
if (driver->securityDriver &&
driver->securityDriver->domainSetSecurityHostdevLabel &&
driver->securityDriver->domainSetSecurityHostdevLabel(driver->securityDriver,
vm, hostdev) < 0)
This pair of checks for NULL clutters up the code, making the driver
calls 2 lines longer than they really need to be. The goal of the
patchset is to change the calling convention to simply
if (virSecurityManagerSetHostdevLabel(driver->securityDriver,
vm, hostdev) < 0)
The first check for 'driver->securityDriver' being NULL is removed
by introducing a 'no op' security driver that will always be present
if no real driver is enabled. This guarentees driver->securityDriver
!= NULL.
The second check for 'driver->securityDriver->domainSetSecurityHostdevLabel'
being non-NULL is hidden in a new abstraction called virSecurityManager.
This separates the driver callbacks, from main internal API. The addition
of a virSecurityManager object, that is separate from the virSecurityDriver
struct also allows for security drivers to carry state / configuration
information directly. Thus the DAC/Stack drivers from src/qemu which
used to pull config from 'struct qemud_driver' can now be moved into
the 'src/security' directory and store their config directly.
* src/qemu/qemu_conf.h, src/qemu/qemu_driver.c: Update to
use new virSecurityManager APIs
* src/qemu/qemu_security_dac.c, src/qemu/qemu_security_dac.h
src/qemu/qemu_security_stacked.c, src/qemu/qemu_security_stacked.h:
Move into src/security directory
* src/security/security_stack.c, src/security/security_stack.h,
src/security/security_dac.c, src/security/security_dac.h: Generic
versions of previous QEMU specific drivers
* src/security/security_apparmor.c, src/security/security_apparmor.h,
src/security/security_driver.c, src/security/security_driver.h,
src/security/security_selinux.c, src/security/security_selinux.h:
Update to take virSecurityManagerPtr object as the first param
in all callbacks
* src/security/security_nop.c, src/security/security_nop.h: Stub
implementation of all security driver APIs.
* src/security/security_manager.h, src/security/security_manager.c:
New internal API for invoking security drivers
* src/libvirt.c: Add missing debug for security APIs
2010-11-17 20:26:30 +00:00
|
|
|
|
2012-05-24 16:42:51 +01:00
|
|
|
.domainSetSecurityAllLabel = virSecuritySELinuxSetSecurityAllLabel,
|
|
|
|
.domainRestoreSecurityAllLabel = virSecuritySELinuxRestoreSecurityAllLabel,
|
Refactor the security drivers to simplify usage
The current security driver usage requires horrible code like
if (driver->securityDriver &&
driver->securityDriver->domainSetSecurityHostdevLabel &&
driver->securityDriver->domainSetSecurityHostdevLabel(driver->securityDriver,
vm, hostdev) < 0)
This pair of checks for NULL clutters up the code, making the driver
calls 2 lines longer than they really need to be. The goal of the
patchset is to change the calling convention to simply
if (virSecurityManagerSetHostdevLabel(driver->securityDriver,
vm, hostdev) < 0)
The first check for 'driver->securityDriver' being NULL is removed
by introducing a 'no op' security driver that will always be present
if no real driver is enabled. This guarentees driver->securityDriver
!= NULL.
The second check for 'driver->securityDriver->domainSetSecurityHostdevLabel'
being non-NULL is hidden in a new abstraction called virSecurityManager.
This separates the driver callbacks, from main internal API. The addition
of a virSecurityManager object, that is separate from the virSecurityDriver
struct also allows for security drivers to carry state / configuration
information directly. Thus the DAC/Stack drivers from src/qemu which
used to pull config from 'struct qemud_driver' can now be moved into
the 'src/security' directory and store their config directly.
* src/qemu/qemu_conf.h, src/qemu/qemu_driver.c: Update to
use new virSecurityManager APIs
* src/qemu/qemu_security_dac.c, src/qemu/qemu_security_dac.h
src/qemu/qemu_security_stacked.c, src/qemu/qemu_security_stacked.h:
Move into src/security directory
* src/security/security_stack.c, src/security/security_stack.h,
src/security/security_dac.c, src/security/security_dac.h: Generic
versions of previous QEMU specific drivers
* src/security/security_apparmor.c, src/security/security_apparmor.h,
src/security/security_driver.c, src/security/security_driver.h,
src/security/security_selinux.c, src/security/security_selinux.h:
Update to take virSecurityManagerPtr object as the first param
in all callbacks
* src/security/security_nop.c, src/security/security_nop.h: Stub
implementation of all security driver APIs.
* src/security/security_manager.h, src/security/security_manager.c:
New internal API for invoking security drivers
* src/libvirt.c: Add missing debug for security APIs
2010-11-17 20:26:30 +00:00
|
|
|
|
2012-05-24 16:42:51 +01:00
|
|
|
.domainSetSecurityHostdevLabel = virSecuritySELinuxSetSecurityHostdevLabel,
|
|
|
|
.domainRestoreSecurityHostdevLabel = virSecuritySELinuxRestoreSecurityHostdevLabel,
|
Refactor the security drivers to simplify usage
The current security driver usage requires horrible code like
if (driver->securityDriver &&
driver->securityDriver->domainSetSecurityHostdevLabel &&
driver->securityDriver->domainSetSecurityHostdevLabel(driver->securityDriver,
vm, hostdev) < 0)
This pair of checks for NULL clutters up the code, making the driver
calls 2 lines longer than they really need to be. The goal of the
patchset is to change the calling convention to simply
if (virSecurityManagerSetHostdevLabel(driver->securityDriver,
vm, hostdev) < 0)
The first check for 'driver->securityDriver' being NULL is removed
by introducing a 'no op' security driver that will always be present
if no real driver is enabled. This guarentees driver->securityDriver
!= NULL.
The second check for 'driver->securityDriver->domainSetSecurityHostdevLabel'
being non-NULL is hidden in a new abstraction called virSecurityManager.
This separates the driver callbacks, from main internal API. The addition
of a virSecurityManager object, that is separate from the virSecurityDriver
struct also allows for security drivers to carry state / configuration
information directly. Thus the DAC/Stack drivers from src/qemu which
used to pull config from 'struct qemud_driver' can now be moved into
the 'src/security' directory and store their config directly.
* src/qemu/qemu_conf.h, src/qemu/qemu_driver.c: Update to
use new virSecurityManager APIs
* src/qemu/qemu_security_dac.c, src/qemu/qemu_security_dac.h
src/qemu/qemu_security_stacked.c, src/qemu/qemu_security_stacked.h:
Move into src/security directory
* src/security/security_stack.c, src/security/security_stack.h,
src/security/security_dac.c, src/security/security_dac.h: Generic
versions of previous QEMU specific drivers
* src/security/security_apparmor.c, src/security/security_apparmor.h,
src/security/security_driver.c, src/security/security_driver.h,
src/security/security_selinux.c, src/security/security_selinux.h:
Update to take virSecurityManagerPtr object as the first param
in all callbacks
* src/security/security_nop.c, src/security/security_nop.h: Stub
implementation of all security driver APIs.
* src/security/security_manager.h, src/security/security_manager.c:
New internal API for invoking security drivers
* src/libvirt.c: Add missing debug for security APIs
2010-11-17 20:26:30 +00:00
|
|
|
|
2012-05-24 16:42:51 +01:00
|
|
|
.domainSetSavedStateLabel = virSecuritySELinuxSetSavedStateLabel,
|
|
|
|
.domainRestoreSavedStateLabel = virSecuritySELinuxRestoreSavedStateLabel,
|
2011-01-23 16:02:42 -05:00
|
|
|
|
2012-05-24 16:42:51 +01:00
|
|
|
.domainSetSecurityImageFDLabel = virSecuritySELinuxSetImageFDLabel,
|
2012-10-15 17:03:49 +08:00
|
|
|
.domainSetSecurityTapFDLabel = virSecuritySELinuxSetTapFDLabel,
|
2012-05-01 15:16:04 +01:00
|
|
|
|
2012-05-24 16:42:51 +01:00
|
|
|
.domainGetSecurityMountOptions = virSecuritySELinuxGetSecurityMountOptions,
|
2009-03-03 10:06:49 +00:00
|
|
|
};
|