diff options
author | 2012-02-02 15:54:53 -0600 | |
---|---|---|
committer | 2012-02-26 10:44:40 +0100 | |
commit | 4a2ca8b2ba4b9820a3e3e26e2cf081c17d8737f9 (patch) | |
tree | 19c8961b56cc0f245cda7d866e0454e56fc8b0b9 | |
parent | recursively delete cgroups on container shutdown (diff) | |
download | lxc-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.c | 39 | ||||
-rw-r--r-- | src/lxc/caps.h | 1 | ||||
-rw-r--r-- | src/lxc/start.c | 7 |
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; |