]> git.ipfire.org Git - thirdparty/libvirt.git/commitdiff
Reduce LXC capabilities
authorDaniel P. Berrange <berrange@redhat.com>
Mon, 29 Jun 2009 17:09:42 +0000 (17:09 +0000)
committerDaniel P. Berrange <berrange@redhat.com>
Mon, 29 Jun 2009 17:09:42 +0000 (17:09 +0000)
ChangeLog
src/lxc_container.c
src/lxc_controller.c

index dc89e19cf3cc3607f1ca23575bda3add06c3e1e5..90047c98dc8a4c0bb0b4ebfcd699defacd431550 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+Mon Jun 29 18:01:20 BST 2009 Daniel P. Berrange <berrange@redhat.com>
+
+       Reduce LXC capabilities
+       * src/lxc_container.c: Use libcap-ng to clear capabilities,
+       and also drop SYS_MODULE, SYS_TIME, AUDIT_CONTROL, and
+       MAC_ADMIN, in addition to SYS_BOOT.
+       * src/lxc_controller.c: Drop all capabilities once container
+       has been spawned.
+
 Mon Jun 29 12:48:20 BST 2009 Daniel P. Berrange <berrange@redhat.com>
 
        Use libcap-ng to clear capabilities for many child processes
index 2592b10803164a507071a4f481369641050d4608..950dd502153db7474f94f324179f487900a5f77c 100644 (file)
@@ -41,8 +41,9 @@
 /* For MS_MOVE */
 #include <linux/fs.h>
 
-#include <sys/prctl.h>
-#include <linux/capability.h>
+#if HAVE_CAPNG
+#include <cap-ng.h>
+#endif
 
 #include "virterror_internal.h"
 #include "logging.h"
@@ -642,27 +643,48 @@ static int lxcContainerSetupMounts(virDomainDefPtr vmDef,
         return lxcContainerSetupExtraMounts(vmDef);
 }
 
-static int lxcContainerDropCapabilities(virDomainDefPtr vmDef ATTRIBUTE_UNUSED)
+
+/*
+ * This is running as the 'init' process insid the container.
+ * It removes some capabilities that could be dangerous to
+ * host system, since they are not currently "containerized"
+ */
+static int lxcContainerDropCapabilities(void)
 {
-#ifdef PR_CAPBSET_DROP
-    int i;
-    const struct {
-        int id;
-        const char *name;
-    } caps[] = {
-#define ID_STRING(name) name, #name
-        { ID_STRING(CAP_SYS_BOOT) },
-    };
+#if HAVE_CAPNG
+    int ret;
+
+    capng_get_caps_process();
+
+    if ((ret = capng_updatev(CAPNG_DROP,
+                             CAPNG_EFFECTIVE | CAPNG_PERMITTED |
+                             CAPNG_INHERITABLE | CAPNG_BOUNDING_SET,
+                             CAP_SYS_BOOT, /* No use of reboot */
+                             CAP_SYS_MODULE, /* No kernel module loading */
+                             CAP_SYS_TIME, /* No changing the clock */
+                             CAP_AUDIT_CONTROL, /* No messing with auditing status */
+                             CAP_MAC_ADMIN, /* No messing with LSM config */
+                             -1 /* sentinal */)) < 0) {
+        lxcError(NULL, NULL, VIR_ERR_INTERNAL_ERROR,
+                 _("failed to remove capabilities %d"), ret);
+        return -1;
+    }
 
-    for (i = 0 ; i < ARRAY_CARDINALITY(caps) ; i++) {
-        if (prctl(PR_CAPBSET_DROP, caps[i].id, 0, 0, 0)) {
-            lxcError(NULL, NULL, VIR_ERR_INTERNAL_ERROR,
-                     _("failed to drop %s"), caps[i].name);
-            return -1;
-        }
+    if ((ret = capng_apply(CAPNG_SELECT_BOTH)) < 0) {
+        lxcError(NULL, NULL, VIR_ERR_INTERNAL_ERROR,
+                 _("failed to apply capabilities: %d"), ret);
+        return -1;
     }
-#else /* ! PR_CAPBSET_DROP */
-    VIR_WARN0(_("failed to drop capabilities PR_CAPBSET_DROP undefined"));
+
+    /* Need to prevent them regaining any caps on exec */
+    if ((ret = capng_lock()) < 0) {
+        lxcError(NULL, NULL, VIR_ERR_INTERNAL_ERROR,
+                 _("failed to lock capabilities: %d"), ret);
+        return -1;
+    }
+
+#else
+    VIR_WARN0(_("libcap-ng support not compiled in, unable to clear capabilities"));
 #endif
     return 0;
 }
@@ -735,7 +757,7 @@ static int lxcContainerChild( void *data )
         return -1;
 
     /* drop a set of root capabilities */
-    if (lxcContainerDropCapabilities(vmDef) < 0)
+    if (lxcContainerDropCapabilities() < 0)
         return -1;
 
     /* this function will only return if an error occured */
index 356ecb80b447da62c3d74531997cb0b9d77691e0..08fbbe43fb818d2d31fe03ec0fe2765cb9ce6606 100644 (file)
 #include <getopt.h>
 #include <sys/mount.h>
 
+#if HAVE_CAPNG
+#include <cap-ng.h>
+#endif
+
 #include "virterror_internal.h"
 #include "logging.h"
 #include "util.h"
@@ -210,6 +214,25 @@ cleanup:
     return rc;
 }
 
+
+static int lxcControllerClearCapabilities(void)
+{
+#if HAVE_CAPNG
+    int ret;
+
+    capng_clear(CAPNG_SELECT_BOTH);
+
+    if ((ret = capng_apply(CAPNG_SELECT_BOTH)) < 0) {
+        lxcError(NULL, NULL, VIR_ERR_INTERNAL_ERROR,
+                 _("failed to apply capabilities: %d"), ret);
+        return -1;
+    }
+#else
+    VIR_WARN0(_("libcap-ng support not compiled in, unable to clear capabilities"));
+#endif
+    return 0;
+}
+
 typedef struct _lxcTtyForwardFd_t {
     int fd;
     int active;
@@ -562,6 +585,11 @@ lxcControllerRun(virDomainDefPtr def,
     if (lxcContainerSendContinue(control[0]) < 0)
         goto cleanup;
 
+    /* Now the container is running, there's no need for us to keep
+       any elevated capabilities */
+    if (lxcControllerClearCapabilities() < 0)
+        goto cleanup;
+
     rc = lxcControllerMain(monitor, client, appPty, containerPty);
 
 cleanup: