mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-01-22 04:25:18 +00:00
Use libcap-ng to clear capabilities for many child processes
This commit is contained in:
parent
1a982aef18
commit
96619805cb
12
ChangeLog
12
ChangeLog
@ -1,3 +1,15 @@
|
||||
Mon Jun 29 12:48:20 BST 2009 Daniel P. Berrange <berrange@redhat.com>
|
||||
|
||||
Use libcap-ng to clear capabilities for many child processes
|
||||
* src/Makefile.am: Link to libcap-ng in util code
|
||||
* src/qemu_conf.c: Clear capabilities when running qemu -help
|
||||
* src/qemu_driver.c: Clear capabilities when running VMs
|
||||
* src/remote_internal.c: Clear capabilities for auto-spawned
|
||||
libvirtd session daemon, and SSH tunnel client
|
||||
* src/uml_driver.c: Clear capabilities for UML VMs
|
||||
* src/util.h, src/util.c: Add virExec() flag to allow
|
||||
clearing of capabilities when spawning processes
|
||||
|
||||
Mon Jun 29 12:28:20 BST 2009 Daniel P. Berrange <berrange@redhat.com>
|
||||
|
||||
Prepare for using libcap-ng
|
||||
|
@ -215,6 +215,8 @@ noinst_LTLIBRARIES = libvirt_util.la
|
||||
libvirt_la_LIBADD = libvirt_util.la
|
||||
libvirt_util_la_SOURCES = \
|
||||
$(UTIL_SOURCES)
|
||||
libvirt_util_la_CFLAGS = $(CAPNG_CFLAGS)
|
||||
libvirt_util_la_LDFLAGS = $(CAPNG_LIBS)
|
||||
|
||||
noinst_LTLIBRARIES += libvirt_driver.la
|
||||
libvirt_la_LIBADD += libvirt_driver.la
|
||||
@ -664,9 +666,9 @@ libvirt_lxc_SOURCES = \
|
||||
$(LXC_CONTROLLER_SOURCES) \
|
||||
$(UTIL_SOURCES) \
|
||||
$(DOMAIN_CONF_SOURCES)
|
||||
libvirt_lxc_LDFLAGS = $(WARN_CFLAGS) $(COVERAGE_LDCFLAGS)
|
||||
libvirt_lxc_LDFLAGS = $(WARN_CFLAGS) $(COVERAGE_LDCFLAGS) $(CAPNG_LIBS)
|
||||
libvirt_lxc_LDADD = $(LIBXML_LIBS) $(NUMACTL_LIBS) ../gnulib/lib/libgnu.la
|
||||
libvirt_lxc_CFLAGS = $(LIBPARTED_CFLAGS) $(NUMACTL_CFLAGS)
|
||||
libvirt_lxc_CFLAGS = $(LIBPARTED_CFLAGS) $(NUMACTL_CFLAGS) $(CAPNG_CFLAGS)
|
||||
endif
|
||||
endif
|
||||
EXTRA_DIST += $(LXC_CONTROLLER_SOURCES)
|
||||
|
@ -596,7 +596,7 @@ int qemudExtractVersionInfo(const char *qemu,
|
||||
*retversion = 0;
|
||||
|
||||
if (virExec(NULL, qemuarg, qemuenv, NULL,
|
||||
&child, -1, &newstdout, NULL, VIR_EXEC_NONE) < 0)
|
||||
&child, -1, &newstdout, NULL, VIR_EXEC_CLEAR_CAPS) < 0)
|
||||
return -1;
|
||||
|
||||
char *help = NULL;
|
||||
|
@ -1461,7 +1461,7 @@ static int qemudStartVMDaemon(virConnectPtr conn,
|
||||
|
||||
ret = virExecDaemonize(conn, argv, progenv, &keepfd, &child,
|
||||
stdin_fd, &logfile, &logfile,
|
||||
VIR_EXEC_NONBLOCK,
|
||||
VIR_EXEC_NONBLOCK | VIR_EXEC_CLEAR_CAPS,
|
||||
qemudSecurityHook, &hookData,
|
||||
pidfile);
|
||||
VIR_FREE(pidfile);
|
||||
|
@ -295,7 +295,8 @@ remoteForkDaemon(virConnectPtr conn)
|
||||
}
|
||||
|
||||
if (virExecDaemonize(NULL, daemonargs, NULL, NULL,
|
||||
&pid, -1, NULL, NULL, 0,
|
||||
&pid, -1, NULL, NULL,
|
||||
VIR_EXEC_CLEAR_CAPS,
|
||||
NULL, NULL, NULL) < 0)
|
||||
return -1;
|
||||
|
||||
@ -749,7 +750,8 @@ doRemoteOpen (virConnectPtr conn,
|
||||
}
|
||||
|
||||
if (virExec(conn, (const char**)cmd_argv, NULL, NULL,
|
||||
&pid, sv[1], &(sv[1]), NULL, VIR_EXEC_NONE) < 0)
|
||||
&pid, sv[1], &(sv[1]), NULL,
|
||||
VIR_EXEC_CLEAR_CAPS) < 0)
|
||||
goto failed;
|
||||
|
||||
/* Parent continues here. */
|
||||
|
@ -845,7 +845,8 @@ static int umlStartVMDaemon(virConnectPtr conn,
|
||||
|
||||
ret = virExecDaemonize(conn, argv, progenv, &keepfd, &pid,
|
||||
-1, &logfd, &logfd,
|
||||
0, NULL, NULL, NULL);
|
||||
VIR_EXEC_CLEAR_CAPS,
|
||||
NULL, NULL, NULL);
|
||||
close(logfd);
|
||||
|
||||
for (i = 0 ; argv[i] ; i++)
|
||||
|
33
src/util.c
33
src/util.c
@ -56,6 +56,10 @@
|
||||
#ifdef HAVE_GETPWUID_R
|
||||
#include <pwd.h>
|
||||
#endif
|
||||
#if HAVE_CAPNG
|
||||
#include <cap-ng.h>
|
||||
#endif
|
||||
|
||||
|
||||
#include "virterror_internal.h"
|
||||
#include "logging.h"
|
||||
@ -264,6 +268,29 @@ int virSetCloseExec(int fd) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
#if HAVE_CAPNG
|
||||
static int virClearCapabilities(void)
|
||||
{
|
||||
int ret;
|
||||
|
||||
capng_clear(CAPNG_SELECT_BOTH);
|
||||
|
||||
if ((ret = capng_apply(CAPNG_SELECT_BOTH)) < 0) {
|
||||
VIR_ERROR("cannot clear process capabilities %d", ret);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
static int virClearCapabilities(void)
|
||||
{
|
||||
// VIR_WARN0("libcap-ng support not compiled in, unable to clear capabilities");
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* @conn Connection to report errors against
|
||||
* @argv argv to exec
|
||||
@ -481,6 +508,12 @@ __virExec(virConnectPtr conn,
|
||||
if ((hook)(data) != 0)
|
||||
_exit(1);
|
||||
|
||||
/* The hook above may need todo something privileged, so
|
||||
* we delay clearing capabilities until now */
|
||||
if ((flags & VIR_EXEC_CLEAR_CAPS) &&
|
||||
virClearCapabilities() < 0)
|
||||
_exit(1);
|
||||
|
||||
/* Daemonize as late as possible, so the parent process can detect
|
||||
* the above errors with wait* */
|
||||
if (flags & VIR_EXEC_DAEMON) {
|
||||
|
@ -37,6 +37,7 @@ enum {
|
||||
VIR_EXEC_NONE = 0,
|
||||
VIR_EXEC_NONBLOCK = (1 << 0),
|
||||
VIR_EXEC_DAEMON = (1 << 1),
|
||||
VIR_EXEC_CLEAR_CAPS = (1 << 2),
|
||||
};
|
||||
|
||||
int virSetNonBlock(int fd);
|
||||
|
Loading…
x
Reference in New Issue
Block a user