]> git.ipfire.org Git - thirdparty/libvirt.git/commitdiff
Use libcap-ng to clear capabilities for many child processes
authorDaniel P. Berrange <berrange@redhat.com>
Mon, 29 Jun 2009 17:00:52 +0000 (17:00 +0000)
committerDaniel P. Berrange <berrange@redhat.com>
Mon, 29 Jun 2009 17:00:52 +0000 (17:00 +0000)
ChangeLog
src/Makefile.am
src/qemu_conf.c
src/qemu_driver.c
src/remote_internal.c
src/uml_driver.c
src/util.c
src/util.h

index c25b94cb634d125a27432acfa63cb07837f396db..dc89e19cf3cc3607f1ca23575bda3add06c3e1e5 100644 (file)
--- a/ChangeLog
+++ b/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
index 19ea781140953856a165f2a4cca12c45fa8588ac..0c284c0e595779722085a3e3801f18b0dc365b6c 100644 (file)
@@ -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)
index 99193dcfffaa9c67572d00f510dbfd84cac4b20f..83992a3960497a9767b87698ac911b75ac67b0ee 100644 (file)
@@ -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;
index 2599212793fd388e87da24269956802201e88ac4..95ea88255eba2980e8fe84d9e8bb0089e5da14e8 100644 (file)
@@ -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);
index 9dc9bc144a5c54e8080da232c6cc1b243df283b0..6df02827fff16dbb10e72ab537c2512b0232f58d 100644 (file)
@@ -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. */
index 70ca899512f8db17d0cb1051271c4b1ff1e21e3b..dc1e8ef7e414101d5d7355acd036c7e98815d12b 100644 (file)
@@ -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++)
index 408e17ac3eec77455e08c08b39f1a3ceea5bf985..f82cddcb11ed1d921c39d1dddaf94ae8a850f4f7 100644 (file)
 #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) {
index e6e801035509ddfe9f8d9154d5a10cbb465c8b89..6dd005fe6a42da77f8cd211730df7396b6bedaa7 100644 (file)
@@ -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);