Unverified Commit ea0f0c84 by Serge Hallyn Committed by GitHub

Merge pull request #2606 from brauner/2018-09-09/cgroup_escape

cgroups: scoping for cgroup v2
parents e52f28af d28779d9
...@@ -483,7 +483,7 @@ AC_ARG_WITH([cgroup-pattern], ...@@ -483,7 +483,7 @@ AC_ARG_WITH([cgroup-pattern],
[AC_HELP_STRING( [AC_HELP_STRING(
[--with-cgroup-pattern=pattern], [--with-cgroup-pattern=pattern],
[pattern for container cgroups] [pattern for container cgroups]
)], [], [with_cgroup_pattern=['lxc/%n']]) )], [], [with_cgroup_pattern=['lxc.payload/%n']])
# The path for the apparmor_parser's cache for generated apparmor profiles # The path for the apparmor_parser's cache for generated apparmor profiles
AC_ARG_WITH([apparmor-cache-dir], AC_ARG_WITH([apparmor-cache-dir],
......
...@@ -22,6 +22,7 @@ ...@@ -22,6 +22,7 @@
*/ */
#include <stdlib.h> #include <stdlib.h>
#include <string.h>
#include <unistd.h> #include <unistd.h>
#include <sys/types.h> #include <sys/types.h>
...@@ -75,6 +76,7 @@ void cgroup_exit(struct cgroup_ops *ops) ...@@ -75,6 +76,7 @@ void cgroup_exit(struct cgroup_ops *ops)
free(ops->cgroup_pattern); free(ops->cgroup_pattern);
free(ops->container_cgroup); free(ops->container_cgroup);
free(ops->monitor_pattern);
for (it = ops->hierarchies; it && *it; it++) { for (it = ops->hierarchies; it && *it; it++) {
char **ctrlr; char **ctrlr;
...@@ -84,8 +86,9 @@ void cgroup_exit(struct cgroup_ops *ops) ...@@ -84,8 +86,9 @@ void cgroup_exit(struct cgroup_ops *ops)
free((*it)->controllers); free((*it)->controllers);
free((*it)->mountpoint); free((*it)->mountpoint);
free((*it)->base_cgroup); free((*it)->container_base_path);
free((*it)->fullcgpath); free((*it)->container_full_path);
free((*it)->monitor_full_path);
free(*it); free(*it);
} }
free(ops->hierarchies); free(ops->hierarchies);
......
...@@ -57,14 +57,17 @@ typedef enum { ...@@ -57,14 +57,17 @@ typedef enum {
* depending on whether this is a hybrid cgroup layout (mix of legacy and * depending on whether this is a hybrid cgroup layout (mix of legacy and
* unified hierarchies) or a pure unified cgroup layout. * unified hierarchies) or a pure unified cgroup layout.
* *
* @base_cgroup * @container_base_path
* - The cgroup under which the container cgroup path * - The cgroup under which the container cgroup path
* is created. This will be either the caller's cgroup (if not root), or * is created. This will be either the caller's cgroup (if not root), or
* init's cgroup (if root). * init's cgroup (if root).
* *
* @fullcgpath * @container_full_path
* - The full path to the containers cgroup. * - The full path to the containers cgroup.
* *
* @monitor_full_path
* - The full path to the monitor's cgroup.
*
* @version * @version
* - legacy hierarchy * - legacy hierarchy
* If the hierarchy is a legacy hierarchy this will be set to * If the hierarchy is a legacy hierarchy this will be set to
...@@ -76,8 +79,9 @@ typedef enum { ...@@ -76,8 +79,9 @@ typedef enum {
struct hierarchy { struct hierarchy {
char **controllers; char **controllers;
char *mountpoint; char *mountpoint;
char *base_cgroup; char *container_base_path;
char *fullcgpath; char *container_full_path;
char *monitor_full_path;
int version; int version;
}; };
...@@ -92,6 +96,7 @@ struct cgroup_ops { ...@@ -92,6 +96,7 @@ struct cgroup_ops {
char **cgroup_use; char **cgroup_use;
char *cgroup_pattern; char *cgroup_pattern;
char *container_cgroup; char *container_cgroup;
char *monitor_pattern;
/* @hierarchies /* @hierarchies
* - A NULL-terminated array of struct hierarchy, one per legacy * - A NULL-terminated array of struct hierarchy, one per legacy
...@@ -124,8 +129,10 @@ struct cgroup_ops { ...@@ -124,8 +129,10 @@ struct cgroup_ops {
bool (*data_init)(struct cgroup_ops *ops); bool (*data_init)(struct cgroup_ops *ops);
void (*destroy)(struct cgroup_ops *ops, struct lxc_handler *handler); void (*destroy)(struct cgroup_ops *ops, struct lxc_handler *handler);
bool (*create)(struct cgroup_ops *ops, struct lxc_handler *handler); bool (*monitor_create)(struct cgroup_ops *ops, struct lxc_handler *handler);
bool (*enter)(struct cgroup_ops *ops, pid_t pid); bool (*monitor_enter)(struct cgroup_ops *ops, pid_t pid);
bool (*payload_create)(struct cgroup_ops *ops, struct lxc_handler *handler);
bool (*payload_enter)(struct cgroup_ops *ops, pid_t pid);
const char *(*get_cgroup)(struct cgroup_ops *ops, const char *controller); const char *(*get_cgroup)(struct cgroup_ops *ops, const char *controller);
bool (*escape)(const struct cgroup_ops *ops, struct lxc_conf *conf); bool (*escape)(const struct cgroup_ops *ops, struct lxc_conf *conf);
int (*num_hierarchies)(struct cgroup_ops *ops); int (*num_hierarchies)(struct cgroup_ops *ops);
......
...@@ -972,7 +972,7 @@ static void do_restore(struct lxc_container *c, int status_pipe, struct migrate_ ...@@ -972,7 +972,7 @@ static void do_restore(struct lxc_container *c, int status_pipe, struct migrate_
goto out_fini_handler; goto out_fini_handler;
handler->cgroup_ops = cgroup_ops; handler->cgroup_ops = cgroup_ops;
if (!cgroup_ops->create(cgroup_ops, handler)) { if (!cgroup_ops->payload_create(cgroup_ops, handler)) {
ERROR("failed creating groups"); ERROR("failed creating groups");
goto out_fini_handler; goto out_fini_handler;
} }
......
...@@ -101,7 +101,7 @@ const char *lxc_global_config_value(const char *option_name) ...@@ -101,7 +101,7 @@ const char *lxc_global_config_value(const char *option_name)
sprintf(user_config_path, "%s/.config/lxc/lxc.conf", user_home); sprintf(user_config_path, "%s/.config/lxc/lxc.conf", user_home);
sprintf(user_default_config_path, "%s/.config/lxc/default.conf", user_home); sprintf(user_default_config_path, "%s/.config/lxc/default.conf", user_home);
sprintf(user_lxc_path, "%s/.local/share/lxc/", user_home); sprintf(user_lxc_path, "%s/.local/share/lxc/", user_home);
user_cgroup_pattern = strdup("lxc/%n"); user_cgroup_pattern = strdup("lxc.payload/%n");
} }
else { else {
user_config_path = strdup(LXC_GLOBAL_CONF); user_config_path = strdup(LXC_GLOBAL_CONF);
......
...@@ -1678,7 +1678,7 @@ static int lxc_spawn(struct lxc_handler *handler) ...@@ -1678,7 +1678,7 @@ static int lxc_spawn(struct lxc_handler *handler)
} }
} }
if (!cgroup_ops->create(cgroup_ops, handler)) { if (!cgroup_ops->payload_create(cgroup_ops, handler)) {
ERROR("Failed creating cgroups"); ERROR("Failed creating cgroups");
goto out_delete_net; goto out_delete_net;
} }
...@@ -1772,7 +1772,7 @@ static int lxc_spawn(struct lxc_handler *handler) ...@@ -1772,7 +1772,7 @@ static int lxc_spawn(struct lxc_handler *handler)
goto out_delete_net; goto out_delete_net;
} }
if (!cgroup_ops->enter(cgroup_ops, handler->pid)) if (!cgroup_ops->payload_enter(cgroup_ops, handler->pid))
goto out_delete_net; goto out_delete_net;
if (!cgroup_ops->chown(cgroup_ops, handler->conf)) if (!cgroup_ops->chown(cgroup_ops, handler->conf))
...@@ -1949,6 +1949,7 @@ int __lxc_start(const char *name, struct lxc_handler *handler, ...@@ -1949,6 +1949,7 @@ int __lxc_start(const char *name, struct lxc_handler *handler,
{ {
int ret, status; int ret, status;
struct lxc_conf *conf = handler->conf; struct lxc_conf *conf = handler->conf;
struct cgroup_ops *cgroup_ops;
ret = lxc_init(name, handler); ret = lxc_init(name, handler);
if (ret < 0) { if (ret < 0) {
...@@ -1958,12 +1959,23 @@ int __lxc_start(const char *name, struct lxc_handler *handler, ...@@ -1958,12 +1959,23 @@ int __lxc_start(const char *name, struct lxc_handler *handler,
handler->ops = ops; handler->ops = ops;
handler->data = data; handler->data = data;
handler->daemonize = daemonize; handler->daemonize = daemonize;
cgroup_ops = handler->cgroup_ops;
if (!attach_block_device(handler->conf)) { if (!attach_block_device(handler->conf)) {
ERROR("Failed to attach block device"); ERROR("Failed to attach block device");
goto out_fini_nonet; goto out_fini_nonet;
} }
if (!cgroup_ops->monitor_create(cgroup_ops, handler)) {
ERROR("Failed to create monitor cgroup");
goto out_fini_nonet;
}
if (!cgroup_ops->monitor_enter(cgroup_ops, lxc_raw_getpid())) {
ERROR("Failed to enter monitor cgroup");
goto out_fini_nonet;
}
if (geteuid() == 0 && !lxc_list_empty(&conf->id_map)) { if (geteuid() == 0 && !lxc_list_empty(&conf->id_map)) {
/* If the backing store is a device, mount it here and now. */ /* If the backing store is a device, mount it here and now. */
if (rootfs_is_blockdev(conf)) { if (rootfs_is_blockdev(conf)) {
......
...@@ -59,7 +59,7 @@ static int test_running_container(const char *lxcpath, ...@@ -59,7 +59,7 @@ static int test_running_container(const char *lxcpath,
char value[NAME_MAX], value_save[NAME_MAX]; char value[NAME_MAX], value_save[NAME_MAX];
struct cgroup_ops *cgroup_ops; struct cgroup_ops *cgroup_ops;
sprintf(relpath, "%s/%s", group ? group : "lxc", name); sprintf(relpath, "%s/%s", group ? group : "lxc.payload", name);
if ((c = lxc_container_new(name, lxcpath)) == NULL) { if ((c = lxc_container_new(name, lxcpath)) == NULL) {
TSTERR("container %s couldn't instantiate", name); TSTERR("container %s couldn't instantiate", name);
......
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