mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2024-12-25 01:34:11 +03:00
f344005547
The virDomainObj struct has @pid member where the domain's hypervisor PID is stored (e.g. QEMU/bhyve/libvirt_lxc/... PID). However, we are not consistent when it comes to shutoff state. Initially, because virDomainObjNew() uses g_new0() the @pid is initialized to 0. But when domain is shut off, some functions set it to -1 (virBhyveProcessStop, virCHProcessStop, qemuProcessStop, ..). In other places, the @pid is tested to be 0, on some other places it's tested for being negative and in the rest for being positive. To solve this inconsistency we can stick with either value, -1 or 0. I've chosen the latter as it's safer IMO. For instance if by mistake we'd kill(vm->pid, SIGTERM) we would kill ourselves instead of init's process group. Signed-off-by: Michal Privoznik <mprivozn@redhat.com> Reviewed-by: Jonathon Jongsma <jjongsma@redhat.com>
265 lines
8.1 KiB
C
265 lines
8.1 KiB
C
/*
|
|
* Copyright (C) 2018 Red Hat, Inc.
|
|
*
|
|
* This library is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
* License as published by the Free Software Foundation; either
|
|
* version 2.1 of the License, or (at your option) any later version.
|
|
*
|
|
* This library is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
* Lesser General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
* License along with this library. If not, see
|
|
* <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
#include <config.h>
|
|
|
|
#include "qemusecuritytest.h"
|
|
#include "testutils.h"
|
|
#include "testutilsqemu.h"
|
|
#include "security/security_manager.h"
|
|
#include "security/security_util.h"
|
|
#include "conf/domain_conf.h"
|
|
#include "qemu/qemu_domain.h"
|
|
#include "qemu/qemu_security.h"
|
|
|
|
#define VIR_FROM_THIS VIR_FROM_NONE
|
|
|
|
struct testData {
|
|
virQEMUDriver *driver;
|
|
const char *file; /* file name to load VM def XML from; qemuxml2argvdata/ */
|
|
};
|
|
|
|
|
|
static int
|
|
prepareObjects(virQEMUDriver *driver,
|
|
const char *xmlname,
|
|
virDomainObj **vm_ret)
|
|
{
|
|
qemuDomainObjPrivate *priv;
|
|
g_autoptr(virDomainObj) vm = NULL;
|
|
g_autofree char *filename = NULL;
|
|
g_autofree char *domxml = NULL;
|
|
g_autofree char *latestCapsFile = NULL;
|
|
|
|
filename = g_strdup_printf("%s/qemuxml2argvdata/%s.xml", abs_srcdir, xmlname);
|
|
|
|
if (virTestLoadFile(filename, &domxml) < 0)
|
|
return -1;
|
|
|
|
if (!(vm = virDomainObjNew(driver->xmlopt)))
|
|
return -1;
|
|
|
|
priv = vm->privateData;
|
|
priv->chardevStdioLogd = false;
|
|
priv->rememberOwner = true;
|
|
|
|
if (!(latestCapsFile = testQemuGetLatestCapsForArch("x86_64", "xml")))
|
|
return -1;
|
|
|
|
if (!(priv->qemuCaps = qemuTestParseCapabilitiesArch(VIR_ARCH_X86_64, latestCapsFile)))
|
|
return -1;
|
|
|
|
if (qemuTestCapsCacheInsert(driver->qemuCapsCache, priv->qemuCaps) < 0)
|
|
return -1;
|
|
|
|
if (!(vm->def = virDomainDefParseString(domxml,
|
|
driver->xmlopt,
|
|
NULL,
|
|
0)))
|
|
return -1;
|
|
|
|
if (virSecurityManagerGenLabel(driver->securityManager, vm->def) < 0)
|
|
return -1;
|
|
|
|
*vm_ret = g_steal_pointer(&vm);
|
|
return 0;
|
|
}
|
|
|
|
|
|
static int
|
|
testDomain(const void *opaque)
|
|
{
|
|
const struct testData *data = opaque;
|
|
g_autoptr(virDomainObj) vm = NULL;
|
|
g_autoptr(GHashTable) notRestored = virHashNew(NULL);
|
|
size_t i;
|
|
int ret = -1;
|
|
|
|
if (prepareObjects(data->driver, data->file, &vm) < 0)
|
|
return -1;
|
|
|
|
for (i = 0; i < vm->def->ndisks; i++) {
|
|
virStorageSource *src = vm->def->disks[i]->src;
|
|
virStorageSource *n;
|
|
|
|
if (!src)
|
|
continue;
|
|
|
|
if (virStorageSourceIsLocalStorage(src) && src->path &&
|
|
(src->shared || src->readonly))
|
|
g_hash_table_insert(notRestored, g_strdup(src->path), NULL);
|
|
|
|
for (n = src->backingStore; virStorageSourceIsBacking(n); n = n->backingStore) {
|
|
if (virStorageSourceIsLocalStorage(n) && n->path)
|
|
g_hash_table_insert(notRestored, g_strdup(n->path), NULL);
|
|
}
|
|
}
|
|
|
|
/* Mocking is enabled only when this env variable is set.
|
|
* See mock code for explanation. */
|
|
if (g_setenv(ENVVAR, "1", FALSE) == FALSE)
|
|
return -1;
|
|
|
|
if (qemuSecuritySetAllLabel(data->driver, vm, NULL, false) < 0)
|
|
goto cleanup;
|
|
|
|
qemuSecurityRestoreAllLabel(data->driver, vm, false);
|
|
|
|
if (checkPaths(notRestored) < 0)
|
|
goto cleanup;
|
|
|
|
ret = 0;
|
|
cleanup:
|
|
g_unsetenv(ENVVAR);
|
|
freePaths();
|
|
return ret;
|
|
}
|
|
|
|
|
|
static int
|
|
mymain(void)
|
|
{
|
|
virQEMUDriver driver;
|
|
virSecurityManager *stack = NULL;
|
|
virSecurityManager *dac = NULL;
|
|
#ifdef WITH_SELINUX
|
|
virSecurityManager *selinux = NULL;
|
|
#endif
|
|
int ret = 0;
|
|
|
|
if (!virSecurityXATTRNamespaceDefined())
|
|
return EXIT_AM_SKIP;
|
|
|
|
if (virInitialize() < 0 ||
|
|
qemuTestDriverInit(&driver) < 0)
|
|
return -1;
|
|
|
|
/* Now fix the secdriver */
|
|
virObjectUnref(driver.securityManager);
|
|
|
|
if (!(dac = virSecurityManagerNewDAC("test", 1000, 1000,
|
|
VIR_SECURITY_MANAGER_PRIVILEGED |
|
|
VIR_SECURITY_MANAGER_DYNAMIC_OWNERSHIP,
|
|
NULL))) {
|
|
fprintf(stderr, "Cannot initialize DAC security driver");
|
|
ret = -1;
|
|
goto cleanup;
|
|
}
|
|
|
|
if (!(stack = virSecurityManagerNewStack(dac))) {
|
|
fprintf(stderr, "Cannot initialize stack security driver");
|
|
ret = -1;
|
|
goto cleanup;
|
|
}
|
|
dac = NULL;
|
|
|
|
#if WITH_SELINUX
|
|
selinux = virSecurityManagerNew("selinux", "test",
|
|
VIR_SECURITY_MANAGER_PRIVILEGED |
|
|
VIR_SECURITY_MANAGER_DEFAULT_CONFINED |
|
|
VIR_SECURITY_MANAGER_REQUIRE_CONFINED);
|
|
if (!selinux) {
|
|
fprintf(stderr, "Cannot initialize selinux security driver");
|
|
ret = -1;
|
|
goto cleanup;
|
|
}
|
|
|
|
if (virSecurityManagerStackAddNested(stack, selinux) < 0) {
|
|
fprintf(stderr, "Cannot add selinux security driver onto stack");
|
|
ret = -1;
|
|
goto cleanup;
|
|
}
|
|
selinux = NULL;
|
|
#endif
|
|
|
|
driver.securityManager = g_steal_pointer(&stack);
|
|
|
|
|
|
#define DO_TEST_DOMAIN(f) \
|
|
do { \
|
|
struct testData data = {.driver = &driver, .file = f}; \
|
|
if (virTestRun(f, testDomain, &data) < 0) \
|
|
ret = -1; \
|
|
} while (0)
|
|
|
|
DO_TEST_DOMAIN("acpi-table");
|
|
DO_TEST_DOMAIN("channel-unix-guestfwd");
|
|
DO_TEST_DOMAIN("console-virtio-unix");
|
|
DO_TEST_DOMAIN("controller-virtio-scsi");
|
|
DO_TEST_DOMAIN("disk-aio");
|
|
DO_TEST_DOMAIN("disk-backing-chains-noindex");
|
|
DO_TEST_DOMAIN("disk-cache");
|
|
DO_TEST_DOMAIN("disk-cdrom");
|
|
DO_TEST_DOMAIN("disk-cdrom-bus-other");
|
|
DO_TEST_DOMAIN("disk-cdrom-network");
|
|
DO_TEST_DOMAIN("disk-cdrom-tray");
|
|
DO_TEST_DOMAIN("disk-copy_on_read");
|
|
DO_TEST_DOMAIN("disk-detect-zeroes");
|
|
DO_TEST_DOMAIN("disk-error-policy");
|
|
DO_TEST_DOMAIN("disk-floppy");
|
|
DO_TEST_DOMAIN("disk-floppy-q35");
|
|
DO_TEST_DOMAIN("disk-network-gluster");
|
|
DO_TEST_DOMAIN("disk-network-iscsi");
|
|
DO_TEST_DOMAIN("disk-network-nbd");
|
|
DO_TEST_DOMAIN("disk-network-rbd");
|
|
DO_TEST_DOMAIN("disk-network-sheepdog");
|
|
DO_TEST_DOMAIN("disk-network-source-auth");
|
|
DO_TEST_DOMAIN("disk-network-tlsx509-nbd");
|
|
DO_TEST_DOMAIN("disk-network-tlsx509-vxhs");
|
|
DO_TEST_DOMAIN("disk-readonly-disk");
|
|
DO_TEST_DOMAIN("disk-scsi");
|
|
DO_TEST_DOMAIN("disk-scsi-device-auto");
|
|
DO_TEST_DOMAIN("disk-shared");
|
|
DO_TEST_DOMAIN("disk-virtio");
|
|
DO_TEST_DOMAIN("disk-virtio-scsi-reservations");
|
|
DO_TEST_DOMAIN("graphics-vnc-tls-secret");
|
|
DO_TEST_DOMAIN("hugepages-nvdimm");
|
|
DO_TEST_DOMAIN("iothreads-virtio-scsi-pci");
|
|
DO_TEST_DOMAIN("memory-hotplug-nvdimm");
|
|
DO_TEST_DOMAIN("memory-hotplug-nvdimm-access");
|
|
DO_TEST_DOMAIN("memory-hotplug-nvdimm-align");
|
|
DO_TEST_DOMAIN("memory-hotplug-nvdimm-label");
|
|
DO_TEST_DOMAIN("memory-hotplug-nvdimm-pmem");
|
|
DO_TEST_DOMAIN("memory-hotplug-nvdimm-readonly");
|
|
DO_TEST_DOMAIN("net-vhostuser");
|
|
DO_TEST_DOMAIN("os-firmware-bios");
|
|
DO_TEST_DOMAIN("os-firmware-efi");
|
|
DO_TEST_DOMAIN("os-firmware-efi-secboot");
|
|
DO_TEST_DOMAIN("pci-bridge-many-disks");
|
|
DO_TEST_DOMAIN("tseg-explicit-size");
|
|
DO_TEST_DOMAIN("usb-redir-unix");
|
|
DO_TEST_DOMAIN("virtio-non-transitional");
|
|
DO_TEST_DOMAIN("virtio-transitional");
|
|
DO_TEST_DOMAIN("x86_64-pc-graphics");
|
|
DO_TEST_DOMAIN("x86_64-pc-headless");
|
|
DO_TEST_DOMAIN("x86_64-q35-graphics");
|
|
DO_TEST_DOMAIN("x86_64-q35-headless");
|
|
|
|
cleanup:
|
|
qemuTestDriverFree(&driver);
|
|
#ifdef WITH_SELINUX
|
|
virObjectUnref(selinux);
|
|
#endif
|
|
virObjectUnref(dac);
|
|
virObjectUnref(stack);
|
|
return ret == 0 ? EXIT_SUCCESS : EXIT_FAILURE;
|
|
}
|
|
|
|
VIR_TEST_MAIN_PRELOAD(mymain,
|
|
VIR_TEST_MOCK("domaincaps"))
|