2009-10-08 16:34:22 +02:00
|
|
|
/*
|
|
|
|
* AppArmor security driver for libvirt
|
2012-07-21 18:06:23 +08:00
|
|
|
*
|
conf: move host disk type to util/
A continuation of the migration of disk details to virstoragefile.
This patch moves a single enum, but converting the name has quite
a bit of fallout.
* src/conf/domain_conf.h (virDomainDiskType): Move...
* src/util/virstoragefile.h (virStorageType): ...and rename.
* src/bhyve/bhyve_command.c (bhyveBuildDiskArgStr)
(virBhyveProcessBuildLoadCmd): Update clients.
* src/conf/domain_conf.c (virDomainDiskSourceDefParse)
(virDomainDiskDefParseXML, virDomainDiskSourceDefFormatInternal)
(virDomainDiskDefFormat, virDomainDiskGetActualType)
(virDomainDiskDefForeachPath, virDomainDiskSourceIsBlockType):
Likewise.
* src/conf/snapshot_conf.h (_virDomainSnapshotDiskDef): Likewise.
* src/conf/snapshot_conf.c (virDomainSnapshotDiskDefParseXML)
(virDomainSnapshotAlignDisks, virDomainSnapshotDiskDefFormat):
Likewise.
* src/esx/esx_driver.c (esxAutodetectSCSIControllerModel)
(esxDomainDefineXML): Likewise.
* src/locking/domain_lock.c (virDomainLockManagerAddDisk):
Likewise.
* src/lxc/lxc_controller.c
(virLXCControllerSetupLoopDeviceDisk)
(virLXCControllerSetupNBDDeviceDisk)
(virLXCControllerSetupLoopDevices, virLXCControllerSetupDisk):
Likewise.
* src/parallels/parallels_driver.c (parallelsGetHddInfo):
Likewise.
* src/phyp/phyp_driver.c (phypDiskType): Likewise.
* src/qemu/qemu_command.c (qemuGetDriveSourceString)
(qemuDomainDiskGetSourceString, qemuBuildDriveStr)
(qemuBuildCommandLine, qemuParseCommandLineDisk)
(qemuParseCommandLine): Likewise.
* src/qemu/qemu_conf.c (qemuCheckSharedDevice)
(qemuTranslateDiskSourcePool)
(qemuTranslateSnapshotDiskSourcePool): Likewise.
* src/qemu/qemu_domain.c (qemuDomainDeviceDefPostParse)
(qemuDomainDetermineDiskChain): Likewise.
* src/qemu/qemu_driver.c (qemuDomainGetBlockInfo)
(qemuDomainSnapshotPrepareDiskExternalBackingInactive)
(qemuDomainSnapshotPrepareDiskExternalBackingActive)
(qemuDomainSnapshotPrepareDiskExternalOverlayActive)
(qemuDomainSnapshotPrepareDiskExternalOverlayInactive)
(qemuDomainSnapshotPrepareDiskInternal)
(qemuDomainSnapshotPrepare)
(qemuDomainSnapshotCreateSingleDiskActive): Likewise.
* src/qemu/qemu_hotplug.c (qemuDomainChangeEjectableMedia):
Likewise.
* src/qemu/qemu_migration.c (qemuMigrationIsSafe): Likewise.
* src/security/security_apparmor.c
(AppArmorRestoreSecurityImageLabel)
(AppArmorSetSecurityImageLabel): Likewise.
* src/security/security_dac.c (virSecurityDACSetSecurityImageLabel)
(virSecurityDACRestoreSecurityImageLabelInt)
(virSecurityDACSetSecurityAllLabel): Likewise.
* src/security/security_selinux.c
(virSecuritySELinuxRestoreSecurityImageLabelInt)
(virSecuritySELinuxSetSecurityImageLabel)
(virSecuritySELinuxSetSecurityAllLabel): Likewise.
* src/storage/storage_backend.c (virStorageFileBackendForType):
Likewise.
* src/storage/storage_backend_fs.c (virStorageFileBackendFile)
(virStorageFileBackendBlock): Likewise.
* src/storage/storage_backend_gluster.c
(virStorageFileBackendGluster): Likewise.
* src/vbox/vbox_tmpl.c (vboxDomainGetXMLDesc, vboxAttachDrives)
(vboxDomainAttachDeviceImpl, vboxDomainDetachDevice): Likewise.
* src/vmware/vmware_conf.c (vmwareVmxPath): Likewise.
* src/vmx/vmx.c (virVMXParseDisk, virVMXFormatDisk)
(virVMXFormatFloppy): Likewise.
* src/xenxs/xen_sxpr.c (xenParseSxprDisks, xenParseSxpr)
(xenFormatSxprDisk): Likewise.
* src/xenxs/xen_xm.c (xenParseXM, xenFormatXMDisk): Likewise.
* tests/securityselinuxlabeltest.c (testSELinuxLoadDef):
Likewise.
* src/libvirt_private.syms (domain_conf.h): Move symbols...
(virstoragefile.h): ...as appropriate.
Signed-off-by: Eric Blake <eblake@redhat.com>
2014-03-27 15:57:49 -06:00
|
|
|
* Copyright (C) 2011-2014 Red Hat, Inc.
|
2010-09-30 14:54:56 -06:00
|
|
|
* Copyright (C) 2009-2010 Canonical Ltd.
|
2009-10-08 16:34:22 +02: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-10-08 16:34:22 +02:00
|
|
|
*/
|
|
|
|
|
|
|
|
#include <config.h>
|
|
|
|
|
|
|
|
#include <sys/types.h>
|
|
|
|
#include <sys/stat.h>
|
|
|
|
#include <fcntl.h>
|
|
|
|
#include <sys/apparmor.h>
|
|
|
|
#include <unistd.h>
|
2022-03-03 13:17:02 +01:00
|
|
|
#include <sys/wait.h>
|
2009-10-08 16:34:22 +02:00
|
|
|
|
|
|
|
#include "internal.h"
|
|
|
|
|
|
|
|
#include "security_apparmor.h"
|
2012-12-12 18:06:53 +00:00
|
|
|
#include "viralloc.h"
|
2012-12-13 18:21:53 +00:00
|
|
|
#include "virerror.h"
|
2009-10-08 16:34:22 +02:00
|
|
|
#include "datatypes.h"
|
2012-12-13 18:01:25 +00:00
|
|
|
#include "viruuid.h"
|
2012-12-13 14:52:25 +00:00
|
|
|
#include "virpci.h"
|
2012-12-12 17:04:51 +00:00
|
|
|
#include "virusb.h"
|
2016-11-21 22:58:21 -05:00
|
|
|
#include "virscsivhost.h"
|
2011-07-19 12:32:58 -06:00
|
|
|
#include "virfile.h"
|
2010-11-16 07:54:17 -07:00
|
|
|
#include "configmake.h"
|
2012-12-12 16:27:01 +00:00
|
|
|
#include "vircommand.h"
|
2012-12-12 17:59:27 +00:00
|
|
|
#include "virlog.h"
|
2013-04-03 12:36:23 +02:00
|
|
|
#include "virstring.h"
|
2013-05-13 14:01:14 +02:00
|
|
|
#include "virscsi.h"
|
2017-02-03 13:25:57 +01:00
|
|
|
#include "virmdev.h"
|
2009-10-08 16:34:22 +02:00
|
|
|
|
|
|
|
#define VIR_FROM_THIS VIR_FROM_SECURITY
|
2014-02-28 12:16:17 +00:00
|
|
|
|
|
|
|
VIR_LOG_INIT("security.security_apparmor");
|
|
|
|
|
2009-10-08 16:34:22 +02:00
|
|
|
#define SECURITY_APPARMOR_VOID_DOI "0"
|
|
|
|
#define SECURITY_APPARMOR_NAME "apparmor"
|
2010-11-16 07:54:17 -07:00
|
|
|
#define VIRT_AA_HELPER LIBEXECDIR "/virt-aa-helper"
|
2009-10-08 16:34:22 +02:00
|
|
|
|
2010-09-30 14:54:56 -06:00
|
|
|
/* Data structure to pass to *FileIterate so we have everything we need */
|
|
|
|
struct SDPDOP {
|
2021-03-11 08:16:13 +01:00
|
|
|
virSecurityManager *mgr;
|
|
|
|
virDomainDef *def;
|
2010-09-30 14:54:56 -06:00
|
|
|
};
|
|
|
|
|
2009-10-08 16:34:22 +02:00
|
|
|
/*
|
2015-10-06 11:12:29 +02:00
|
|
|
* profile_status returns '-2' on error, '-1' if not loaded, '0' if loaded
|
2009-10-08 16:34:22 +02:00
|
|
|
*
|
2015-10-06 11:12:29 +02:00
|
|
|
* If check_enforcing is set to '1', then returns '-2' on error, '-1' if
|
|
|
|
* not loaded, '0' if loaded in complain mode, and '1' if loaded in
|
|
|
|
* enforcing mode.
|
2009-10-08 16:34:22 +02:00
|
|
|
*/
|
|
|
|
static int
|
|
|
|
profile_status(const char *str, const int check_enforcing)
|
|
|
|
{
|
|
|
|
char *content = NULL;
|
|
|
|
char *tmp = NULL;
|
|
|
|
char *etmp = NULL;
|
2015-10-06 11:12:29 +02:00
|
|
|
int rc = -2;
|
2009-10-08 16:34:22 +02:00
|
|
|
|
|
|
|
/* create string that is '<str> \0' for accurate matching */
|
2019-10-22 15:26:14 +02:00
|
|
|
tmp = g_strdup_printf("%s ", str);
|
2009-10-08 16:34:22 +02:00
|
|
|
|
|
|
|
if (check_enforcing != 0) {
|
|
|
|
/* create string that is '<str> (enforce)\0' for accurate matching */
|
2019-10-22 15:26:14 +02:00
|
|
|
etmp = g_strdup_printf("%s (enforce)", str);
|
2009-10-08 16:34:22 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
if (virFileReadAll(APPARMOR_PROFILES_PATH, MAX_FILE_LEN, &content) < 0) {
|
2010-02-04 21:02:58 +01:00
|
|
|
virReportSystemError(errno,
|
2009-10-08 16:34:22 +02:00
|
|
|
_("Failed to read AppArmor profiles list "
|
|
|
|
"\'%s\'"), APPARMOR_PROFILES_PATH);
|
2013-04-29 18:38:21 +01:00
|
|
|
goto cleanup;
|
2009-10-08 16:34:22 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
if (strstr(content, tmp) != NULL)
|
|
|
|
rc = 0;
|
2015-10-06 11:12:29 +02:00
|
|
|
else
|
|
|
|
rc = -1; /* return -1 if not loaded */
|
2009-10-08 16:34:22 +02:00
|
|
|
if (check_enforcing != 0) {
|
|
|
|
if (rc == 0 && strstr(content, etmp) != NULL)
|
|
|
|
rc = 1; /* return '1' if loaded and enforcing */
|
|
|
|
}
|
|
|
|
|
|
|
|
VIR_FREE(content);
|
2014-03-25 07:57:22 +01:00
|
|
|
cleanup:
|
2009-10-08 16:34:22 +02:00
|
|
|
VIR_FREE(tmp);
|
2009-11-13 15:27:43 +01:00
|
|
|
VIR_FREE(etmp);
|
2009-10-08 16:34:22 +02:00
|
|
|
|
|
|
|
return rc;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
profile_loaded(const char *str)
|
|
|
|
{
|
|
|
|
return profile_status(str, 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* profile_status_file returns '-1' on error, '0' if file on disk is in
|
|
|
|
* complain mode and '1' if file on disk is in enforcing mode
|
|
|
|
*/
|
|
|
|
static int
|
|
|
|
profile_status_file(const char *str)
|
|
|
|
{
|
2009-11-13 15:27:43 +01:00
|
|
|
char *profile = NULL;
|
2009-10-08 16:34:22 +02:00
|
|
|
char *content = NULL;
|
|
|
|
char *tmp = NULL;
|
|
|
|
int rc = -1;
|
|
|
|
int len;
|
|
|
|
|
2019-10-22 15:26:14 +02:00
|
|
|
profile = g_strdup_printf("%s/%s", APPARMOR_DIR "/libvirt", str);
|
2009-10-08 16:34:22 +02:00
|
|
|
|
2009-11-13 15:27:43 +01:00
|
|
|
if (!virFileExists(profile))
|
|
|
|
goto failed;
|
|
|
|
|
2009-10-08 16:34:22 +02:00
|
|
|
if ((len = virFileReadAll(profile, MAX_FILE_LEN, &content)) < 0) {
|
2010-02-04 21:02:58 +01:00
|
|
|
virReportSystemError(errno,
|
2009-10-08 16:34:22 +02:00
|
|
|
_("Failed to read \'%s\'"), profile);
|
2009-11-13 15:27:43 +01:00
|
|
|
goto failed;
|
2009-10-08 16:34:22 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/* create string that is ' <str> flags=(complain)\0' */
|
2019-10-22 15:26:14 +02:00
|
|
|
tmp = g_strdup_printf(" %s flags=(complain)", str);
|
2009-10-08 16:34:22 +02:00
|
|
|
|
|
|
|
if (strstr(content, tmp) != NULL)
|
|
|
|
rc = 0;
|
|
|
|
else
|
|
|
|
rc = 1;
|
|
|
|
|
2014-03-25 07:57:22 +01:00
|
|
|
failed:
|
2009-10-08 16:34:22 +02:00
|
|
|
VIR_FREE(tmp);
|
2009-11-13 15:27:43 +01:00
|
|
|
VIR_FREE(profile);
|
2009-10-08 16:34:22 +02:00
|
|
|
VIR_FREE(content);
|
|
|
|
|
|
|
|
return rc;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* load (add) a profile. Will create one if necessary
|
|
|
|
*/
|
|
|
|
static int
|
2021-03-11 08:16:13 +01:00
|
|
|
load_profile(virSecurityManager *mgr G_GNUC_UNUSED,
|
2010-09-30 14:54:56 -06:00
|
|
|
const char *profile,
|
2021-03-11 08:16:13 +01:00
|
|
|
virDomainDef *def,
|
2010-09-30 14:54:56 -06:00
|
|
|
const char *fn,
|
|
|
|
bool append)
|
2009-10-08 16:34:22 +02:00
|
|
|
{
|
|
|
|
bool create = true;
|
2021-12-13 14:06:17 +01:00
|
|
|
g_autofree char *xml = NULL;
|
|
|
|
g_autoptr(virCommand) cmd = NULL;
|
2009-10-08 16:34:22 +02:00
|
|
|
|
2019-11-27 11:57:34 +00:00
|
|
|
xml = virDomainDefFormat(def, NULL, VIR_DOMAIN_DEF_FORMAT_SECURE);
|
2009-10-08 16:34:22 +02:00
|
|
|
if (!xml)
|
2021-12-13 14:06:17 +01:00
|
|
|
return -1;
|
2009-10-08 16:34:22 +02:00
|
|
|
|
|
|
|
if (profile_status_file(profile) >= 0)
|
|
|
|
create = false;
|
|
|
|
|
2018-06-04 09:00:41 +02:00
|
|
|
cmd = virCommandNewArgList(VIRT_AA_HELPER,
|
2011-05-06 14:48:26 -04:00
|
|
|
create ? "-c" : "-r",
|
|
|
|
"-u", profile, NULL);
|
|
|
|
if (!create && fn) {
|
|
|
|
if (append) {
|
|
|
|
virCommandAddArgList(cmd, "-F", fn, NULL);
|
|
|
|
} else {
|
|
|
|
virCommandAddArgList(cmd, "-f", fn, NULL);
|
|
|
|
}
|
2009-10-08 16:34:22 +02:00
|
|
|
}
|
|
|
|
|
2015-06-25 10:36:52 +02:00
|
|
|
virCommandAddEnvFormat(cmd,
|
|
|
|
"LIBVIRT_LOG_OUTPUTS=%d:stderr",
|
|
|
|
virLogGetDefaultPriority());
|
|
|
|
|
2011-05-06 14:48:26 -04:00
|
|
|
virCommandSetInputBuffer(cmd, xml);
|
2021-12-13 14:06:17 +01:00
|
|
|
return virCommandRun(cmd, NULL);
|
2009-10-08 16:34:22 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
remove_profile(const char *profile)
|
|
|
|
{
|
2020-04-22 16:25:24 +02:00
|
|
|
g_autoptr(virCommand) cmd = virCommandNewArgList(VIRT_AA_HELPER, "-D", "-u",
|
|
|
|
profile, NULL);
|
2009-10-08 16:34:22 +02:00
|
|
|
|
2020-04-22 16:25:24 +02:00
|
|
|
return virCommandRun(cmd, NULL);
|
2009-10-08 16:34:22 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
static char *
|
2021-03-11 08:16:13 +01:00
|
|
|
get_profile_name(virDomainDef *def)
|
2009-10-08 16:34:22 +02:00
|
|
|
{
|
|
|
|
char uuidstr[VIR_UUID_STRING_BUFLEN];
|
|
|
|
|
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
|
|
|
virUUIDFormat(def->uuid, uuidstr);
|
2020-05-04 17:03:42 +02:00
|
|
|
return g_strdup_printf("%s%s", AA_PREFIX, uuidstr);
|
2009-10-08 16:34:22 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/* returns -1 on error or profile for libvirtd is unconfined, 0 if complain
|
|
|
|
* mode and 1 if enforcing. This is required because at present you cannot
|
|
|
|
* aa_change_profile() from a process that is unconfined.
|
|
|
|
*/
|
|
|
|
static int
|
|
|
|
use_apparmor(void)
|
|
|
|
{
|
|
|
|
int rc = -1;
|
2010-01-20 16:12:43 -05:00
|
|
|
char *libvirt_daemon = NULL;
|
2009-10-08 16:34:22 +02:00
|
|
|
|
2010-01-20 16:12:43 -05:00
|
|
|
if (virFileResolveLink("/proc/self/exe", &libvirt_daemon) < 0) {
|
2012-07-18 15:39:18 +01:00
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
|
"%s", _("could not find libvirtd"));
|
2009-10-08 16:34:22 +02:00
|
|
|
return rc;
|
|
|
|
}
|
|
|
|
|
2014-03-03 11:26:42 +01:00
|
|
|
/* If libvirt_lxc is calling us, then consider apparmor is used
|
|
|
|
* and enforced. */
|
|
|
|
if (strstr(libvirt_daemon, "libvirt_lxc"))
|
|
|
|
return 1;
|
|
|
|
|
2009-10-08 16:34:22 +02:00
|
|
|
if (access(APPARMOR_PROFILES_PATH, R_OK) != 0)
|
2010-01-20 16:12:43 -05:00
|
|
|
goto cleanup;
|
|
|
|
|
2019-03-01 14:34:17 -07:00
|
|
|
/* First check profile status using full binary path. If that fails
|
|
|
|
* check using profile name.
|
|
|
|
*/
|
2010-01-20 16:12:43 -05:00
|
|
|
rc = profile_status(libvirt_daemon, 1);
|
2019-03-01 14:34:17 -07:00
|
|
|
if (rc < 0) {
|
|
|
|
rc = profile_status("libvirtd", 1);
|
2020-01-24 21:30:04 +01:00
|
|
|
/* Error or unconfined should all result in -1 */
|
2019-03-01 14:34:17 -07:00
|
|
|
if (rc < 0)
|
|
|
|
rc = -1;
|
|
|
|
}
|
2009-10-08 16:34:22 +02:00
|
|
|
|
2014-03-25 07:57:22 +01:00
|
|
|
cleanup:
|
2010-01-20 16:12:43 -05:00
|
|
|
VIR_FREE(libvirt_daemon);
|
|
|
|
return rc;
|
2009-10-08 16:34:22 +02:00
|
|
|
}
|
|
|
|
|
2010-06-04 12:20:29 -04:00
|
|
|
/* reload the profile, adding read/write file specified by fn if it is not
|
|
|
|
* NULL.
|
|
|
|
*/
|
|
|
|
static int
|
2021-03-11 08:16:13 +01:00
|
|
|
reload_profile(virSecurityManager *mgr,
|
|
|
|
virDomainDef *def,
|
2010-09-30 14:54:56 -06:00
|
|
|
const char *fn,
|
|
|
|
bool append)
|
2010-06-04 12:20:29 -04:00
|
|
|
{
|
2021-03-11 08:16:13 +01:00
|
|
|
virSecurityLabelDef *secdef = virDomainDefGetSecurityLabelDef(
|
2012-08-15 19:10:37 -03:00
|
|
|
def, SECURITY_APPARMOR_NAME);
|
|
|
|
|
2017-02-02 19:26:13 -07:00
|
|
|
if (!secdef || !secdef->relabel)
|
2010-06-04 12:20:29 -04:00
|
|
|
return 0;
|
|
|
|
|
|
|
|
/* Update the profile only if it is loaded */
|
|
|
|
if (profile_loaded(secdef->imagelabel) >= 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
|
|
|
if (load_profile(mgr, secdef->imagelabel, def, fn, append) < 0) {
|
2012-07-18 15:39:18 +01:00
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
|
_("cannot update AppArmor profile "
|
|
|
|
"\'%s\'"),
|
|
|
|
secdef->imagelabel);
|
2019-10-16 09:15:14 +02:00
|
|
|
return -1;
|
2010-06-04 12:20:29 -04:00
|
|
|
}
|
|
|
|
}
|
2019-10-16 09:15:14 +02:00
|
|
|
return 0;
|
2010-06-04 12:20:29 -04:00
|
|
|
}
|
|
|
|
|
2010-09-30 14:54:56 -06:00
|
|
|
static int
|
2013-05-04 02:07:28 +08:00
|
|
|
AppArmorSetSecurityHostdevLabelHelper(const char *file, void *opaque)
|
2010-09-30 14:54:56 -06:00
|
|
|
{
|
|
|
|
struct SDPDOP *ptr = opaque;
|
2021-03-11 08:16:13 +01:00
|
|
|
virDomainDef *def = ptr->def;
|
2010-09-30 14:54:56 -06:00
|
|
|
|
2017-02-02 19:17:29 -07:00
|
|
|
return reload_profile(ptr->mgr, def, file, true);
|
2010-09-30 14:54:56 -06:00
|
|
|
}
|
|
|
|
|
2013-05-04 02:07:28 +08:00
|
|
|
static int
|
2021-03-11 08:16:13 +01:00
|
|
|
AppArmorSetSecurityUSBLabel(virUSBDevice *dev G_GNUC_UNUSED,
|
2013-05-04 02:07:28 +08:00
|
|
|
const char *file, void *opaque)
|
|
|
|
{
|
|
|
|
return AppArmorSetSecurityHostdevLabelHelper(file, opaque);
|
|
|
|
}
|
|
|
|
|
2010-09-30 14:54:56 -06:00
|
|
|
static int
|
2021-03-11 08:16:13 +01:00
|
|
|
AppArmorSetSecurityPCILabel(virPCIDevice *dev G_GNUC_UNUSED,
|
2013-01-14 22:11:44 +00:00
|
|
|
const char *file, void *opaque)
|
2010-09-30 14:54:56 -06:00
|
|
|
{
|
2013-05-04 02:07:28 +08:00
|
|
|
return AppArmorSetSecurityHostdevLabelHelper(file, opaque);
|
|
|
|
}
|
2010-09-30 14:54:56 -06:00
|
|
|
|
2013-05-04 02:07:28 +08:00
|
|
|
static int
|
2021-03-11 08:16:13 +01:00
|
|
|
AppArmorSetSecuritySCSILabel(virSCSIDevice *dev G_GNUC_UNUSED,
|
2013-05-04 02:07:28 +08:00
|
|
|
const char *file, void *opaque)
|
|
|
|
{
|
|
|
|
return AppArmorSetSecurityHostdevLabelHelper(file, opaque);
|
2010-09-30 14:54:56 -06:00
|
|
|
}
|
|
|
|
|
2016-11-21 22:58:21 -05:00
|
|
|
static int
|
2021-03-11 08:16:13 +01:00
|
|
|
AppArmorSetSecurityHostLabel(virSCSIVHostDevice *dev G_GNUC_UNUSED,
|
2016-11-21 22:58:21 -05:00
|
|
|
const char *file, void *opaque)
|
|
|
|
{
|
|
|
|
return AppArmorSetSecurityHostdevLabelHelper(file, opaque);
|
|
|
|
}
|
|
|
|
|
2009-10-08 16:34:22 +02:00
|
|
|
/* Called on libvirtd startup to see if AppArmor is available */
|
|
|
|
static int
|
2019-10-14 14:45:33 +02:00
|
|
|
AppArmorSecurityManagerProbe(const char *virtDriver G_GNUC_UNUSED)
|
2009-10-08 16:34:22 +02:00
|
|
|
{
|
2014-07-15 11:02:50 +02:00
|
|
|
char *template_qemu = NULL;
|
|
|
|
char *template_lxc = NULL;
|
2009-11-13 15:27:43 +01:00
|
|
|
int rc = SECURITY_DRIVER_DISABLE;
|
2009-10-08 16:34:22 +02:00
|
|
|
|
|
|
|
if (use_apparmor() < 0)
|
2009-11-13 15:27:43 +01:00
|
|
|
return rc;
|
2009-10-08 16:34:22 +02:00
|
|
|
|
|
|
|
/* see if template file exists */
|
2019-10-22 15:26:14 +02:00
|
|
|
template_qemu = g_strdup_printf("%s/TEMPLATE.qemu", APPARMOR_DIR "/libvirt");
|
|
|
|
template_lxc = g_strdup_printf("%s/TEMPLATE.lxc", APPARMOR_DIR "/libvirt");
|
2014-07-15 11:02:50 +02:00
|
|
|
|
|
|
|
if (!virFileExists(template_qemu)) {
|
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
|
_("template \'%s\' does not exist"), template_qemu);
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
if (!virFileExists(template_lxc)) {
|
2012-07-18 15:39:18 +01:00
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
2014-07-15 11:02:50 +02:00
|
|
|
_("template \'%s\' does not exist"), template_lxc);
|
2013-04-29 18:38:21 +01:00
|
|
|
goto cleanup;
|
2009-10-08 16:34:22 +02:00
|
|
|
}
|
2009-11-13 15:27:43 +01:00
|
|
|
rc = SECURITY_DRIVER_ENABLE;
|
2009-10-08 16:34:22 +02:00
|
|
|
|
2014-03-25 07:57:22 +01:00
|
|
|
cleanup:
|
2014-07-15 11:02:50 +02:00
|
|
|
VIR_FREE(template_qemu);
|
|
|
|
VIR_FREE(template_lxc);
|
2009-11-13 15:27:43 +01:00
|
|
|
|
|
|
|
return rc;
|
2009-10-08 16:34:22 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Security driver initialization. DOI is for 'Domain of Interpretation' and is
|
|
|
|
* currently not used.
|
|
|
|
*/
|
|
|
|
static int
|
2021-03-11 08:16:13 +01:00
|
|
|
AppArmorSecurityManagerOpen(virSecurityManager *mgr G_GNUC_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 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
2021-03-11 08:16:13 +01:00
|
|
|
AppArmorSecurityManagerClose(virSecurityManager *mgr G_GNUC_UNUSED)
|
2009-10-08 16:34:22 +02: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
|
|
|
static const char *
|
2021-03-11 08:16:13 +01:00
|
|
|
AppArmorSecurityManagerGetModel(virSecurityManager *mgr G_GNUC_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_APPARMOR_NAME;
|
|
|
|
}
|
|
|
|
|
|
|
|
static const char *
|
2021-03-11 08:16:13 +01:00
|
|
|
AppArmorSecurityManagerGetDOI(virSecurityManager *mgr G_GNUC_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_APPARMOR_VOID_DOI;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2009-10-08 16:34:22 +02:00
|
|
|
/* Currently called in qemudStartVMDaemon to setup a 'label'. We look for and
|
|
|
|
* use a profile based on the UUID, otherwise create one based on a template.
|
|
|
|
* Keep in mind that this is called on 'start' with RestoreSecurityLabel being
|
|
|
|
* called on shutdown.
|
|
|
|
*/
|
|
|
|
static int
|
2021-03-11 08:16:13 +01:00
|
|
|
AppArmorGenSecurityLabel(virSecurityManager *mgr G_GNUC_UNUSED,
|
|
|
|
virDomainDef *def)
|
2009-10-08 16:34:22 +02:00
|
|
|
{
|
|
|
|
int rc = -1;
|
|
|
|
char *profile_name = NULL;
|
2021-03-11 08:16:13 +01:00
|
|
|
virSecurityLabelDef *secdef = virDomainDefGetSecurityLabelDef(def,
|
2012-08-15 19:10:37 -03:00
|
|
|
SECURITY_APPARMOR_NAME);
|
2009-10-08 16:34:22 +02:00
|
|
|
|
2012-08-15 19:10:37 -03:00
|
|
|
if (!secdef)
|
2017-02-02 19:26:13 -07:00
|
|
|
return 0;
|
2012-08-15 19:10:37 -03:00
|
|
|
|
2014-03-03 11:26:46 +01:00
|
|
|
if ((secdef->type == VIR_DOMAIN_SECLABEL_STATIC) ||
|
|
|
|
(secdef->type == VIR_DOMAIN_SECLABEL_NONE))
|
2010-01-13 14:03:04 +00:00
|
|
|
return 0;
|
|
|
|
|
2012-08-15 19:10:37 -03:00
|
|
|
if (secdef->baselabel) {
|
2012-07-18 15:39:18 +01:00
|
|
|
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
|
|
|
|
"%s", _("Cannot set a base label with AppArmour"));
|
2011-06-23 15:48:48 +01:00
|
|
|
return rc;
|
|
|
|
}
|
|
|
|
|
2013-02-27 16:32:35 -07:00
|
|
|
if (secdef->label || secdef->imagelabel) {
|
2012-07-18 15:39:18 +01:00
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
|
"%s",
|
|
|
|
_("security label already defined for VM"));
|
2009-10-08 16:34:22 +02:00
|
|
|
return rc;
|
|
|
|
}
|
|
|
|
|
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 ((profile_name = get_profile_name(def)) == NULL)
|
2009-10-08 16:34:22 +02:00
|
|
|
return rc;
|
|
|
|
|
2019-10-20 13:49:46 +02:00
|
|
|
secdef->label = g_strdup(profile_name);
|
2009-10-08 16:34:22 +02:00
|
|
|
|
|
|
|
/* set imagelabel the same as label (but we won't use it) */
|
2019-10-20 13:49:46 +02:00
|
|
|
secdef->imagelabel = g_strdup(profile_name);
|
2009-10-08 16:34:22 +02:00
|
|
|
|
2019-10-18 15:08:21 +02:00
|
|
|
if (!secdef->model)
|
|
|
|
secdef->model = g_strdup(SECURITY_APPARMOR_NAME);
|
2009-10-08 16:34:22 +02:00
|
|
|
|
2011-06-24 09:51:37 -05:00
|
|
|
/* Now that we have a label, load the profile into the kernel. */
|
2012-08-15 19:10:37 -03:00
|
|
|
if (load_profile(mgr, secdef->label, def, NULL, false) < 0) {
|
2012-07-18 15:39:18 +01:00
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
|
_("cannot load AppArmor profile "
|
2012-08-15 19:10:37 -03:00
|
|
|
"\'%s\'"), secdef->label);
|
2011-06-24 09:51:37 -05:00
|
|
|
goto err;
|
|
|
|
}
|
|
|
|
|
2009-10-08 16:34:22 +02:00
|
|
|
rc = 0;
|
2013-04-29 18:38:21 +01:00
|
|
|
goto cleanup;
|
2009-10-08 16:34:22 +02:00
|
|
|
|
2014-03-25 07:57:22 +01:00
|
|
|
err:
|
2012-08-15 19:10:37 -03:00
|
|
|
VIR_FREE(secdef->label);
|
|
|
|
VIR_FREE(secdef->imagelabel);
|
|
|
|
VIR_FREE(secdef->model);
|
2009-10-08 16:34:22 +02:00
|
|
|
|
2014-03-25 07:57:22 +01:00
|
|
|
cleanup:
|
2009-10-08 16:34:22 +02:00
|
|
|
VIR_FREE(profile_name);
|
|
|
|
|
|
|
|
return rc;
|
|
|
|
}
|
|
|
|
|
2010-01-11 11:04:40 +00:00
|
|
|
static int
|
2021-03-11 08:16:13 +01:00
|
|
|
AppArmorSetSecurityAllLabel(virSecurityManager *mgr,
|
|
|
|
virDomainDef *def,
|
2020-07-01 11:50:00 +02:00
|
|
|
const char *incomingPath,
|
2019-10-14 14:45:33 +02:00
|
|
|
bool chardevStdioLogd G_GNUC_UNUSED,
|
|
|
|
bool migrated G_GNUC_UNUSED)
|
2010-01-11 11:04:40 +00:00
|
|
|
{
|
2021-03-11 08:16:13 +01:00
|
|
|
virSecurityLabelDef *secdef = virDomainDefGetSecurityLabelDef(def,
|
2012-08-15 19:10:37 -03:00
|
|
|
SECURITY_APPARMOR_NAME);
|
2017-02-02 19:26:13 -07:00
|
|
|
if (!secdef || !secdef->relabel)
|
2010-01-11 11:04:40 +00:00
|
|
|
return 0;
|
|
|
|
|
2020-07-01 11:50:00 +02:00
|
|
|
/* Reload the profile if incomingPath is specified. Note that
|
2011-06-24 09:51:37 -05:00
|
|
|
GenSecurityLabel() will have already been run. */
|
2020-07-01 11:50:00 +02:00
|
|
|
if (incomingPath)
|
|
|
|
return reload_profile(mgr, def, incomingPath, true);
|
2010-01-11 11:04:40 +00:00
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2009-10-08 16:34:22 +02:00
|
|
|
/* Seen with 'virsh dominfo <vm>'. This function only called if the VM is
|
|
|
|
* running.
|
|
|
|
*/
|
|
|
|
static int
|
2021-03-11 08:16:13 +01:00
|
|
|
AppArmorGetSecurityProcessLabel(virSecurityManager *mgr G_GNUC_UNUSED,
|
|
|
|
virDomainDef *def,
|
2019-10-14 14:45:33 +02:00
|
|
|
pid_t pid G_GNUC_UNUSED,
|
2010-06-15 17:44:19 +01:00
|
|
|
virSecurityLabelPtr sec)
|
2009-10-08 16:34:22 +02:00
|
|
|
{
|
|
|
|
int rc = -1;
|
2015-10-06 11:12:29 +02:00
|
|
|
int status;
|
2009-10-08 16:34:22 +02:00
|
|
|
char *profile_name = NULL;
|
|
|
|
|
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 ((profile_name = get_profile_name(def)) == NULL)
|
2009-10-08 16:34:22 +02:00
|
|
|
return rc;
|
|
|
|
|
2015-10-06 11:12:29 +02:00
|
|
|
status = profile_status(profile_name, 1);
|
|
|
|
if (status < -1) {
|
2012-07-18 15:39:18 +01:00
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
2015-10-06 11:12:29 +02:00
|
|
|
"%s", _("error getting profile status"));
|
2013-04-29 18:38:21 +01:00
|
|
|
goto cleanup;
|
2015-10-06 11:12:29 +02:00
|
|
|
} else if (status == -1) {
|
2019-09-09 09:50:39 -06:00
|
|
|
sec->label[0] = '\0';
|
|
|
|
} else {
|
|
|
|
if (virStrcpy(sec->label, profile_name, VIR_SECURITY_LABEL_BUFLEN) < 0) {
|
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
|
"%s", _("error copying profile name"));
|
|
|
|
goto cleanup;
|
|
|
|
}
|
2009-10-08 16:34:22 +02:00
|
|
|
}
|
2015-10-06 11:12:29 +02:00
|
|
|
|
|
|
|
sec->enforcing = status == 1;
|
2009-10-08 16:34:22 +02:00
|
|
|
rc = 0;
|
|
|
|
|
2014-03-25 07:57:22 +01:00
|
|
|
cleanup:
|
2009-10-08 16:34:22 +02:00
|
|
|
VIR_FREE(profile_name);
|
|
|
|
|
|
|
|
return rc;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Called on VM shutdown and destroy. See AppArmorGenSecurityLabel (above) for
|
|
|
|
* more details. Currently called via qemudShutdownVMDaemon.
|
|
|
|
*/
|
|
|
|
static int
|
2021-03-11 08:16:13 +01:00
|
|
|
AppArmorReleaseSecurityLabel(virSecurityManager *mgr G_GNUC_UNUSED,
|
|
|
|
virDomainDef *def)
|
2010-01-11 11:04:40 +00:00
|
|
|
{
|
2021-03-11 08:16:13 +01:00
|
|
|
virSecurityLabelDef *secdef = virDomainDefGetSecurityLabelDef(def,
|
2012-08-15 19:10:37 -03:00
|
|
|
SECURITY_APPARMOR_NAME);
|
2017-02-02 19:26:13 -07:00
|
|
|
if (secdef) {
|
|
|
|
VIR_FREE(secdef->model);
|
|
|
|
VIR_FREE(secdef->label);
|
|
|
|
VIR_FREE(secdef->imagelabel);
|
|
|
|
}
|
2010-01-11 11:04:40 +00:00
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static int
|
2021-03-11 08:16:13 +01:00
|
|
|
AppArmorRestoreSecurityAllLabel(virSecurityManager *mgr G_GNUC_UNUSED,
|
|
|
|
virDomainDef *def,
|
2019-10-14 14:45:33 +02:00
|
|
|
bool migrated G_GNUC_UNUSED,
|
|
|
|
bool chardevStdioLogd G_GNUC_UNUSED)
|
2009-10-08 16:34:22 +02:00
|
|
|
{
|
|
|
|
int rc = 0;
|
2021-03-11 08:16:13 +01:00
|
|
|
virSecurityLabelDef *secdef =
|
2012-08-15 19:10:37 -03:00
|
|
|
virDomainDefGetSecurityLabelDef(def, SECURITY_APPARMOR_NAME);
|
|
|
|
|
|
|
|
if (!secdef)
|
2017-02-02 19:26:13 -07:00
|
|
|
return 0;
|
2009-10-08 16:34:22 +02:00
|
|
|
|
2010-01-13 14:03:04 +00:00
|
|
|
if (secdef->type == VIR_DOMAIN_SECLABEL_DYNAMIC) {
|
2009-10-08 16:34:22 +02:00
|
|
|
if ((rc = remove_profile(secdef->label)) != 0) {
|
2012-07-18 15:39:18 +01:00
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
|
_("could not remove profile for \'%s\'"),
|
|
|
|
secdef->label);
|
2009-10-08 16:34:22 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
return rc;
|
|
|
|
}
|
|
|
|
|
2011-05-06 14:48:26 -04:00
|
|
|
/* Called via virCommand hook. Output goes to
|
2010-11-16 07:54:17 -07:00
|
|
|
* LOCALSTATEDIR/log/libvirt/qemu/<vm name>.log
|
2009-10-08 16:34:22 +02:00
|
|
|
*/
|
|
|
|
static int
|
2021-03-11 08:16:13 +01:00
|
|
|
AppArmorSetSecurityProcessLabel(virSecurityManager *mgr G_GNUC_UNUSED,
|
|
|
|
virDomainDef *def)
|
2009-10-08 16:34:22 +02:00
|
|
|
{
|
|
|
|
int rc = -1;
|
|
|
|
char *profile_name = NULL;
|
2021-03-11 08:16:13 +01:00
|
|
|
virSecurityLabelDef *secdef =
|
2012-08-15 19:10:37 -03:00
|
|
|
virDomainDefGetSecurityLabelDef(def, SECURITY_APPARMOR_NAME);
|
|
|
|
|
2017-02-02 19:26:13 -07:00
|
|
|
if (!secdef || !secdef->label)
|
2014-03-03 11:26:46 +01: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
|
|
|
if ((profile_name = get_profile_name(def)) == NULL)
|
2009-10-08 16:34:22 +02:00
|
|
|
return rc;
|
|
|
|
|
2013-02-11 14:22:56 +00:00
|
|
|
if (STRNEQ(SECURITY_APPARMOR_NAME, 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\'."),
|
2013-02-11 14:22:56 +00:00
|
|
|
secdef->model, SECURITY_APPARMOR_NAME);
|
2009-10-08 16:34:22 +02:00
|
|
|
if (use_apparmor() > 0)
|
2013-04-29 18:38:21 +01:00
|
|
|
goto cleanup;
|
2009-10-08 16:34:22 +02:00
|
|
|
}
|
|
|
|
|
2014-03-03 11:26:44 +01:00
|
|
|
VIR_DEBUG("Changing AppArmor profile to %s", profile_name);
|
2009-10-08 16:34:22 +02:00
|
|
|
if (aa_change_profile(profile_name) < 0) {
|
2012-07-18 15:39:18 +01:00
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
|
|
|
_("error calling aa_change_profile()"));
|
2013-04-29 18:38:21 +01:00
|
|
|
goto cleanup;
|
2009-10-08 16:34:22 +02:00
|
|
|
}
|
|
|
|
rc = 0;
|
|
|
|
|
2014-03-25 07:57:22 +01:00
|
|
|
cleanup:
|
2009-10-08 16:34:22 +02:00
|
|
|
VIR_FREE(profile_name);
|
|
|
|
|
|
|
|
return rc;
|
|
|
|
}
|
|
|
|
|
security: add new virSecurityManagerSetChildProcessLabel API
The existing virSecurityManagerSetProcessLabel() API is designed so
that it must be called after forking the child process, but before
exec'ing the child. Due to the way the virCommand API works, that
means it needs to be put in a "hook" function that virCommand is told
to call out to at that time.
Setting the child process label is a basic enough need when executing
any process that virCommand should have a method of doing that. But
virCommand must be told what label to set, and only the security
driver knows the answer to that question.
The new virSecurityManagerSet*Child*ProcessLabel() API is the way to
transfer the knowledge about what label to set from the security
driver to the virCommand object. It is given a virCommandPtr, and each
security driver calls the appropriate virCommand* API to tell
virCommand what to do between fork and exec.
1) in the case of the DAC security driver, it calls
virCommandSetUID/GID() to set a uid and gid that must be set for the
child process.
2) for the SELinux security driver, it calls
virCommandSetSELinuxLabel() to save a copy of the char* that will be
sent to setexeccon_raw() *after forking the child process*.
3) for the AppArmor security drivers, it calls
virCommandSetAppArmorProfile() to save a copy of the char* that will
be sent to aa_change_profile() *after forking the child process*.
With this new API in place, we will be able to remove
virSecurityManagerSetProcessLabel() from any virCommand pre-exec
hooks.
(Unfortunately, the LXC driver uses clone() rather than virCommand, so
it can't take advantage of this new security driver API, meaning that
we need to keep around the older virSecurityManagerSetProcessLabel(),
at least for now.)
2013-02-01 15:02:03 -05:00
|
|
|
/* Called directly by API user prior to virCommandRun().
|
|
|
|
* virCommandRun() will then call aa_change_profile() (if a
|
|
|
|
* cmd->appArmorProfile has been set) *after forking the child
|
|
|
|
* process*.
|
|
|
|
*/
|
|
|
|
static int
|
2021-03-11 08:16:13 +01:00
|
|
|
AppArmorSetSecurityChildProcessLabel(virSecurityManager *mgr G_GNUC_UNUSED,
|
|
|
|
virDomainDef *def,
|
|
|
|
virCommand *cmd)
|
security: add new virSecurityManagerSetChildProcessLabel API
The existing virSecurityManagerSetProcessLabel() API is designed so
that it must be called after forking the child process, but before
exec'ing the child. Due to the way the virCommand API works, that
means it needs to be put in a "hook" function that virCommand is told
to call out to at that time.
Setting the child process label is a basic enough need when executing
any process that virCommand should have a method of doing that. But
virCommand must be told what label to set, and only the security
driver knows the answer to that question.
The new virSecurityManagerSet*Child*ProcessLabel() API is the way to
transfer the knowledge about what label to set from the security
driver to the virCommand object. It is given a virCommandPtr, and each
security driver calls the appropriate virCommand* API to tell
virCommand what to do between fork and exec.
1) in the case of the DAC security driver, it calls
virCommandSetUID/GID() to set a uid and gid that must be set for the
child process.
2) for the SELinux security driver, it calls
virCommandSetSELinuxLabel() to save a copy of the char* that will be
sent to setexeccon_raw() *after forking the child process*.
3) for the AppArmor security drivers, it calls
virCommandSetAppArmorProfile() to save a copy of the char* that will
be sent to aa_change_profile() *after forking the child process*.
With this new API in place, we will be able to remove
virSecurityManagerSetProcessLabel() from any virCommand pre-exec
hooks.
(Unfortunately, the LXC driver uses clone() rather than virCommand, so
it can't take advantage of this new security driver API, meaning that
we need to keep around the older virSecurityManagerSetProcessLabel(),
at least for now.)
2013-02-01 15:02:03 -05:00
|
|
|
{
|
|
|
|
int rc = -1;
|
|
|
|
char *profile_name = NULL;
|
2014-03-03 11:26:44 +01:00
|
|
|
char *cmd_str = NULL;
|
2021-03-11 08:16:13 +01:00
|
|
|
virSecurityLabelDef *secdef =
|
security: add new virSecurityManagerSetChildProcessLabel API
The existing virSecurityManagerSetProcessLabel() API is designed so
that it must be called after forking the child process, but before
exec'ing the child. Due to the way the virCommand API works, that
means it needs to be put in a "hook" function that virCommand is told
to call out to at that time.
Setting the child process label is a basic enough need when executing
any process that virCommand should have a method of doing that. But
virCommand must be told what label to set, and only the security
driver knows the answer to that question.
The new virSecurityManagerSet*Child*ProcessLabel() API is the way to
transfer the knowledge about what label to set from the security
driver to the virCommand object. It is given a virCommandPtr, and each
security driver calls the appropriate virCommand* API to tell
virCommand what to do between fork and exec.
1) in the case of the DAC security driver, it calls
virCommandSetUID/GID() to set a uid and gid that must be set for the
child process.
2) for the SELinux security driver, it calls
virCommandSetSELinuxLabel() to save a copy of the char* that will be
sent to setexeccon_raw() *after forking the child process*.
3) for the AppArmor security drivers, it calls
virCommandSetAppArmorProfile() to save a copy of the char* that will
be sent to aa_change_profile() *after forking the child process*.
With this new API in place, we will be able to remove
virSecurityManagerSetProcessLabel() from any virCommand pre-exec
hooks.
(Unfortunately, the LXC driver uses clone() rather than virCommand, so
it can't take advantage of this new security driver API, meaning that
we need to keep around the older virSecurityManagerSetProcessLabel(),
at least for now.)
2013-02-01 15:02:03 -05:00
|
|
|
virDomainDefGetSecurityLabelDef(def, SECURITY_APPARMOR_NAME);
|
|
|
|
|
2017-02-02 19:26:13 -07:00
|
|
|
if (!secdef || !secdef->label)
|
2014-03-03 11:26:46 +01:00
|
|
|
return 0;
|
|
|
|
|
security: add new virSecurityManagerSetChildProcessLabel API
The existing virSecurityManagerSetProcessLabel() API is designed so
that it must be called after forking the child process, but before
exec'ing the child. Due to the way the virCommand API works, that
means it needs to be put in a "hook" function that virCommand is told
to call out to at that time.
Setting the child process label is a basic enough need when executing
any process that virCommand should have a method of doing that. But
virCommand must be told what label to set, and only the security
driver knows the answer to that question.
The new virSecurityManagerSet*Child*ProcessLabel() API is the way to
transfer the knowledge about what label to set from the security
driver to the virCommand object. It is given a virCommandPtr, and each
security driver calls the appropriate virCommand* API to tell
virCommand what to do between fork and exec.
1) in the case of the DAC security driver, it calls
virCommandSetUID/GID() to set a uid and gid that must be set for the
child process.
2) for the SELinux security driver, it calls
virCommandSetSELinuxLabel() to save a copy of the char* that will be
sent to setexeccon_raw() *after forking the child process*.
3) for the AppArmor security drivers, it calls
virCommandSetAppArmorProfile() to save a copy of the char* that will
be sent to aa_change_profile() *after forking the child process*.
With this new API in place, we will be able to remove
virSecurityManagerSetProcessLabel() from any virCommand pre-exec
hooks.
(Unfortunately, the LXC driver uses clone() rather than virCommand, so
it can't take advantage of this new security driver API, meaning that
we need to keep around the older virSecurityManagerSetProcessLabel(),
at least for now.)
2013-02-01 15:02:03 -05:00
|
|
|
if (STRNEQ(SECURITY_APPARMOR_NAME, secdef->model)) {
|
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
|
_("security label driver mismatch: "
|
|
|
|
"\'%s\' model configured for domain, but "
|
|
|
|
"hypervisor driver is \'%s\'."),
|
|
|
|
secdef->model, SECURITY_APPARMOR_NAME);
|
|
|
|
if (use_apparmor() > 0)
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ((profile_name = get_profile_name(def)) == NULL)
|
|
|
|
goto cleanup;
|
|
|
|
|
qemu: use line breaks in command line args written to log
The QEMU command line arguments are very long and currently all written
on a single line to /var/log/libvirt/qemu/$GUEST.log. This introduces
logic to add line breaks after every env variable and "-" optional
argument, and every positional argument. This will create a clearer log
file, which will in turn present better in bug reports when people cut +
paste from the log into a bug comment.
An example log file entry now looks like this:
2018-12-14 12:57:03.677+0000: starting up libvirt version: 5.0.0, qemu version: 3.0.0qemu-3.0.0-1.fc29, kernel: 4.19.5-300.fc29.x86_64, hostname: localhost.localdomain
LC_ALL=C \
PATH=/usr/local/bin:/usr/local/sbin:/usr/bin:/usr/sbin \
HOME=/home/berrange \
USER=berrange \
LOGNAME=berrange \
QEMU_AUDIO_DRV=none \
/usr/bin/qemu-system-ppc64 \
-name guest=guest,debug-threads=on \
-S \
-object secret,id=masterKey0,format=raw,file=/home/berrange/.config/libvirt/qemu/lib/domain-33-guest/master-key.aes \
-machine pseries-2.10,accel=tcg,usb=off,dump-guest-core=off \
-m 1024 \
-realtime mlock=off \
-smp 1,sockets=1,cores=1,threads=1 \
-uuid c8a74977-ab18-41d0-ae3b-4041c7fffbcd \
-display none \
-no-user-config \
-nodefaults \
-chardev socket,id=charmonitor,fd=23,server,nowait \
-mon chardev=charmonitor,id=monitor,mode=control \
-rtc base=utc \
-no-shutdown \
-boot strict=on \
-device qemu-xhci,id=usb,bus=pci.0,addr=0x1 \
-device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x2 \
-sandbox on,obsolete=deny,elevateprivileges=deny,spawn=deny,resourcecontrol=deny \
-msg timestamp=on
2018-12-14 12:57:03.730+0000: shutting down, reason=failed
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
2018-12-14 12:07:08 +00:00
|
|
|
cmd_str = virCommandToString(cmd, false);
|
2014-03-03 11:26:44 +01:00
|
|
|
VIR_DEBUG("Changing AppArmor profile to %s on %s", profile_name, cmd_str);
|
security: add new virSecurityManagerSetChildProcessLabel API
The existing virSecurityManagerSetProcessLabel() API is designed so
that it must be called after forking the child process, but before
exec'ing the child. Due to the way the virCommand API works, that
means it needs to be put in a "hook" function that virCommand is told
to call out to at that time.
Setting the child process label is a basic enough need when executing
any process that virCommand should have a method of doing that. But
virCommand must be told what label to set, and only the security
driver knows the answer to that question.
The new virSecurityManagerSet*Child*ProcessLabel() API is the way to
transfer the knowledge about what label to set from the security
driver to the virCommand object. It is given a virCommandPtr, and each
security driver calls the appropriate virCommand* API to tell
virCommand what to do between fork and exec.
1) in the case of the DAC security driver, it calls
virCommandSetUID/GID() to set a uid and gid that must be set for the
child process.
2) for the SELinux security driver, it calls
virCommandSetSELinuxLabel() to save a copy of the char* that will be
sent to setexeccon_raw() *after forking the child process*.
3) for the AppArmor security drivers, it calls
virCommandSetAppArmorProfile() to save a copy of the char* that will
be sent to aa_change_profile() *after forking the child process*.
With this new API in place, we will be able to remove
virSecurityManagerSetProcessLabel() from any virCommand pre-exec
hooks.
(Unfortunately, the LXC driver uses clone() rather than virCommand, so
it can't take advantage of this new security driver API, meaning that
we need to keep around the older virSecurityManagerSetProcessLabel(),
at least for now.)
2013-02-01 15:02:03 -05:00
|
|
|
virCommandSetAppArmorProfile(cmd, profile_name);
|
|
|
|
rc = 0;
|
|
|
|
|
2014-03-25 07:57:22 +01:00
|
|
|
cleanup:
|
security: add new virSecurityManagerSetChildProcessLabel API
The existing virSecurityManagerSetProcessLabel() API is designed so
that it must be called after forking the child process, but before
exec'ing the child. Due to the way the virCommand API works, that
means it needs to be put in a "hook" function that virCommand is told
to call out to at that time.
Setting the child process label is a basic enough need when executing
any process that virCommand should have a method of doing that. But
virCommand must be told what label to set, and only the security
driver knows the answer to that question.
The new virSecurityManagerSet*Child*ProcessLabel() API is the way to
transfer the knowledge about what label to set from the security
driver to the virCommand object. It is given a virCommandPtr, and each
security driver calls the appropriate virCommand* API to tell
virCommand what to do between fork and exec.
1) in the case of the DAC security driver, it calls
virCommandSetUID/GID() to set a uid and gid that must be set for the
child process.
2) for the SELinux security driver, it calls
virCommandSetSELinuxLabel() to save a copy of the char* that will be
sent to setexeccon_raw() *after forking the child process*.
3) for the AppArmor security drivers, it calls
virCommandSetAppArmorProfile() to save a copy of the char* that will
be sent to aa_change_profile() *after forking the child process*.
With this new API in place, we will be able to remove
virSecurityManagerSetProcessLabel() from any virCommand pre-exec
hooks.
(Unfortunately, the LXC driver uses clone() rather than virCommand, so
it can't take advantage of this new security driver API, meaning that
we need to keep around the older virSecurityManagerSetProcessLabel(),
at least for now.)
2013-02-01 15:02:03 -05:00
|
|
|
VIR_FREE(profile_name);
|
2014-03-03 11:26:44 +01:00
|
|
|
VIR_FREE(cmd_str);
|
security: add new virSecurityManagerSetChildProcessLabel API
The existing virSecurityManagerSetProcessLabel() API is designed so
that it must be called after forking the child process, but before
exec'ing the child. Due to the way the virCommand API works, that
means it needs to be put in a "hook" function that virCommand is told
to call out to at that time.
Setting the child process label is a basic enough need when executing
any process that virCommand should have a method of doing that. But
virCommand must be told what label to set, and only the security
driver knows the answer to that question.
The new virSecurityManagerSet*Child*ProcessLabel() API is the way to
transfer the knowledge about what label to set from the security
driver to the virCommand object. It is given a virCommandPtr, and each
security driver calls the appropriate virCommand* API to tell
virCommand what to do between fork and exec.
1) in the case of the DAC security driver, it calls
virCommandSetUID/GID() to set a uid and gid that must be set for the
child process.
2) for the SELinux security driver, it calls
virCommandSetSELinuxLabel() to save a copy of the char* that will be
sent to setexeccon_raw() *after forking the child process*.
3) for the AppArmor security drivers, it calls
virCommandSetAppArmorProfile() to save a copy of the char* that will
be sent to aa_change_profile() *after forking the child process*.
With this new API in place, we will be able to remove
virSecurityManagerSetProcessLabel() from any virCommand pre-exec
hooks.
(Unfortunately, the LXC driver uses clone() rather than virCommand, so
it can't take advantage of this new security driver API, meaning that
we need to keep around the older virSecurityManagerSetProcessLabel(),
at least for now.)
2013-02-01 15:02:03 -05:00
|
|
|
return rc;
|
|
|
|
}
|
|
|
|
|
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
|
2021-03-11 08:16:13 +01:00
|
|
|
AppArmorSetSecurityDaemonSocketLabel(virSecurityManager *mgr G_GNUC_UNUSED,
|
|
|
|
virDomainDef *vm G_GNUC_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 0;
|
|
|
|
}
|
|
|
|
|
2011-08-26 09:39:32 +02:00
|
|
|
static int
|
2021-03-11 08:16:13 +01:00
|
|
|
AppArmorSetSecuritySocketLabel(virSecurityManager *mgr G_GNUC_UNUSED,
|
|
|
|
virDomainDef *def G_GNUC_UNUSED)
|
2011-08-26 09:39:32 +02: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
|
|
|
static int
|
2021-03-11 08:16:13 +01:00
|
|
|
AppArmorClearSecuritySocketLabel(virSecurityManager *mgr G_GNUC_UNUSED,
|
|
|
|
virDomainDef *def G_GNUC_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 0;
|
|
|
|
}
|
|
|
|
|
2009-10-08 16:34:22 +02:00
|
|
|
|
|
|
|
/* Called when hotplugging */
|
|
|
|
static int
|
2021-03-11 08:16:13 +01:00
|
|
|
AppArmorRestoreSecurityImageLabel(virSecurityManager *mgr,
|
|
|
|
virDomainDef *def,
|
|
|
|
virStorageSource *src,
|
2019-10-14 14:45:33 +02:00
|
|
|
virSecurityDomainImageLabelFlags flags G_GNUC_UNUSED)
|
2009-10-08 16:34:22 +02:00
|
|
|
{
|
2014-06-23 17:19:25 +02:00
|
|
|
if (!virStorageSourceIsLocalStorage(src))
|
2011-12-09 19:49:40 -08: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
|
|
|
return reload_profile(mgr, def, NULL, false);
|
2009-10-08 16:34:22 +02:00
|
|
|
}
|
|
|
|
|
2014-06-23 17:19:25 +02:00
|
|
|
|
2018-03-19 13:12:14 +01:00
|
|
|
/* Called when hotplugging */
|
|
|
|
static int
|
2021-03-11 08:16:13 +01:00
|
|
|
AppArmorSetMemoryLabel(virSecurityManager *mgr,
|
|
|
|
virDomainDef *def,
|
|
|
|
virDomainMemoryDef *mem)
|
2018-03-19 13:12:14 +01:00
|
|
|
{
|
2020-10-31 21:24:08 +01:00
|
|
|
switch (mem->model) {
|
2018-03-19 13:12:14 +01:00
|
|
|
case VIR_DOMAIN_MEMORY_MODEL_NVDIMM:
|
2020-12-09 16:33:20 +01:00
|
|
|
case VIR_DOMAIN_MEMORY_MODEL_VIRTIO_PMEM:
|
2018-03-19 13:12:14 +01:00
|
|
|
if (!virFileExists(mem->nvdimmPath)) {
|
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
|
_("%s: \'%s\' does not exist"),
|
|
|
|
__func__, mem->nvdimmPath);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
return reload_profile(mgr, def, mem->nvdimmPath, true);
|
|
|
|
case VIR_DOMAIN_MEMORY_MODEL_NONE:
|
|
|
|
case VIR_DOMAIN_MEMORY_MODEL_DIMM:
|
conf: Introduce virtio-mem <memory/> model
The virtio-mem is paravirtualized mechanism of adding/removing
memory to/from a VM. A virtio-mem-pci device is split into blocks
of equal size which are then exposed (all or only a requested
portion of them) to the guest kernel to use as regular memory.
Therefore, the device has two important attributes:
1) block-size, which defines the size of a block
2) requested-size, which defines how much memory (in bytes)
is the device requested to expose to the guest.
The 'block-size' is configured on command line and immutable
throughout device's lifetime. The 'requested-size' can be set on
the command line too, but also is adjustable via monitor. In
fact, that is how management software places its requests to
change the memory allocation. If it wants to give more memory to
the guest it changes 'requested-size' to a bigger value, and if it
wants to shrink guest memory it changes the 'requested-size' to a
smaller value. Note, value of zero means that guest should
release all memory offered by the device. Of course, guest has to
cooperate. Therefore, there is a third attribute 'size' which is
read only and reflects how much memory the guest still has. This
can be different to 'requested-size', obviously. Because of name
clash, I've named it 'current' and it is dealt with in future
commits (it is a runtime information anyway).
In the backend, memory for virtio-mem is backed by usual objects:
memory-backend-{ram,file,memfd} and their size puts the cap on
the amount of memory that a virtio-mem device can offer to a
guest. But we are already able to express this info using <size/>
under <target/>.
Therefore, we need only two more elements to cover 'block-size'
and 'requested-size' attributes. This is the XML I've came up
with:
<memory model='virtio-mem'>
<source>
<nodemask>1-3</nodemask>
<pagesize unit='KiB'>2048</pagesize>
</source>
<target>
<size unit='KiB'>2097152</size>
<node>0</node>
<block unit='KiB'>2048</block>
<requested unit='KiB'>1048576</requested>
</target>
<address type='pci' domain='0x0000' bus='0x00' slot='0x04' function='0x0'/>
</memory>
I hope by now it is obvious that:
1) 'requested-size' must be an integer multiple of
'block-size', and
2) virtio-mem-pci device goes onto PCI bus and thus needs PCI
address.
Then there is a limitation that the minimal 'block-size' is
transparent huge page size (I'll leave this without explanation).
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
2021-01-18 16:13:12 +01:00
|
|
|
case VIR_DOMAIN_MEMORY_MODEL_VIRTIO_MEM:
|
2018-03-19 13:12:14 +01:00
|
|
|
case VIR_DOMAIN_MEMORY_MODEL_LAST:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static int
|
2021-03-11 08:16:13 +01:00
|
|
|
AppArmorRestoreMemoryLabel(virSecurityManager *mgr,
|
|
|
|
virDomainDef *def,
|
|
|
|
virDomainMemoryDef *mem G_GNUC_UNUSED)
|
2018-03-19 13:12:14 +01:00
|
|
|
{
|
|
|
|
return reload_profile(mgr, def, NULL, false);
|
|
|
|
}
|
|
|
|
|
2018-03-19 14:48:39 +01:00
|
|
|
/* Called when hotplugging */
|
|
|
|
static int
|
2021-03-11 08:16:13 +01:00
|
|
|
AppArmorSetInputLabel(virSecurityManager *mgr,
|
|
|
|
virDomainDef *def,
|
|
|
|
virDomainInputDef *input)
|
2018-03-19 14:48:39 +01:00
|
|
|
{
|
|
|
|
if (input == NULL)
|
|
|
|
return 0;
|
|
|
|
|
2018-04-25 14:42:34 +02:00
|
|
|
switch ((virDomainInputType)input->type) {
|
2018-03-19 14:48:39 +01:00
|
|
|
case VIR_DOMAIN_INPUT_TYPE_PASSTHROUGH:
|
2021-05-21 13:01:07 +02:00
|
|
|
case VIR_DOMAIN_INPUT_TYPE_EVDEV:
|
2018-03-19 14:48:39 +01:00
|
|
|
if (input->source.evdev == NULL) {
|
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
|
_("%s: passthrough input device has no source"),
|
|
|
|
__func__);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
if (!virFileExists(input->source.evdev)) {
|
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
|
_("%s: \'%s\' does not exist"),
|
|
|
|
__func__, input->source.evdev);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
return reload_profile(mgr, def, input->source.evdev, true);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case VIR_DOMAIN_INPUT_TYPE_MOUSE:
|
|
|
|
case VIR_DOMAIN_INPUT_TYPE_TABLET:
|
|
|
|
case VIR_DOMAIN_INPUT_TYPE_KBD:
|
|
|
|
case VIR_DOMAIN_INPUT_TYPE_LAST:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static int
|
2021-03-11 08:16:13 +01:00
|
|
|
AppArmorRestoreInputLabel(virSecurityManager *mgr,
|
|
|
|
virDomainDef *def,
|
|
|
|
virDomainInputDef *input G_GNUC_UNUSED)
|
2018-03-19 14:48:39 +01:00
|
|
|
{
|
|
|
|
return reload_profile(mgr, def, NULL, false);
|
|
|
|
}
|
|
|
|
|
2009-10-08 16:34:22 +02:00
|
|
|
/* Called when hotplugging */
|
|
|
|
static int
|
2021-03-11 08:16:13 +01:00
|
|
|
AppArmorSetSecurityImageLabelInternal(virSecurityManager *mgr,
|
|
|
|
virDomainDef *def,
|
|
|
|
virStorageSource *src)
|
2009-10-08 16:34:22 +02:00
|
|
|
{
|
2019-06-27 11:17:52 +02:00
|
|
|
g_autofree char *vfioGroupDev = NULL;
|
|
|
|
const char *path;
|
2014-06-24 17:04:21 +02:00
|
|
|
|
2019-06-27 11:17:52 +02:00
|
|
|
if (src->type == VIR_STORAGE_TYPE_NVME) {
|
|
|
|
const virStorageSourceNVMeDef *nvme = src->nvme;
|
|
|
|
|
|
|
|
if (!(vfioGroupDev = virPCIDeviceAddressGetIOMMUGroupDev(&nvme->pciAddr)))
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
path = vfioGroupDev;
|
|
|
|
} else {
|
|
|
|
if (!src->path || !virStorageSourceIsLocalStorage(src))
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
path = src->path;
|
|
|
|
}
|
|
|
|
|
2019-10-16 09:32:52 +02:00
|
|
|
/* if the device doesn't exist, error out */
|
2019-06-27 11:17:52 +02:00
|
|
|
if (!virFileExists(path)) {
|
2019-10-16 09:32:52 +02:00
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
|
_("\'%s\' does not exist"),
|
2019-06-27 11:17:52 +02:00
|
|
|
path);
|
2019-10-16 09:32:52 +02:00
|
|
|
return -1;
|
2009-10-08 16:34:22 +02:00
|
|
|
}
|
|
|
|
|
2019-06-27 11:17:52 +02:00
|
|
|
return reload_profile(mgr, def, path, true);
|
2009-10-08 16:34:22 +02:00
|
|
|
}
|
|
|
|
|
2021-01-13 12:32:18 +01:00
|
|
|
static int
|
2021-03-11 08:16:13 +01:00
|
|
|
AppArmorSetSecurityImageLabel(virSecurityManager *mgr,
|
|
|
|
virDomainDef *def,
|
|
|
|
virStorageSource *src,
|
2021-01-13 12:32:18 +01:00
|
|
|
virSecurityDomainImageLabelFlags flags G_GNUC_UNUSED)
|
|
|
|
{
|
2021-03-11 08:16:13 +01:00
|
|
|
virSecurityLabelDef *secdef;
|
|
|
|
virStorageSource *n;
|
2021-01-13 12:32:18 +01:00
|
|
|
|
|
|
|
secdef = virDomainDefGetSecurityLabelDef(def, SECURITY_APPARMOR_NAME);
|
|
|
|
if (!secdef || !secdef->relabel)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
if (!secdef->imagelabel)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
for (n = src; virStorageSourceIsBacking(n); n = n->backingStore) {
|
|
|
|
if (AppArmorSetSecurityImageLabelInternal(mgr, def, n) < 0)
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2009-10-08 16:34:22 +02:00
|
|
|
static int
|
2021-03-11 08:16:13 +01:00
|
|
|
AppArmorSecurityVerify(virSecurityManager *mgr G_GNUC_UNUSED,
|
|
|
|
virDomainDef *def)
|
2009-10-08 16:34:22 +02:00
|
|
|
{
|
2021-03-11 08:16:13 +01:00
|
|
|
virSecurityLabelDef *secdef =
|
2012-08-15 19:10:37 -03:00
|
|
|
virDomainDefGetSecurityLabelDef(def, SECURITY_APPARMOR_NAME);
|
|
|
|
|
|
|
|
if (!secdef)
|
2017-02-02 19:26:13 -07:00
|
|
|
return 0;
|
2009-10-08 16:34:22 +02:00
|
|
|
|
|
|
|
if (secdef->type == VIR_DOMAIN_SECLABEL_STATIC) {
|
|
|
|
if (use_apparmor() < 0 || profile_status(secdef->label, 0) < 0) {
|
2012-07-18 15:39:18 +01:00
|
|
|
virReportError(VIR_ERR_XML_ERROR,
|
|
|
|
_("Invalid security label \'%s\'"),
|
|
|
|
secdef->label);
|
2009-10-08 16:34:22 +02:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
2021-03-11 08:16:13 +01:00
|
|
|
AppArmorReserveSecurityLabel(virSecurityManager *mgr G_GNUC_UNUSED,
|
|
|
|
virDomainDef *def G_GNUC_UNUSED,
|
2019-10-14 14:45:33 +02:00
|
|
|
pid_t pid G_GNUC_UNUSED)
|
2009-10-08 16:34:22 +02:00
|
|
|
{
|
|
|
|
/* NOOP. Nothing to reserve with AppArmor */
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
2021-03-11 08:16:13 +01:00
|
|
|
AppArmorSetSecurityHostdevLabel(virSecurityManager *mgr,
|
|
|
|
virDomainDef *def,
|
|
|
|
virDomainHostdevDef *dev,
|
2012-11-27 16:17:47 +00:00
|
|
|
const char *vroot)
|
2009-10-08 16:34:22 +02:00
|
|
|
{
|
2010-09-30 14:54:56 -06:00
|
|
|
struct SDPDOP *ptr;
|
|
|
|
int ret = -1;
|
2021-03-11 08:16:13 +01:00
|
|
|
virSecurityLabelDef *secdef =
|
2012-08-15 19:10:37 -03:00
|
|
|
virDomainDefGetSecurityLabelDef(def, SECURITY_APPARMOR_NAME);
|
2021-03-11 08:16:13 +01:00
|
|
|
virDomainHostdevSubsysUSB *usbsrc = &dev->source.subsys.u.usb;
|
|
|
|
virDomainHostdevSubsysPCI *pcisrc = &dev->source.subsys.u.pci;
|
|
|
|
virDomainHostdevSubsysSCSI *scsisrc = &dev->source.subsys.u.scsi;
|
|
|
|
virDomainHostdevSubsysSCSIVHost *hostsrc = &dev->source.subsys.u.scsi_host;
|
|
|
|
virDomainHostdevSubsysMediatedDev *mdevsrc = &dev->source.subsys.u.mdev;
|
2012-08-15 19:10:37 -03:00
|
|
|
|
2017-02-02 19:26:13 -07:00
|
|
|
if (!secdef || !secdef->relabel)
|
2010-01-13 14:03:04 +00:00
|
|
|
return 0;
|
|
|
|
|
2010-09-30 14:54:56 -06:00
|
|
|
if (dev->mode != VIR_DOMAIN_HOSTDEV_MODE_SUBSYS)
|
|
|
|
return 0;
|
|
|
|
|
2014-07-09 09:31:38 -04:00
|
|
|
/* Like AppArmorRestoreSecurityImageLabel() for a networked disk,
|
|
|
|
* do nothing for an iSCSI hostdev
|
|
|
|
*/
|
2014-09-24 11:47:46 -04:00
|
|
|
if (dev->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI &&
|
|
|
|
scsisrc->protocol == VIR_DOMAIN_HOSTDEV_SCSI_PROTOCOL_TYPE_ISCSI)
|
2014-07-09 09:31:38 -04:00
|
|
|
return 0;
|
|
|
|
|
2010-09-30 14:54:56 -06:00
|
|
|
if (profile_loaded(secdef->imagelabel) < 0)
|
|
|
|
return 0;
|
|
|
|
|
2020-09-23 22:05:21 +02:00
|
|
|
ptr = g_new0(struct SDPDOP, 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
|
|
|
ptr->mgr = 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
|
|
|
ptr->def = def;
|
2010-09-30 14:54:56 -06:00
|
|
|
|
2018-04-25 14:42:34 +02:00
|
|
|
switch ((virDomainHostdevSubsysType)dev->source.subsys.type) {
|
2010-09-30 14:54:56 -06:00
|
|
|
case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB: {
|
2021-03-11 08:16:13 +01:00
|
|
|
virUSBDevice *usb =
|
2014-07-03 15:43:05 -04:00
|
|
|
virUSBDeviceNew(usbsrc->bus, usbsrc->device, vroot);
|
2010-09-30 14:54:56 -06:00
|
|
|
if (!usb)
|
|
|
|
goto done;
|
|
|
|
|
2013-01-14 22:11:44 +00:00
|
|
|
ret = virUSBDeviceFileIterate(usb, AppArmorSetSecurityUSBLabel, ptr);
|
|
|
|
virUSBDeviceFree(usb);
|
2010-09-30 14:54:56 -06:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI: {
|
2021-03-11 08:16:13 +01:00
|
|
|
virPCIDevice *pci =
|
virpci.c: simplify virPCIDeviceNew() signature
The current virPCIDeviceNew() signature, receiving 4 uints in sequence
(domain, bus, slot, function), is not neat.
We already have a way to represent a PCI address in virPCIDeviceAddress
that is used in the code. Aside from the test files, most of
virPCIDeviceNew() callers have access to a virPCIDeviceAddress reference,
but then we need to retrieve the 4 required uints (addr.domain, addr.bus,
addr.slot, addr.function) to satisfy virPCIDeviceNew(). The result is
that we have extra verbosity/boilerplate to retrieve an information that
is already available in virPCIDeviceAddress.
A better way is presented by virNVMEDeviceNew(), where the caller just
supplies a virPCIDeviceAddress pointer and the function handles the
details internally.
This patch changes virPCIDeviceNew() to receive a virPCIDeviceAddress
pointer instead of 4 uints.
Reviewed-by: Laine Stump <laine@redhat.com>
Signed-off-by: Daniel Henrique Barboza <danielhb413@gmail.com>
2021-01-04 09:54:28 -03:00
|
|
|
virPCIDeviceNew(&pcisrc->addr);
|
2010-09-30 14:54:56 -06:00
|
|
|
|
|
|
|
if (!pci)
|
|
|
|
goto done;
|
|
|
|
|
2014-07-03 16:31:39 -04:00
|
|
|
if (pcisrc->backend == VIR_DOMAIN_HOSTDEV_PCI_BACKEND_VFIO) {
|
2013-06-14 16:18:44 -04:00
|
|
|
char *vfioGroupDev = virPCIDeviceGetIOMMUGroupDev(pci);
|
2013-04-25 06:37:21 -04:00
|
|
|
|
2013-04-30 10:59:29 -04:00
|
|
|
if (!vfioGroupDev) {
|
|
|
|
virPCIDeviceFree(pci);
|
2013-04-25 06:37:21 -04:00
|
|
|
goto done;
|
2013-04-30 10:59:29 -04:00
|
|
|
}
|
2013-04-25 06:37:21 -04:00
|
|
|
ret = AppArmorSetSecurityPCILabel(pci, vfioGroupDev, ptr);
|
|
|
|
VIR_FREE(vfioGroupDev);
|
|
|
|
} else {
|
|
|
|
ret = virPCIDeviceFileIterate(pci, AppArmorSetSecurityPCILabel, ptr);
|
|
|
|
}
|
2013-01-14 22:11:44 +00:00
|
|
|
virPCIDeviceFree(pci);
|
2010-09-30 14:54:56 -06:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2013-05-04 02:07:28 +08:00
|
|
|
case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI: {
|
2021-03-11 08:16:13 +01:00
|
|
|
virDomainHostdevSubsysSCSIHost *scsihostsrc = &scsisrc->u.host;
|
|
|
|
virSCSIDevice *scsi =
|
2014-01-30 15:05:59 +08:00
|
|
|
virSCSIDeviceNew(NULL,
|
2014-06-20 11:35:46 -04:00
|
|
|
scsihostsrc->adapter, scsihostsrc->bus,
|
|
|
|
scsihostsrc->target, scsihostsrc->unit,
|
2014-07-03 17:01:10 -04:00
|
|
|
dev->readonly, dev->shareable);
|
2013-05-04 02:07:28 +08:00
|
|
|
|
|
|
|
if (!scsi)
|
|
|
|
goto done;
|
|
|
|
|
|
|
|
ret = virSCSIDeviceFileIterate(scsi, AppArmorSetSecuritySCSILabel, ptr);
|
|
|
|
virSCSIDeviceFree(scsi);
|
|
|
|
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2016-11-21 22:58:16 -05:00
|
|
|
case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI_HOST: {
|
2021-03-11 08:16:13 +01:00
|
|
|
virSCSIVHostDevice *host = virSCSIVHostDeviceNew(hostsrc->wwpn);
|
2016-11-21 22:58:21 -05:00
|
|
|
|
|
|
|
if (!host)
|
|
|
|
goto done;
|
|
|
|
|
|
|
|
ret = virSCSIVHostDeviceFileIterate(host,
|
|
|
|
AppArmorSetSecurityHostLabel,
|
|
|
|
ptr);
|
|
|
|
virSCSIVHostDeviceFree(host);
|
|
|
|
break;
|
2016-11-21 22:58:16 -05:00
|
|
|
}
|
|
|
|
|
2017-02-03 13:25:57 +01:00
|
|
|
case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_MDEV: {
|
|
|
|
char *vfiodev = NULL;
|
|
|
|
|
2017-04-26 14:47:15 +02:00
|
|
|
if (!(vfiodev = virMediatedDeviceGetIOMMUGroupDev(mdevsrc->uuidstr)))
|
2017-02-03 13:25:57 +01:00
|
|
|
goto done;
|
|
|
|
|
|
|
|
ret = AppArmorSetSecurityHostdevLabelHelper(vfiodev, ptr);
|
|
|
|
|
|
|
|
VIR_FREE(vfiodev);
|
2017-01-31 17:26:36 +01:00
|
|
|
break;
|
2017-02-03 13:25:57 +01:00
|
|
|
}
|
2017-01-31 17:26:36 +01:00
|
|
|
|
2016-11-08 13:26:23 -05:00
|
|
|
case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_LAST:
|
2010-09-30 14:54:56 -06:00
|
|
|
ret = 0;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2014-03-25 07:57:22 +01:00
|
|
|
done:
|
2010-09-30 14:54:56 -06:00
|
|
|
VIR_FREE(ptr);
|
|
|
|
return ret;
|
2009-10-08 16:34:22 +02:00
|
|
|
}
|
|
|
|
|
2010-09-30 14:54:56 -06:00
|
|
|
|
2009-10-08 16:34:22 +02:00
|
|
|
static int
|
2021-03-11 08:16:13 +01:00
|
|
|
AppArmorRestoreSecurityHostdevLabel(virSecurityManager *mgr,
|
|
|
|
virDomainDef *def,
|
|
|
|
virDomainHostdevDef *dev G_GNUC_UNUSED,
|
2019-10-14 14:45:33 +02:00
|
|
|
const char *vroot G_GNUC_UNUSED)
|
2009-10-08 16:34:22 +02:00
|
|
|
|
|
|
|
{
|
2021-03-11 08:16:13 +01:00
|
|
|
virSecurityLabelDef *secdef =
|
2012-08-15 19:10:37 -03:00
|
|
|
virDomainDefGetSecurityLabelDef(def, SECURITY_APPARMOR_NAME);
|
|
|
|
|
2017-02-02 19:26:13 -07:00
|
|
|
if (!secdef || !secdef->relabel)
|
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
|
|
|
return reload_profile(mgr, def, NULL, false);
|
2009-10-08 16:34:22 +02:00
|
|
|
}
|
|
|
|
|
2018-01-09 16:04:04 +01:00
|
|
|
static int
|
2021-03-11 08:16:13 +01:00
|
|
|
AppArmorSetChardevLabel(virSecurityManager *mgr,
|
|
|
|
virDomainDef *def,
|
|
|
|
virDomainChrSourceDef *dev_source,
|
2019-10-14 14:45:33 +02:00
|
|
|
bool chardevStdioLogd G_GNUC_UNUSED)
|
2018-01-09 16:04:04 +01:00
|
|
|
{
|
|
|
|
char *in = NULL, *out = NULL;
|
|
|
|
int ret = -1;
|
2021-03-11 08:16:13 +01:00
|
|
|
virSecurityLabelDef *secdef;
|
2018-01-09 16:04:04 +01:00
|
|
|
|
|
|
|
secdef = virDomainDefGetSecurityLabelDef(def, SECURITY_APPARMOR_NAME);
|
|
|
|
if (!secdef)
|
|
|
|
return 0;
|
|
|
|
|
2018-04-25 14:42:34 +02:00
|
|
|
switch ((virDomainChrType)dev_source->type) {
|
2018-01-09 16:04:04 +01:00
|
|
|
case VIR_DOMAIN_CHR_TYPE_DEV:
|
|
|
|
case VIR_DOMAIN_CHR_TYPE_FILE:
|
|
|
|
case VIR_DOMAIN_CHR_TYPE_UNIX:
|
|
|
|
case VIR_DOMAIN_CHR_TYPE_PTY:
|
|
|
|
ret = reload_profile(mgr, def, dev_source->data.file.path, true);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case VIR_DOMAIN_CHR_TYPE_PIPE:
|
2019-10-22 15:26:14 +02:00
|
|
|
in = g_strdup_printf("%s.in", dev_source->data.file.path);
|
|
|
|
out = g_strdup_printf("%s.out", dev_source->data.file.path);
|
2018-01-09 16:04:04 +01:00
|
|
|
if (virFileExists(in)) {
|
|
|
|
if (reload_profile(mgr, def, in, true) < 0)
|
|
|
|
goto done;
|
|
|
|
}
|
|
|
|
if (virFileExists(out)) {
|
|
|
|
if (reload_profile(mgr, def, out, true) < 0)
|
|
|
|
goto done;
|
|
|
|
}
|
|
|
|
ret = reload_profile(mgr, def, dev_source->data.file.path, true);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case VIR_DOMAIN_CHR_TYPE_SPICEPORT:
|
|
|
|
case VIR_DOMAIN_CHR_TYPE_NULL:
|
|
|
|
case VIR_DOMAIN_CHR_TYPE_VC:
|
|
|
|
case VIR_DOMAIN_CHR_TYPE_STDIO:
|
|
|
|
case VIR_DOMAIN_CHR_TYPE_UDP:
|
|
|
|
case VIR_DOMAIN_CHR_TYPE_TCP:
|
|
|
|
case VIR_DOMAIN_CHR_TYPE_SPICEVMC:
|
|
|
|
case VIR_DOMAIN_CHR_TYPE_NMDM:
|
2022-03-18 15:51:39 -05:00
|
|
|
case VIR_DOMAIN_CHR_TYPE_QEMU_VDAGENT:
|
2018-01-09 16:04:04 +01:00
|
|
|
case VIR_DOMAIN_CHR_TYPE_LAST:
|
|
|
|
ret = 0;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
done:
|
|
|
|
VIR_FREE(in);
|
|
|
|
VIR_FREE(out);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
2021-03-11 08:16:13 +01:00
|
|
|
AppArmorRestoreChardevLabel(virSecurityManager *mgr,
|
|
|
|
virDomainDef *def,
|
|
|
|
virDomainChrSourceDef *dev_source G_GNUC_UNUSED,
|
2019-10-14 14:45:33 +02:00
|
|
|
bool chardevStdioLogd G_GNUC_UNUSED)
|
2018-01-09 16:04:04 +01:00
|
|
|
{
|
2021-03-11 08:16:13 +01:00
|
|
|
virSecurityLabelDef *secdef;
|
2018-01-09 16:04:04 +01:00
|
|
|
|
|
|
|
secdef = virDomainDefGetSecurityLabelDef(def, SECURITY_APPARMOR_NAME);
|
|
|
|
if (!secdef)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
return reload_profile(mgr, def, NULL, false);
|
|
|
|
}
|
|
|
|
|
2021-07-27 18:13:36 -06:00
|
|
|
static int
|
|
|
|
AppArmorSetNetdevLabel(virSecurityManager *mgr,
|
|
|
|
virDomainDef *def,
|
|
|
|
virDomainNetDef *net)
|
|
|
|
{
|
|
|
|
int ret = -1;
|
|
|
|
virSecurityLabelDef *secdef;
|
|
|
|
virDomainChrSourceDef *dev_source;
|
|
|
|
virDomainNetType actualType;
|
|
|
|
|
|
|
|
secdef = virDomainDefGetSecurityLabelDef(def, SECURITY_APPARMOR_NAME);
|
|
|
|
if (!secdef)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
actualType = virDomainNetGetActualType(net);
|
|
|
|
if (actualType != VIR_DOMAIN_NET_TYPE_VHOSTUSER)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
dev_source = net->data.vhostuser;
|
|
|
|
switch ((virDomainChrType)dev_source->type) {
|
|
|
|
case VIR_DOMAIN_CHR_TYPE_UNIX:
|
|
|
|
ret = reload_profile(mgr, def, dev_source->data.file.path, true);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case VIR_DOMAIN_CHR_TYPE_DEV:
|
|
|
|
case VIR_DOMAIN_CHR_TYPE_FILE:
|
|
|
|
case VIR_DOMAIN_CHR_TYPE_PTY:
|
|
|
|
case VIR_DOMAIN_CHR_TYPE_PIPE:
|
|
|
|
case VIR_DOMAIN_CHR_TYPE_SPICEPORT:
|
|
|
|
case VIR_DOMAIN_CHR_TYPE_NULL:
|
|
|
|
case VIR_DOMAIN_CHR_TYPE_VC:
|
|
|
|
case VIR_DOMAIN_CHR_TYPE_STDIO:
|
|
|
|
case VIR_DOMAIN_CHR_TYPE_UDP:
|
|
|
|
case VIR_DOMAIN_CHR_TYPE_TCP:
|
|
|
|
case VIR_DOMAIN_CHR_TYPE_SPICEVMC:
|
|
|
|
case VIR_DOMAIN_CHR_TYPE_NMDM:
|
2022-03-18 15:51:39 -05:00
|
|
|
case VIR_DOMAIN_CHR_TYPE_QEMU_VDAGENT:
|
2021-07-27 18:13:36 -06:00
|
|
|
case VIR_DOMAIN_CHR_TYPE_LAST:
|
|
|
|
ret = 0;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
AppArmorRestoreNetdevLabel(virSecurityManager *mgr,
|
|
|
|
virDomainDef *def,
|
|
|
|
virDomainNetDef *net G_GNUC_UNUSED)
|
|
|
|
{
|
|
|
|
virSecurityLabelDef *secdef;
|
|
|
|
|
|
|
|
secdef = virDomainDefGetSecurityLabelDef(def, SECURITY_APPARMOR_NAME);
|
|
|
|
if (!secdef)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
return reload_profile(mgr, def, NULL, false);
|
|
|
|
}
|
|
|
|
|
2018-01-09 16:04:02 +01:00
|
|
|
static int
|
2021-03-11 08:16:13 +01:00
|
|
|
AppArmorSetPathLabel(virSecurityManager *mgr,
|
|
|
|
virDomainDef *def,
|
2018-01-09 16:04:03 +01:00
|
|
|
const char *path,
|
|
|
|
bool allowSubtree)
|
2018-01-09 16:04:02 +01:00
|
|
|
{
|
2018-01-09 16:04:03 +01:00
|
|
|
int rc = -1;
|
|
|
|
char *full_path = NULL;
|
|
|
|
|
|
|
|
if (allowSubtree) {
|
2019-10-22 15:26:14 +02:00
|
|
|
full_path = g_strdup_printf("%s/{,**}", path);
|
2018-01-09 16:04:03 +01:00
|
|
|
rc = reload_profile(mgr, def, full_path, true);
|
|
|
|
VIR_FREE(full_path);
|
|
|
|
} else {
|
|
|
|
rc = reload_profile(mgr, def, path, true);
|
|
|
|
}
|
|
|
|
|
|
|
|
return rc;
|
2018-01-09 16:04:02 +01:00
|
|
|
}
|
2010-06-04 12:20:29 -04:00
|
|
|
|
|
|
|
static int
|
2021-03-11 08:16:13 +01:00
|
|
|
AppArmorRestorePathLabel(virSecurityManager *mgr,
|
|
|
|
virDomainDef *def,
|
2020-06-17 11:32:53 +02:00
|
|
|
const char *path G_GNUC_UNUSED)
|
2010-06-04 12:20:29 -04: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
|
|
|
return reload_profile(mgr, def, NULL, false);
|
2010-06-04 12:20:29 -04:00
|
|
|
}
|
|
|
|
|
2011-01-23 16:02:42 -05:00
|
|
|
static int
|
2021-03-11 08:16:13 +01:00
|
|
|
AppArmorSetFDLabel(virSecurityManager *mgr,
|
|
|
|
virDomainDef *def,
|
2013-03-08 00:16:59 +08:00
|
|
|
int fd)
|
2011-01-23 16:02:42 -05:00
|
|
|
{
|
2011-06-20 11:53:24 +08:00
|
|
|
char *proc = NULL;
|
|
|
|
char *fd_path = NULL;
|
|
|
|
|
2021-03-11 08:16:13 +01:00
|
|
|
virSecurityLabelDef *secdef =
|
2012-08-15 19:10:37 -03:00
|
|
|
virDomainDefGetSecurityLabelDef(def, SECURITY_APPARMOR_NAME);
|
|
|
|
|
2017-02-02 19:26:13 -07:00
|
|
|
if (!secdef || !secdef->imagelabel)
|
2011-06-20 11:53:24 +08:00
|
|
|
return 0;
|
|
|
|
|
2019-10-22 15:26:14 +02:00
|
|
|
proc = g_strdup_printf("/proc/self/fd/%d", fd);
|
2011-06-20 11:53:24 +08:00
|
|
|
|
|
|
|
if (virFileResolveLink(proc, &fd_path) < 0) {
|
2011-12-02 13:10:58 -06:00
|
|
|
/* it's a deleted file, presumably. Ignore? */
|
|
|
|
VIR_WARN("could not find path for descriptor %s, skipping", proc);
|
|
|
|
return 0;
|
2011-06-20 11:53:24 +08: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
|
|
|
return reload_profile(mgr, def, fd_path, true);
|
2011-01-23 16:02:42 -05:00
|
|
|
}
|
|
|
|
|
2012-11-22 14:11:35 +00:00
|
|
|
static char *
|
2021-03-11 08:16:13 +01:00
|
|
|
AppArmorGetMountOptions(virSecurityManager *mgr G_GNUC_UNUSED,
|
|
|
|
virDomainDef *vm G_GNUC_UNUSED)
|
2012-11-22 14:11:35 +00:00
|
|
|
{
|
2021-10-22 10:56:01 +02:00
|
|
|
return g_strdup("");
|
2012-11-22 14:11:35 +00:00
|
|
|
}
|
|
|
|
|
2013-10-18 14:13:20 +02:00
|
|
|
static const char *
|
2021-03-11 08:16:13 +01:00
|
|
|
AppArmorGetBaseLabel(virSecurityManager *mgr G_GNUC_UNUSED,
|
2019-10-14 14:45:33 +02:00
|
|
|
int virtType G_GNUC_UNUSED)
|
2013-10-18 14:13:20 +02:00
|
|
|
{
|
|
|
|
return NULL;
|
|
|
|
}
|
2012-11-22 14:11:35 +00:00
|
|
|
|
2009-10-08 16:34:22 +02:00
|
|
|
virSecurityDriver virAppArmorSecurityDriver = {
|
2012-05-24 15:11:26 +02:00
|
|
|
.privateDataLen = 0,
|
|
|
|
.name = SECURITY_APPARMOR_NAME,
|
|
|
|
.probe = AppArmorSecurityManagerProbe,
|
|
|
|
.open = AppArmorSecurityManagerOpen,
|
|
|
|
.close = AppArmorSecurityManagerClose,
|
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 15:11:26 +02:00
|
|
|
.getModel = AppArmorSecurityManagerGetModel,
|
|
|
|
.getDOI = AppArmorSecurityManagerGetDOI,
|
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 15:11:26 +02:00
|
|
|
.domainSecurityVerify = AppArmorSecurityVerify,
|
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
|
|
|
|
2014-06-24 17:04:21 +02:00
|
|
|
.domainSetSecurityImageLabel = AppArmorSetSecurityImageLabel,
|
2014-06-23 17:19:25 +02:00
|
|
|
.domainRestoreSecurityImageLabel = AppArmorRestoreSecurityImageLabel,
|
|
|
|
|
2018-03-19 13:12:14 +01:00
|
|
|
.domainSetSecurityMemoryLabel = AppArmorSetMemoryLabel,
|
|
|
|
.domainRestoreSecurityMemoryLabel = AppArmorRestoreMemoryLabel,
|
|
|
|
|
2018-03-19 14:48:39 +01:00
|
|
|
.domainSetSecurityInputLabel = AppArmorSetInputLabel,
|
|
|
|
.domainRestoreSecurityInputLabel = AppArmorRestoreInputLabel,
|
|
|
|
|
2012-05-24 15:11:26 +02:00
|
|
|
.domainSetSecurityDaemonSocketLabel = AppArmorSetSecurityDaemonSocketLabel,
|
|
|
|
.domainSetSecuritySocketLabel = AppArmorSetSecuritySocketLabel,
|
|
|
|
.domainClearSecuritySocketLabel = AppArmorClearSecuritySocketLabel,
|
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 15:11:26 +02:00
|
|
|
.domainGenSecurityLabel = AppArmorGenSecurityLabel,
|
|
|
|
.domainReserveSecurityLabel = AppArmorReserveSecurityLabel,
|
|
|
|
.domainReleaseSecurityLabel = AppArmorReleaseSecurityLabel,
|
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 15:11:26 +02:00
|
|
|
.domainGetSecurityProcessLabel = AppArmorGetSecurityProcessLabel,
|
|
|
|
.domainSetSecurityProcessLabel = AppArmorSetSecurityProcessLabel,
|
security: add new virSecurityManagerSetChildProcessLabel API
The existing virSecurityManagerSetProcessLabel() API is designed so
that it must be called after forking the child process, but before
exec'ing the child. Due to the way the virCommand API works, that
means it needs to be put in a "hook" function that virCommand is told
to call out to at that time.
Setting the child process label is a basic enough need when executing
any process that virCommand should have a method of doing that. But
virCommand must be told what label to set, and only the security
driver knows the answer to that question.
The new virSecurityManagerSet*Child*ProcessLabel() API is the way to
transfer the knowledge about what label to set from the security
driver to the virCommand object. It is given a virCommandPtr, and each
security driver calls the appropriate virCommand* API to tell
virCommand what to do between fork and exec.
1) in the case of the DAC security driver, it calls
virCommandSetUID/GID() to set a uid and gid that must be set for the
child process.
2) for the SELinux security driver, it calls
virCommandSetSELinuxLabel() to save a copy of the char* that will be
sent to setexeccon_raw() *after forking the child process*.
3) for the AppArmor security drivers, it calls
virCommandSetAppArmorProfile() to save a copy of the char* that will
be sent to aa_change_profile() *after forking the child process*.
With this new API in place, we will be able to remove
virSecurityManagerSetProcessLabel() from any virCommand pre-exec
hooks.
(Unfortunately, the LXC driver uses clone() rather than virCommand, so
it can't take advantage of this new security driver API, meaning that
we need to keep around the older virSecurityManagerSetProcessLabel(),
at least for now.)
2013-02-01 15:02:03 -05:00
|
|
|
.domainSetSecurityChildProcessLabel = AppArmorSetSecurityChildProcessLabel,
|
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 15:11:26 +02:00
|
|
|
.domainSetSecurityAllLabel = AppArmorSetSecurityAllLabel,
|
|
|
|
.domainRestoreSecurityAllLabel = AppArmorRestoreSecurityAllLabel,
|
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 15:11:26 +02:00
|
|
|
.domainSetSecurityHostdevLabel = AppArmorSetSecurityHostdevLabel,
|
|
|
|
.domainRestoreSecurityHostdevLabel = AppArmorRestoreSecurityHostdevLabel,
|
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
|
|
|
|
2018-01-09 16:04:02 +01:00
|
|
|
.domainSetPathLabel = AppArmorSetPathLabel,
|
2020-06-17 11:32:53 +02:00
|
|
|
.domainRestorePathLabel = AppArmorRestorePathLabel,
|
2018-01-09 16:04:02 +01:00
|
|
|
|
2018-01-09 16:04:04 +01:00
|
|
|
.domainSetSecurityChardevLabel = AppArmorSetChardevLabel,
|
|
|
|
.domainRestoreSecurityChardevLabel = AppArmorRestoreChardevLabel,
|
|
|
|
|
2021-07-27 18:13:36 -06:00
|
|
|
.domainSetSecurityNetdevLabel = AppArmorSetNetdevLabel,
|
|
|
|
.domainRestoreSecurityNetdevLabel = AppArmorRestoreNetdevLabel,
|
|
|
|
|
2013-03-08 00:16:59 +08:00
|
|
|
.domainSetSecurityImageFDLabel = AppArmorSetFDLabel,
|
|
|
|
.domainSetSecurityTapFDLabel = AppArmorSetFDLabel,
|
2012-11-22 14:11:35 +00:00
|
|
|
|
|
|
|
.domainGetSecurityMountOptions = AppArmorGetMountOptions,
|
2013-10-18 14:13:20 +02:00
|
|
|
|
2013-10-29 17:01:22 +01:00
|
|
|
.getBaseLabel = AppArmorGetBaseLabel,
|
2009-10-08 16:34:22 +02:00
|
|
|
};
|