[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