attach: use PR_SET_NO_NEW_PRIVS

- When we detect that the container, we want to attach to, has been stared with PR_SET_NO_NEW_PRIVS we attach with PR_SET_NO_NEW_PRIVS as well. (We might relax this restriction later but let's be strict for now.) - When LXC_ATTACH_NO_NEW_PRIVS is set in the flags passed to lxc_attach()/attach_child_main() then we set PR_SET_NO_NEW_PRIVS irrespective of whether the container was started with PR_SET_NO_NEW_PRIVS or not. - Set no_new_privs before lsm and seccomp. We probably don't want attach() to be able to change the lsm or seccomp policy if the container was started with PR_SET_NO_NEW_PRIVS enabled. Signed-off-by: 's avatarChristian Brauner <christian.brauner@canonical.com>
parent ff07d7bb
......@@ -668,7 +668,7 @@ static bool fetch_seccomp(struct lxc_proc_context_info *i,
c = i->container;
/* Initialize an empty lxc_conf */
/* Remove current setting. */
if (!c->set_config_item(c, "lxc.seccomp", "")) {
return false;
}
......@@ -692,6 +692,37 @@ static bool fetch_seccomp(struct lxc_proc_context_info *i,
return false;
}
INFO("Retrieved seccomp policy.");
return true;
}
static bool no_new_privs(struct lxc_proc_context_info *ctx,
lxc_attach_options_t *options)
{
struct lxc_container *c;
char *val;
c = ctx->container;
/* Remove current setting. */
if (!c->set_config_item(c, "lxc.no_new_privs", "")) {
return false;
}
/* Retrieve currently active setting. */
val = c->get_running_config_item(c, "lxc.no_new_privs");
if (!val) {
INFO("Failed to get running config item for lxc.no_new_privs.");
return false;
}
/* Set currently active setting. */
if (!c->set_config_item(c, "lxc.no_new_privs", val)) {
free(val);
return false;
}
free(val);
return true;
}
......@@ -748,6 +779,9 @@ int lxc_attach(const char* name, const char* lxcpath, lxc_attach_exec_t exec_fun
if (!fetch_seccomp(init_ctx, options))
WARN("Failed to get seccomp policy");
if (!no_new_privs(init_ctx, options))
WARN("Could not determine whether PR_SET_NO_NEW_PRIVS is set.");
cwd = getcwd(NULL, 0);
/* determine which namespaces the container was created with
......@@ -1147,6 +1181,19 @@ static int attach_child_main(void* data)
shutdown(ipc_socket, SHUT_RDWR);
close(ipc_socket);
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)) {
if (prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0) < 0) {
SYSERROR("PR_SET_NO_NEW_PRIVS could not be set. "
"Process can use execve() gainable "
"privileges.");
rexit(-1);
}
INFO("PR_SET_NO_NEW_PRIVS is set. Process cannot use execve() "
"gainable privileges.");
}
/* set new apparmor profile/selinux context */
if ((options->namespaces & CLONE_NEWNS) && (options->attach_flags & LXC_ATTACH_LSM) && init_ctx->lsm_label) {
int on_exec;
......@@ -1162,7 +1209,6 @@ static int attach_child_main(void* data)
ERROR("Loading seccomp policy");
rexit(-1);
}
lxc_proc_put_context_info(init_ctx);
/* The following is done after the communication socket is
......
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