[lxc-devel] [PATCH 6/8] A few changes for unprivileged lxc-start
Serge Hallyn
serge at mail.hallyn.com
Fri Jul 19 14:26:53 UTC 2013
From: Serge Hallyn <serge.hallyn at ubuntu.com>
When doing reboot test, must add clone_newuser to clone flags, else
we can't clone(CLONE_NEWPID).
If we don't have caps at lxc-start, don't refuse to start. Drop the
lxc_caps_check() function altogether as it is unused now.
Signed-off-by: Serge Hallyn <serge.hallyn at ubuntu.com>
---
src/lxc/caps.c | 38 --------------------------------------
src/lxc/caps.h | 4 ----
src/lxc/lxc_start.c | 8 --------
src/lxc/start.c | 24 ++++++++++++------------
4 files changed, 12 insertions(+), 62 deletions(-)
diff --git a/src/lxc/caps.c b/src/lxc/caps.c
index 0544451..56f0241 100644
--- a/src/lxc/caps.c
+++ b/src/lxc/caps.c
@@ -227,42 +227,4 @@ 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;
-}
#endif
diff --git a/src/lxc/caps.h b/src/lxc/caps.h
index 97bdab6..8de9635 100644
--- a/src/lxc/caps.h
+++ b/src/lxc/caps.h
@@ -30,7 +30,6 @@ 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);
#else
@@ -46,9 +45,6 @@ static inline int lxc_caps_up(void) {
static inline int lxc_caps_init(void) {
return 0;
}
-static inline int lxc_caps_check(void) {
- return 1;
-}
static inline int lxc_caps_last_cap(void) {
return 0;
diff --git a/src/lxc/lxc_start.c b/src/lxc/lxc_start.c
index 490dbad..e779304 100644
--- a/src/lxc/lxc_start.c
+++ b/src/lxc/lxc_start.c
@@ -227,14 +227,6 @@ int main(int argc, char *argv[])
}
if (my_args.daemonize) {
- /* do an early check for needed privs, since otherwise the
- * user won't see the error */
-
- if (!lxc_caps_check()) {
- ERROR("Not running with sufficient privilege");
- goto out;
- }
-
if (daemon(0, 0)) {
SYSERROR("failed to daemonize '%s'", my_args.name);
goto out;
diff --git a/src/lxc/start.c b/src/lxc/start.c
index c91b231..00020de 100644
--- a/src/lxc/start.c
+++ b/src/lxc/start.c
@@ -253,17 +253,10 @@ out_sigfd:
return -1;
}
-extern int lxc_caps_check(void);
-
struct lxc_handler *lxc_init(const char *name, struct lxc_conf *conf, const char *lxcpath)
{
struct lxc_handler *handler;
- if (!lxc_caps_check()) {
- ERROR("Not running with sufficient privilege");
- return NULL;
- }
-
handler = malloc(sizeof(*handler));
if (!handler)
return NULL;
@@ -417,10 +410,10 @@ static int container_reboot_supported(void *arg)
return 0;
}
-static int must_drop_cap_sys_boot(void)
+static int must_drop_cap_sys_boot(struct lxc_conf *conf)
{
FILE *f = fopen("/proc/sys/kernel/ctrl-alt-del", "r");
- int ret, cmd, v;
+ int ret, cmd, v, flags;
long stack_size = 4096;
void *stack = alloca(stack_size);
int status;
@@ -439,11 +432,15 @@ static int must_drop_cap_sys_boot(void)
}
cmd = v ? LINUX_REBOOT_CMD_CAD_ON : LINUX_REBOOT_CMD_CAD_OFF;
+ flags = CLONE_NEWPID | SIGCHLD;
+ if (!lxc_list_empty(&conf->id_map))
+ flags |= CLONE_NEWUSER;
+
#ifdef __ia64__
- pid = __clone2(container_reboot_supported, stack, stack_size, CLONE_NEWPID | SIGCHLD, &cmd);
+ pid = __clone2(container_reboot_supported, stack, stack_size, flags, &cmd);
#else
stack += stack_size;
- pid = clone(container_reboot_supported, stack, CLONE_NEWPID | SIGCHLD, &cmd);
+ pid = clone(container_reboot_supported, stack, flags, &cmd);
#endif
if (pid < 0) {
SYSERROR("failed to clone\n");
@@ -668,6 +665,9 @@ int lxc_spawn(struct lxc_handler *handler)
curcgroup = alloca(len);
if (lxc_curcgroup(curcgroup, len) <= 1)
curcgroup = NULL;
+ FILE *f = fopen("/tmp/a", "a");
+ fprintf(f, "curcgroup is %s\n", curcgroup);
+ fclose(f);
}
if ((handler->cgroup = lxc_cgroup_path_create(curcgroup, name)) == NULL)
goto out_delete_net;
@@ -776,7 +776,7 @@ int __lxc_start(const char *name, struct lxc_conf *conf,
handler->ops = ops;
handler->data = data;
- if (must_drop_cap_sys_boot()) {
+ if (must_drop_cap_sys_boot(handler->conf)) {
#if HAVE_SYS_CAPABILITY_H
DEBUG("Dropping cap_sys_boot\n");
#else
--
1.8.3.2
More information about the lxc-devel
mailing list