aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSerge Hallyn <serge.hallyn@canonical.com>2012-02-02 15:54:53 -0600
committerDaniel Lezcano <daniel.lezcano@free.fr>2012-02-26 10:44:40 +0100
commit4a2ca8b2ba4b9820a3e3e26e2cf081c17d8737f9 (patch)
tree19c8961b56cc0f245cda7d866e0454e56fc8b0b9
parentrecursively delete cgroups on container shutdown (diff)
downloadlxc-4a2ca8b2ba4b9820a3e3e26e2cf081c17d8737f9.tar.gz
lxc-4a2ca8b2ba4b9820a3e3e26e2cf081c17d8737f9.tar.bz2
lxc-4a2ca8b2ba4b9820a3e3e26e2cf081c17d8737f9.zip
lxc-start: exit early and cleanly if we have insufficient privs
Signed-off-by: Serge Hallyn <serge.hallyn@canonical.com> Signed-off-by: Daniel Lezcano <dlezcano@fr.ibm.com>
-rw-r--r--src/lxc/caps.c39
-rw-r--r--src/lxc/caps.h1
-rw-r--r--src/lxc/start.c7
3 files changed, 47 insertions, 0 deletions
diff --git a/src/lxc/caps.c b/src/lxc/caps.c
index 1610002..10a0b4a 100644
--- a/src/lxc/caps.c
+++ b/src/lxc/caps.c
@@ -213,3 +213,42 @@ int lxc_caps_last_cap(void)
return last_cap;
}
+
+/*
+ * check if we have the caps needed to start a container. returns 1 on
+ * success, 0 on error. (I'd prefer this be a bool, but am afraid that
+ * might fail to build on some distros).
+ */
+int lxc_caps_check(void)
+{
+ uid_t uid = getuid();
+ cap_t caps;
+ cap_flag_value_t value;
+ int i, ret;
+
+ cap_value_t needed_caps[] = { CAP_SYS_ADMIN, CAP_NET_ADMIN, CAP_SETUID, CAP_SETGID };
+
+#define NUMCAPS ((int) (sizeof(needed_caps) / sizeof(cap_t)))
+
+ if (!uid)
+ return 1;
+
+ caps = cap_get_proc();
+ if (!caps) {
+ ERROR("failed to cap_get_proc: %m");
+ return 0;
+ }
+
+ for (i=0; i<NUMCAPS; i++) {
+ ret = cap_get_flag(caps, needed_caps[i], CAP_EFFECTIVE, &value);
+ if (ret) {
+ ERROR("Failed to cap_get_flag: %m");
+ return 0;
+ }
+ if (!value) {
+ return 0;
+ }
+ }
+
+ return 1;
+}
diff --git a/src/lxc/caps.h b/src/lxc/caps.h
index e4e0d42..0cf8460 100644
--- a/src/lxc/caps.h
+++ b/src/lxc/caps.h
@@ -27,6 +27,7 @@ extern int lxc_caps_reset(void);
extern int lxc_caps_down(void);
extern int lxc_caps_up(void);
extern int lxc_caps_init(void);
+extern int lxc_caps_check(void);
extern int lxc_caps_last_cap(void);
diff --git a/src/lxc/start.c b/src/lxc/start.c
index eb7d01f..91ce5fa 100644
--- a/src/lxc/start.c
+++ b/src/lxc/start.c
@@ -319,10 +319,17 @@ out_sigfd:
return -1;
}
+extern int lxc_caps_check(void);
+
struct lxc_handler *lxc_init(const char *name, struct lxc_conf *conf)
{
struct lxc_handler *handler;
+ if (!lxc_caps_check()) {
+ ERROR("Not running with sufficient privilege");
+ return NULL;
+ }
+
handler = malloc(sizeof(*handler));
if (!handler)
return NULL;