[prev in list] [next in list] [prev in thread] [next in thread] 

List:       cgmanager-devel
Subject:    [cgmanager-devel] [PATCH RFC] add a configurable maximum cgroup depth
From:       stgraber () ubuntu ! com (=?iso-8859-1?Q?St=E9phane?= Graber)
Date:       2014-02-26 16:33:58
Message-ID: 20140226163358.GJ16361 () castiana
[Download RAW message or body]

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>



[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic