[lxc-devel] Patch: Allow to drop capabilities for container

Michael Holzt lxc at my.fqdn.org
Mon Jan 4 03:39:54 UTC 2010


Hello everyone!

I've written a patch against lxc 0.6.4 which adds a new config keyword 
'lxc.dropcap'. This keyword allows to specify capabilities which are 
dropped before executing the container binary.

Example:

| # grep dropcap /var/lib/lxc/webhost/config 
| lxc.dropcap = CAP_SYS_CHROOT
| lxc.dropcap = CAP_MKNOD
|
| # lxc-start -n webhost /bin/sh
| # getpcaps 1
| Capabilities for : =ep cap_sys_chroot,cap_sys_boot,cap_mknod-ep

I attach the patch to this mail with the hope that it is useful and will be
merged.


Regards
Michael

-- 
It's an insane world, but i'm proud to be a part of it. -- Bill Hicks
-------------- next part --------------
diff -Naur lxc-0.6.4/src/lxc/conf.c lxc-0.6.4-dropcap/src/lxc/conf.c
--- lxc-0.6.4/src/lxc/conf.c	2009-11-24 09:47:26.000000000 +0100
+++ lxc-0.6.4-dropcap/src/lxc/conf.c	2010-01-04 04:36:07.000000000 +0100
@@ -38,6 +38,7 @@
 #include <sys/socket.h>
 #include <sys/mount.h>
 #include <sys/mman.h>
+#include <sys/prctl.h>
 
 #include <arpa/inet.h>
 #include <fcntl.h>
@@ -73,6 +74,11 @@
 	int flag;
 };
 
+struct dropcap_opt {
+	char *name;
+	int value;
+};
+
 static int instanciate_veth(struct lxc_netdev *);
 static int instanciate_macvlan(struct lxc_netdev *);
 static int instanciate_phys(struct lxc_netdev *);
@@ -109,6 +115,44 @@
 	{ NULL,         0, 0              },
 };
 
+static struct dropcap_opt dropcap_opt[] = {
+	{ "CAP_CHOWN",			0 },
+	{ "CAP_DAC_OVERRIDE",		1 },
+	{ "CAP_DAC_READ_SEARCH",	2 },
+	{ "CAP_FOWNER",			3 },
+	{ "CAP_FSETID",			4 },
+	{ "CAP_KILL",			5 },
+	{ "CAP_SETGID",			6 },
+	{ "CAP_SETUID",			7 },
+	{ "CAP_SETPCAP",		8 },
+	{ "CAP_LINUX_IMMUTABLE",	9 },
+	{ "CAP_NET_BIND_SERVICE",	10 },
+	{ "CAP_NET_BROADCAST",		11 },
+	{ "CAP_NET_ADMIN",		12 },
+	{ "CAP_NET_RAW",		13 },
+	{ "CAP_IPC_LOCK",		14 },
+	{ "CAP_IPC_OWNER",		15 },
+	{ "CAP_SYS_MODULE",		16 },
+	{ "CAP_SYS_RAWIO",		17 },
+	{ "CAP_SYS_CHROOT",		18 },
+	{ "CAP_SYS_PTRACE",		19 },
+	{ "CAP_SYS_PACCT",		20 },
+	{ "CAP_SYS_ADMIN",		21 },
+	{ "CAP_SYS_BOOT",		22 },
+	{ "CAP_SYS_NICE",		23 },
+	{ "CAP_SYS_RESOURCE",		24 },
+	{ "CAP_SYS_TIME",		25 },
+	{ "CAP_SYS_TTY_CONFIG",		26 },
+	{ "CAP_MKNOD",			27 },
+	{ "CAP_LEASE",			28 },
+	{ "CAP_AUDIT_WRITE",		29 },
+	{ "CAP_AUDIT_CONTROL",		30 },
+	{ "CAP_SETFCAP",		31 },
+	{ "CAP_MAC_OVERRIDE",		32 },
+	{ "CAP_MAC_ADMIN",		33 },
+	{ NULL,				0 },
+};
+
 static int configure_find_fstype_cb(void* buffer, void *data)
 {
 	struct cbarg {
@@ -620,6 +664,40 @@
 	return ret;
 }
 
+static int setup_dropcap(struct lxc_list *dropcap)
+{
+	struct lxc_list *iterator;
+	struct dropcap_opt *dco;
+	char *drop_entry;
+	int capid;
+
+	lxc_list_for_each(iterator, dropcap) {
+		drop_entry = iterator->elem;
+
+		capid = -1;
+		
+		for (dco = &dropcap_opt[0]; dco->name != NULL; dco++) {
+			if (!strncmp(drop_entry, dco->name, strlen(dco->name)))
+				capid = dco->value;
+		}
+
+	        if ( capid < 0 ) {
+        		ERROR("unknown capability %s", drop_entry);
+        		return -1;
+		}
+
+		DEBUG("drop capability %s (%d)", drop_entry, capid);
+
+		if (prctl(PR_CAPBSET_DROP, capid, 0, 0, 0)) {
+                       SYSERROR("failed to remove %s capability", drop_entry);
+                       return -1;
+                }
+                                               
+	}
+
+	return 0;
+}
+
 static int setup_hw_addr(char *hwaddr, const char *ifname)
 {
 	struct sockaddr sockaddr;
@@ -824,6 +902,7 @@
 	lxc_list_init(&conf->cgroup);
 	lxc_list_init(&conf->network);
 	lxc_list_init(&conf->mount_list);
+	lxc_list_init(&conf->dropcap);
 	return 0;
 }
 
@@ -1095,6 +1174,11 @@
 		ERROR("failed to setup the new pts instance");
 		return -1;
 	}
