mirror of
https://git.proxmox.com/git/mirror_lxc
synced 2025-07-27 09:48:32 +00:00
attach: handle id switching smarter
For setup, switch to the most privileged ids we can find. That is either nsuid 0 if a mapping has been established if not switch to the ids the init running in the container was started with. After setup, switch to the actual requested ids. Closes #2591. Signed-off-by: Christian Brauner <christian.brauner@ubuntu.com>
This commit is contained in:
parent
db2d1af171
commit
936efc72f6
@ -749,6 +749,8 @@ static int attach_child_main(struct attach_clone_payload *payload)
|
||||
int fd, lsm_fd, ret;
|
||||
uid_t new_uid;
|
||||
gid_t new_gid;
|
||||
uid_t ns_root_uid = 0;
|
||||
gid_t ns_root_gid = 0;
|
||||
lxc_attach_options_t* options = payload->options;
|
||||
struct lxc_proc_context_info* init_ctx = payload->init_ctx;
|
||||
bool needs_lsm = (options->namespaces & CLONE_NEWNS) &&
|
||||
@ -836,25 +838,23 @@ static int attach_child_main(struct attach_clone_payload *payload)
|
||||
goto on_error;
|
||||
}
|
||||
|
||||
/* Set {u,g}id. */
|
||||
new_uid = 0;
|
||||
new_gid = 0;
|
||||
if (options->namespaces & CLONE_NEWUSER) {
|
||||
/* Check whether nsuid 0 has a mapping. */
|
||||
ns_root_uid = get_ns_uid(0);
|
||||
|
||||
/* Ignore errors, we will fall back to root in that case (/proc was not
|
||||
* mounted etc.).
|
||||
*/
|
||||
if (options->namespaces & CLONE_NEWUSER)
|
||||
lxc_attach_get_init_uidgid(&new_uid, &new_gid);
|
||||
/* Check whether nsgid 0 has a mapping. */
|
||||
ns_root_gid = get_ns_gid(0);
|
||||
|
||||
if (options->uid != (uid_t)-1)
|
||||
new_uid = options->uid;
|
||||
/* If there's no mapping for nsuid 0 try to retrieve the nsuid
|
||||
* init was started with.
|
||||
*/
|
||||
if (ns_root_uid == LXC_INVALID_UID)
|
||||
lxc_attach_get_init_uidgid(&ns_root_uid, &ns_root_gid);
|
||||
|
||||
if (options->gid != (gid_t)-1)
|
||||
new_gid = options->gid;
|
||||
if (ns_root_uid == LXC_INVALID_UID)
|
||||
goto on_error;
|
||||
|
||||
/* Try to set the {u,g}id combination. */
|
||||
if (new_uid != 0 || new_gid != 0 || options->namespaces & CLONE_NEWUSER) {
|
||||
ret = lxc_switch_uid_gid(new_uid, new_gid);
|
||||
ret = lxc_switch_uid_gid(ns_root_uid, ns_root_gid);
|
||||
if (ret < 0)
|
||||
goto on_error;
|
||||
}
|
||||
@ -863,6 +863,17 @@ static int attach_child_main(struct attach_clone_payload *payload)
|
||||
if (ret < 0 && errno != EPERM)
|
||||
goto on_error;
|
||||
|
||||
/* Set {u,g}id. */
|
||||
if (options->uid != LXC_INVALID_UID)
|
||||
new_uid = options->uid;
|
||||
else
|
||||
new_uid = ns_root_uid;
|
||||
|
||||
if (options->gid != LXC_INVALID_GID)
|
||||
new_gid = options->gid;
|
||||
else
|
||||
new_gid = ns_root_gid;
|
||||
|
||||
if ((init_ctx->container && init_ctx->container->lxc_conf &&
|
||||
init_ctx->container->lxc_conf->no_new_privs) ||
|
||||
(options->attach_flags & LXC_ATTACH_NO_NEW_PRIVS)) {
|
||||
@ -952,6 +963,17 @@ static int attach_child_main(struct attach_clone_payload *payload)
|
||||
TRACE("Prepared terminal file descriptor %d", payload->terminal_slave_fd);
|
||||
}
|
||||
|
||||
/* Avoid unnecessary syscalls. */
|
||||
if (new_uid == ns_root_uid)
|
||||
new_uid = LXC_INVALID_UID;
|
||||
|
||||
if (new_gid == ns_root_gid)
|
||||
new_gid = LXC_INVALID_GID;
|
||||
|
||||
ret = lxc_switch_uid_gid(new_uid, new_gid);
|
||||
if (ret < 0)
|
||||
goto on_error;
|
||||
|
||||
/* We're done, so we can now do whatever the user intended us to do. */
|
||||
_exit(payload->exec_function(payload->exec_payload));
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user