[cgmanager-devel] [PATCH RFC] add a configurable maximum cgroup depth
Stéphane Graber
stgraber at ubuntu.com
Wed Feb 26 16:33:58 UTC 2014
On Wed, Feb 26, 2014 at 10:30:43AM -0600, Serge Hallyn wrote:
> Signed-off-by: Serge Hallyn <serge.hallyn at ubuntu.com>
Looks good to me. Let me know when you have a FFe.
Acked-by: Stéphane Graber <stgraber at ubuntu.com>
> ---
> cgmanager.c | 42 +++++++++++++++++++++++++++++-------------
> fs.c | 21 ++++++++++++++++++++-
> fs.h | 4 +++-
> 3 files changed, 52 insertions(+), 15 deletions(-)
>
> diff --git a/cgmanager.c b/cgmanager.c
> index b77220a..7c38c25 100644
> --- a/cgmanager.c
> +++ b/cgmanager.c
> @@ -19,6 +19,14 @@
>
> #include <frontend.h>
>
> +/*
> + * Maximum depth of directories we allow in Create
> + * Default is 16. Figure 4 directories per level of container
> + * nesting (/user/1000.user/c2.session/c1), that lets us nest
> + * 4 containers deep.
> + * */
> +static int maxdepth = 16;
> +
> /* GetPidCgroup */
> int get_pid_cgroup_main(void *parent, const char *controller,struct ucred p,
> struct ucred r, struct ucred v, char **output)
> @@ -26,13 +34,13 @@ int get_pid_cgroup_main(void *parent, const char *controller,struct ucred p,
> char rcgpath[MAXPATHLEN], vcgpath[MAXPATHLEN];
>
> // Get r's current cgroup in rcgpath
> - if (!compute_pid_cgroup(r.pid, controller, "", rcgpath)) {
> + if (!compute_pid_cgroup(r.pid, controller, "", rcgpath, NULL)) {
> nih_error("Could not determine the requestor cgroup");
> return -1;
> }
>
> // Get v's cgroup in vcgpath
> - if (!compute_pid_cgroup(v.pid, controller, "", vcgpath)) {
> + if (!compute_pid_cgroup(v.pid, controller, "", vcgpath, NULL)) {
> nih_error("Could not determine the victim cgroup");
> return -1;
> }
> @@ -57,7 +65,7 @@ static bool victim_under_proxy_cgroup(char *rcgpath, pid_t v,
> {
> char vcgpath[MAXPATHLEN];
>
> - if (!compute_pid_cgroup(v, controller, "", vcgpath)) {
> + if (!compute_pid_cgroup(v, controller, "", vcgpath, NULL)) {
> nih_error("Could not determine the victim's cgroup");
> return false;
> }
> @@ -87,7 +95,7 @@ int do_move_pid_main(const char *controller, const char *cgroup, struct ucred p,
> // Get r's current cgroup in rcgpath
> if (escape)
> query = p.pid;
> - if (!compute_pid_cgroup(query, controller, "", rcgpath)) {
> + if (!compute_pid_cgroup(query, controller, "", rcgpath, NULL)) {
> nih_error("Could not determine the requested cgroup");
> return -1;
> }
> @@ -163,7 +171,7 @@ int move_pid_abs_main(const char *controller, const char *cgroup, struct ucred p
> int create_main(const char *controller, const char *cgroup, struct ucred p,
> struct ucred r, int32_t *existed)
> {
> - int ret;
> + int ret, depth;
> char rcgpath[MAXPATHLEN], path[MAXPATHLEN], dirpath[MAXPATHLEN];
> nih_local char *copy = NULL;
> size_t cgroup_len;
> @@ -179,11 +187,17 @@ int create_main(const char *controller, const char *cgroup, struct ucred p,
> }
>
> // Get r's current cgroup in rcgpath
> - if (!compute_pid_cgroup(r.pid, controller, "", rcgpath)) {
> + if (!compute_pid_cgroup(r.pid, controller, "", rcgpath, &depth)) {
> nih_error("Could not determine the requested cgroup");
> return -1;
> }
>
> + depth += get_path_depth(cgroup);
> + if (depth > maxdepth) {
> + nih_error("Cgroup too deep: %s/%s", rcgpath, cgroup);
> + return -1;
> + }
> +
> cgroup_len = strlen(cgroup);
>
> if (strlen(rcgpath) + cgroup_len > MAXPATHLEN) {
> @@ -200,7 +214,7 @@ int create_main(const char *controller, const char *cgroup, struct ucred p,
> oldp2 = *p2;
> *p2 = '\0';
> if (strcmp(p1, "..") == 0) {
> - nih_error("Out of memory copying cgroup name");
> + nih_error("Invalid cgroup path at create: %s", p1);
> return -1;
> }
> strncat(path, "/", MAXPATHLEN-1);
> @@ -272,7 +286,7 @@ int chown_main(const char *controller, const char *cgroup, struct ucred p,
> }
>
> // Get r's current cgroup in rcgpath
> - if (!compute_pid_cgroup(r.pid, controller, "", rcgpath)) {
> + if (!compute_pid_cgroup(r.pid, controller, "", rcgpath, NULL)) {
> nih_error("Could not determine the requested cgroup");
> return -1;
> }
> @@ -327,7 +341,7 @@ int chmod_main(const char *controller, const char *cgroup, const char *file,
> }
>
> // Get r's current cgroup in rcgpath
> - if (!compute_pid_cgroup(r.pid, controller, "", rcgpath)) {
> + if (!compute_pid_cgroup(r.pid, controller, "", rcgpath, NULL)) {
> nih_error("Could not determine the requested cgroup");
> return -1;
> }
> @@ -372,7 +386,7 @@ int get_value_main(void *parent, const char *controller, const char *cgroup,
> return -1;
> }
>
> - if (!compute_pid_cgroup(r.pid, controller, cgroup, path)) {
> + if (!compute_pid_cgroup(r.pid, controller, cgroup, path, NULL)) {
> nih_error("Could not determine the requested cgroup");
> return -1;
> }
> @@ -421,7 +435,7 @@ int set_value_main(const char *controller, const char *cgroup,
> return -1;
> }
>
> - if (!compute_pid_cgroup(r.pid, controller, cgroup, path)) {
> + if (!compute_pid_cgroup(r.pid, controller, cgroup, path, NULL)) {
> nih_error("Could not determine the requested cgroup");
> return -1;
> }
> @@ -545,7 +559,7 @@ int remove_main(const char *controller, const char *cgroup, struct ucred p,
> }
>
> // Get r's current cgroup in rcgpath
> - if (!compute_pid_cgroup(r.pid, controller, "", rcgpath)) {
> + if (!compute_pid_cgroup(r.pid, controller, "", rcgpath, NULL)) {
> nih_error("Could not determine the requested cgroup");
> return -1;
> }
> @@ -604,7 +618,7 @@ int get_tasks_main(void *parent, const char *controller, const char *cgroup,
> return -1;
> }
>
> - if (!compute_pid_cgroup(r.pid, controller, cgroup, path)) {
> + if (!compute_pid_cgroup(r.pid, controller, cgroup, path, NULL)) {
> nih_error("Could not determine the requested cgroup");
> return -1;
> }
> @@ -643,6 +657,8 @@ my_setter (NihOption *option, const char *arg)
> * Command-line options accepted by this program.
> **/
> static NihOption options[] = {
> + { 0, "max-depth", N_("Maximum cgroup depth"),
> + NULL, NULL, &maxdepth, NULL },
> { 'm', "mount", N_("Extra subsystems to mount"),
> NULL, "subsystems to mount", NULL, my_setter },
> { 0, "daemon", N_("Detach and run in the background"),
> diff --git a/fs.c b/fs.c
> index b6dd4fd..32a06a5 100644
> --- a/fs.c
> +++ b/fs.c
> @@ -455,6 +455,21 @@ const char *get_controller_path(const char *controller)
> return NULL;
> }
>
> +int get_path_depth(const char *p)
> +{
> + int depth = 0;
> +
> + while (*p) {
> + while (*p && *p == '/')
> + p++;
> + if (*p)
> + depth++;
> + while (*p && *p != '/')
> + p++;
> + }
> + return depth;
> +}
> +
> /*
> * Calculate a full path to the cgroup being requested.
> * @pid is the process making the request
> @@ -464,7 +479,8 @@ const char *get_controller_path(const char *controller)
> * "a/b", then we concatenate "/cgroup/for/pid" with "a/b"
> * If @cgroup is "/a/b", then we use "/a/b"
> */
> -bool compute_pid_cgroup(pid_t pid, const char *controller, const char *cgroup, char *path)
> +bool compute_pid_cgroup(pid_t pid, const char *controller, const char *cgroup,
> + char *path, int *depth)
> {
> int ret;
> char requestor_cgpath[MAXPATHLEN], fullpath[MAXPATHLEN], *cg;
> @@ -479,6 +495,9 @@ bool compute_pid_cgroup(pid_t pid, const char *controller, const char *cgroup, c
> } else
> abspath = true;
>
> + if (depth)
> + *depth = get_path_depth(cg);
> +
> if ((cont_path = get_controller_path(controller)) == NULL) {
> nih_error("Controller %s not mounted", controller);
> return false;
> diff --git a/fs.h b/fs.h
> index b5d3868..6067e23 100644
> --- a/fs.h
> +++ b/fs.h
> @@ -25,7 +25,9 @@
> */
>
> int setup_cgroup_mounts(char *extra_mounts);
> -bool compute_pid_cgroup(pid_t pid, const char *controller, const char *cgroup, char *path);
> +bool compute_pid_cgroup(pid_t pid, const char *controller, const char *cgroup,
> + char *path, int *depth);
> +int get_path_depth(const char *path);
> bool may_access(pid_t pid, uid_t uid, gid_t gid, const char *path, int mode);
> void get_pid_creds(pid_t pid, uid_t *uid, gid_t *gid);
> char *file_read_string(void *parent, const char *path);
> --
> 1.9.0
>
> _______________________________________________
> cgmanager-devel mailing list
> cgmanager-devel at lists.linuxcontainers.org
> http://lists.linuxcontainers.org/listinfo/cgmanager-devel
--
Stéphane Graber
Ubuntu developer
http://www.ubuntu.com
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <http://lists.linuxcontainers.org/pipermail/cgmanager-devel/attachments/20140226/8170cfe6/attachment.pgp>
More information about the cgmanager-devel
mailing list