+	
+	if (setup_dropcap(&lxc_conf->dropcap)) {
+		ERROR("failed to drop capabilities");
+		return -1;
+	}
 
 	NOTICE("'%s' is setup.", name);
 
diff -Naur lxc-0.6.4/src/lxc/conf.h lxc-0.6.4-dropcap/src/lxc/conf.h
--- lxc-0.6.4/src/lxc/conf.h	2009-11-19 15:06:02.000000000 +0100
+++ lxc-0.6.4-dropcap/src/lxc/conf.h	2010-01-04 04:19:50.000000000 +0100
@@ -140,6 +140,7 @@
 	struct lxc_list cgroup;
 	struct lxc_list network;
 	struct lxc_list mount_list;
+	struct lxc_list dropcap;
 	struct lxc_tty_info tty_info;
 	char console[MAXPATHLEN];
 };
@@ -173,4 +174,5 @@
 #define conf_has_cgroup(__name)  conf_has(__name, "cgroup")
 #define conf_has_tty(__name)     conf_has(__name, "tty")
 #define conf_has_pts(__name)     conf_has(__name, "pts")
+#define conf_has_dropcap(__name) conf_has(__name, "dropcap")
 #endif
diff -Naur lxc-0.6.4/src/lxc/confile.c lxc-0.6.4-dropcap/src/lxc/confile.c
--- lxc-0.6.4/src/lxc/confile.c	2009-11-19 15:06:02.000000000 +0100
+++ lxc-0.6.4-dropcap/src/lxc/confile.c	2010-01-04 04:18:49.000000000 +0100
@@ -53,6 +53,7 @@
 static int config_network_mtu(const char *, char *, struct lxc_conf *);
 static int config_network_ipv4(const char *, char *, struct lxc_conf *);
 static int config_network_ipv6(const char *, char *, struct lxc_conf *);
+static int config_dropcap(const char *, char *, struct lxc_conf *);
 
 typedef int (*config_cb)(const char *, char *, struct lxc_conf *);
 
@@ -77,6 +78,7 @@
 	{ "lxc.network.mtu",    config_network_mtu    },
 	{ "lxc.network.ipv4",   config_network_ipv4   },
 	{ "lxc.network.ipv6",   config_network_ipv6   },
+	{ "lxc.dropcap",	config_dropcap	      },
 };
 
 static const size_t config_size = sizeof(config)/sizeof(struct config);
@@ -478,6 +480,26 @@
 	return 0;
 }
 
+static int config_dropcap(const char *key, char *value, struct lxc_conf *lxc_conf)
+{
+	char *dropelem;
+	struct lxc_list *droplist;
+
+	if (!strlen(value))
+		return -1;
+
+	droplist = malloc(sizeof(*droplist));
+	if (!droplist)
+		return -1;
+
+	dropelem = strdup(value);
+	droplist->elem = dropelem;
+
+	lxc_list_add_tail(&lxc_conf->dropcap, droplist);
+
+	return 0;
+}
+
 static int config_rootfs(const char *key, char *value, struct lxc_conf *lxc_conf)
 {
 	if (strlen(value) >= MAXPATHLEN) {


More information about the lxc-devel mailing list