utils: make lxc_setgroups() return bool

parent 964581c2
...@@ -859,8 +859,7 @@ static int attach_child_main(struct attach_clone_payload *payload) ...@@ -859,8 +859,7 @@ static int attach_child_main(struct attach_clone_payload *payload)
goto on_error; goto on_error;
} }
ret = lxc_setgroups(0, NULL); if (!lxc_setgroups(0, NULL) && errno != EPERM)
if (ret < 0 && errno != EPERM)
goto on_error; goto on_error;
/* Set {u,g}id. */ /* Set {u,g}id. */
......
...@@ -108,8 +108,7 @@ static int do_child(void *vargv) ...@@ -108,8 +108,7 @@ static int do_child(void *vargv)
if (ret < 0) if (ret < 0)
return -1; return -1;
ret = lxc_setgroups(0, NULL); if (!lxc_setgroups(0, NULL))
if (ret < 0)
return -1; return -1;
ret = unshare(CLONE_NEWNS); ret = unshare(CLONE_NEWNS);
......
...@@ -1046,7 +1046,6 @@ static int do_start(void *data) ...@@ -1046,7 +1046,6 @@ static int do_start(void *data)
{ {
int ret; int ret;
char path[PATH_MAX]; char path[PATH_MAX];
bool have_cap_setgid;
uid_t new_uid; uid_t new_uid;
gid_t new_gid; gid_t new_gid;
struct lxc_list *iterator; struct lxc_list *iterator;
...@@ -1132,8 +1131,8 @@ static int do_start(void *data) ...@@ -1132,8 +1131,8 @@ static int do_start(void *data)
/* Drop groups only after we switched to a valid gid in the new /* Drop groups only after we switched to a valid gid in the new
* user namespace. * user namespace.
*/ */
ret = lxc_setgroups(0, NULL); if (!lxc_setgroups(0, NULL) &&
if (ret < 0 && (handler->am_root || errno != EPERM)) (handler->am_root || errno != EPERM))
goto out_warn_father; goto out_warn_father;
ret = prctl(PR_SET_DUMPABLE, prctl_arg(1), prctl_arg(0), ret = prctl(PR_SET_DUMPABLE, prctl_arg(1), prctl_arg(0),
...@@ -1356,21 +1355,6 @@ static int do_start(void *data) ...@@ -1356,21 +1355,6 @@ static int do_start(void *data)
new_uid = handler->conf->init_uid; new_uid = handler->conf->init_uid;
new_gid = handler->conf->init_gid; new_gid = handler->conf->init_gid;
/* If we are in a new user namespace we already dropped all groups when
* we switched to root in the new user namespace further above. Only
* drop groups if we can, so ensure that we have necessary privilege.
*/
#if HAVE_LIBCAP
have_cap_setgid = lxc_proc_cap_is_set(CAP_SETGID, CAP_EFFECTIVE);
#else
have_cap_setgid = false;
#endif
if (lxc_list_empty(&handler->conf->id_map) && have_cap_setgid) {
ret = lxc_setgroups(0, NULL);
if (ret < 0)
goto out_warn_father;
}
/* Avoid unnecessary syscalls. */ /* Avoid unnecessary syscalls. */
if (new_uid == nsuid) if (new_uid == nsuid)
new_uid = LXC_INVALID_UID; new_uid = LXC_INVALID_UID;
...@@ -1382,6 +1366,17 @@ static int do_start(void *data) ...@@ -1382,6 +1366,17 @@ static int do_start(void *data)
if (ret < 0) if (ret < 0)
goto out_warn_father; goto out_warn_father;
/* If we are in a new user namespace we already dropped all groups when
* we switched to root in the new user namespace further above. Only
* drop groups if we can, so ensure that we have necessary privilege.
*/
if (lxc_list_empty(&handler->conf->id_map))
#if HAVE_LIBCAP
if (lxc_proc_cap_is_set(CAP_SETGID, CAP_EFFECTIVE))
#endif
if (!lxc_setgroups(0, NULL))
goto out_warn_father;
ret = lxc_ambient_caps_down(); ret = lxc_ambient_caps_down();
if (ret < 0) { if (ret < 0) {
ERROR("Failed to clear ambient capabilities"); ERROR("Failed to clear ambient capabilities");
......
...@@ -54,8 +54,7 @@ int lxc_rsync_exec_wrapper(void *data) ...@@ -54,8 +54,7 @@ int lxc_rsync_exec_wrapper(void *data)
if (ret < 0) if (ret < 0)
return -1; return -1;
ret = lxc_setgroups(0, NULL); if (!lxc_setgroups(0, NULL))
if (ret < 0)
return -1; return -1;
return lxc_rsync_exec(args->src, args->dest); return lxc_rsync_exec(args->src, args->dest);
...@@ -121,8 +120,7 @@ int lxc_rsync(struct rsync_data *data) ...@@ -121,8 +120,7 @@ int lxc_rsync(struct rsync_data *data)
if (ret < 0) if (ret < 0)
return -1; return -1;
ret = lxc_setgroups(0, NULL); if (!lxc_setgroups(0, NULL))
if (ret < 0)
return -1; return -1;
src = lxc_storage_get_path(orig->dest, orig->type); src = lxc_storage_get_path(orig->dest, orig->type);
......
...@@ -1377,15 +1377,15 @@ int lxc_switch_uid_gid(uid_t uid, gid_t gid) ...@@ -1377,15 +1377,15 @@ int lxc_switch_uid_gid(uid_t uid, gid_t gid)
} }
/* Simple covenience function which enables uniform logging. */ /* Simple covenience function which enables uniform logging. */
int lxc_setgroups(int size, gid_t list[]) bool lxc_setgroups(int size, gid_t list[])
{ {
if (setgroups(size, list) < 0) { if (setgroups(size, list) < 0) {
SYSERROR("Failed to setgroups()."); SYSERROR("Failed to setgroups()");
return -errno; return false;
} }
NOTICE("Dropped additional groups."); NOTICE("Dropped additional groups");
return 0; return true;
} }
static int lxc_get_unused_loop_dev_legacy(char *loop_name) static int lxc_get_unused_loop_dev_legacy(char *loop_name)
......
...@@ -362,7 +362,7 @@ extern bool task_blocks_signal(pid_t pid, int signal); ...@@ -362,7 +362,7 @@ extern bool task_blocks_signal(pid_t pid, int signal);
* If LXC_INVALID_{G,U}ID is passed then the set{g,u}id() will not be called. * If LXC_INVALID_{G,U}ID is passed then the set{g,u}id() will not be called.
*/ */
extern int lxc_switch_uid_gid(uid_t uid, gid_t gid); extern int lxc_switch_uid_gid(uid_t uid, gid_t gid);
extern int lxc_setgroups(int size, gid_t list[]); extern bool lxc_setgroups(int size, gid_t list[]);
/* Find an unused loop device and associate it with source. */ /* Find an unused loop device and associate it with source. */
extern int lxc_prepare_loop_dev(const char *source, char *loop_dev, int flags); extern int lxc_prepare_loop_dev(const char *source, char *loop_dev, int flags);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment