1
0
mirror of https://gitlab.com/libvirt/libvirt.git synced 2024-12-26 03:21:44 +03:00

qemu: Enter the namespace on relabelling

Instead of trying to fix our security drivers, we can use a
simple trick to relabel paths in both namespace and the host.
I mean, if we enter the namespace some paths are still shared
with the host so any change done to them is visible from the host
too.
Therefore, we can just enter the namespace and call
SetAllLabel()/RestoreAllLabel() from there. Yes, it has slight
overhead because we have to fork in order to enter the namespace.
But on the other hand, no complexity is added to our code.

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
This commit is contained in:
Michal Privoznik 2016-11-23 11:52:57 +01:00
parent 2160f338a7
commit eadaa97548
4 changed files with 181 additions and 8 deletions

View File

@ -838,7 +838,8 @@ QEMU_DRIVER_SOURCES = \
qemu/qemu_monitor_json.h \
qemu/qemu_driver.c qemu/qemu_driver.h \
qemu/qemu_interface.c qemu/qemu_interface.h \
qemu/qemu_capspriv.h
qemu/qemu_capspriv.h \
qemu/qemu_security.c qemu/qemu_security.h
XENAPI_DRIVER_SOURCES = \
xenapi/xenapi_driver.c xenapi/xenapi_driver.h \

View File

@ -45,6 +45,7 @@
#include "qemu_hotplug.h"
#include "qemu_migration.h"
#include "qemu_interface.h"
#include "qemu_security.h"
#include "cpu/cpu.h"
#include "datatypes.h"
@ -5591,10 +5592,10 @@ qemuProcessLaunch(virConnectPtr conn,
goto cleanup;
VIR_DEBUG("Setting domain security labels");
if (virSecurityManagerSetAllLabel(driver->securityManager,
vm->def,
incoming ? incoming->path : NULL) < 0)
goto cleanup;
if (qemuSecuritySetAllLabel(driver,
vm,
incoming ? incoming->path : NULL) < 0)
goto cleanup;
/* Security manager labeled all devices, therefore
* if any operation from now on fails, we need to ask the caller to
@ -6131,9 +6132,9 @@ void qemuProcessStop(virQEMUDriverPtr driver,
/* Reset Security Labels unless caller don't want us to */
if (!(flags & VIR_QEMU_PROCESS_STOP_NO_RELABEL))
virSecurityManagerRestoreAllLabel(driver->securityManager,
vm->def,
!!(flags & VIR_QEMU_PROCESS_STOP_MIGRATED));
qemuSecurityRestoreAllLabel(driver, vm,
!!(flags & VIR_QEMU_PROCESS_STOP_MIGRATED));
virSecurityManagerReleaseLabel(driver->securityManager, vm->def);
for (i = 0; i < vm->def->ndisks; i++) {

132
src/qemu/qemu_security.c Normal file
View File

@ -0,0 +1,132 @@
/*
* qemu_security.c: QEMU security management
*
* Copyright (C) 2016 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/>.
*
* Authors:
* Michal Privoznik <mprivozn@redhat.com>
*/
#include <config.h>
#include "qemu_domain.h"
#include "qemu_security.h"
#include "virlog.h"
#define VIR_FROM_THIS VIR_FROM_QEMU
VIR_LOG_INIT("qemu.qemu_process");
struct qemuSecuritySetRestoreAllLabelData {
bool set;
virQEMUDriverPtr driver;
virDomainObjPtr vm;
const char *stdin_path;
bool migrated;
};
static int
qemuSecuritySetRestoreAllLabelHelper(pid_t pid,
void *opaque)
{
struct qemuSecuritySetRestoreAllLabelData *data = opaque;
virSecurityManagerPostFork(data->driver->securityManager);
if (data->set) {
VIR_DEBUG("Setting up security labels inside namespace pid=%lld",
(long long) pid);
if (virSecurityManagerSetAllLabel(data->driver->securityManager,
data->vm->def,
data->stdin_path) < 0)
return -1;
} else {
VIR_DEBUG("Restoring security labels inside namespace pid=%lld",
(long long) pid);
if (virSecurityManagerRestoreAllLabel(data->driver->securityManager,
data->vm->def,
data->migrated) < 0)
return -1;
}
return 0;
}
int
qemuSecuritySetAllLabel(virQEMUDriverPtr driver,
virDomainObjPtr vm,
const char *stdin_path)
{
struct qemuSecuritySetRestoreAllLabelData data;
memset(&data, 0, sizeof(data));
data.set = true;
data.driver = driver;
data.vm = vm;
data.stdin_path = stdin_path;
if (qemuDomainNamespaceEnabled(vm, QEMU_DOMAIN_NS_MOUNT)) {
if (virSecurityManagerPreFork(driver->securityManager) < 0)
return -1;
if (virProcessRunInMountNamespace(vm->pid,
qemuSecuritySetRestoreAllLabelHelper,
&data) < 0) {
virSecurityManagerPostFork(driver->securityManager);
return -1;
}
virSecurityManagerPostFork(driver->securityManager);
} else {
if (virSecurityManagerSetAllLabel(driver->securityManager,
vm->def,
stdin_path) < 0)
return -1;
}
return 0;
}
void
qemuSecurityRestoreAllLabel(virQEMUDriverPtr driver,
virDomainObjPtr vm,
bool migrated)
{
struct qemuSecuritySetRestoreAllLabelData data;
memset(&data, 0, sizeof(data));
data.driver = driver;
data.vm = vm;
data.migrated = migrated;
if (qemuDomainNamespaceEnabled(vm, QEMU_DOMAIN_NS_MOUNT)) {
if (virSecurityManagerPreFork(driver->securityManager) < 0)
return;
virProcessRunInMountNamespace(vm->pid,
qemuSecuritySetRestoreAllLabelHelper,
&data);
virSecurityManagerPostFork(driver->securityManager);
} else {
virSecurityManagerRestoreAllLabel(driver->securityManager,
vm->def,
migrated);
}
}

39
src/qemu/qemu_security.h Normal file
View File

@ -0,0 +1,39 @@
/*
* qemu_security.h: QEMU security management
*
* Copyright (C) 2016 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/>.
*
* Authors:
* Michal Privoznik <mprivozn@redhat.com>
*/
#ifndef __QEMU_SECURITY_H__
# define __QEMU_SECURITY_H__
# include <stdbool.h>
# include "qemu_conf.h"
# include "domain_conf.h"
int qemuSecuritySetAllLabel(virQEMUDriverPtr driver,
virDomainObjPtr vm,
const char *stdin_path);
void qemuSecurityRestoreAllLabel(virQEMUDriverPtr driver,
virDomainObjPtr vm,
bool migrated);
#endif /* __QEMU_SECURITY_H__ */