Skip to content
This repository has been archived by the owner on Apr 15, 2020. It is now read-only.

Commit

Permalink
Fix subdirectory check
Browse files Browse the repository at this point in the history
Commit 6a30adc was not quite complete.  If the task is in
/xxx then it may act on /xxx or /xxx/a, but not /xxx2.  This commit
fixes the check to disallow /xxx2.  It also commonizes the check,
cleaning up the code a bit.

Signed-off-by: Serge Hallyn <serge.hallyn@ubuntu.com>
  • Loading branch information
hallyn committed Feb 12, 2015
1 parent a08d1c0 commit 9c41660
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 55 deletions.
65 changes: 10 additions & 55 deletions cgmanager.c
Expand Up @@ -557,20 +557,13 @@ int chmod_main(const char *controller, const char *cgroup, const char *file,
int get_value_main(void *parent, const char *controller, const char *cgroup,
const char *key, struct ucred p, struct ucred r, char **value)
{
char pcgpath[MAXPATHLEN], path[MAXPATHLEN];
char path[MAXPATHLEN];

if (!sane_cgroup(cgroup)) {
nih_error("%s: unsafe cgroup", __func__);
return -1;
}

// Get p's current cgroup in pcgpath
if (!compute_pid_cgroup(p.pid, controller, "", pcgpath, NULL)) {
nih_error("%s: Could not determine the proxy's cgroup for %s",
__func__, controller);
return -1;
}

if (!compute_pid_cgroup(r.pid, controller, cgroup, path, NULL)) {
nih_error("%s: Could not determine the requested cgroup (%s:%s)",
__func__, controller, cgroup);
Expand All @@ -583,9 +576,7 @@ int get_value_main(void *parent, const char *controller, const char *cgroup,
return -1;
}

// Make sure target cgroup is under proxy's
int plen = strlen(pcgpath);
if (strncmp(pcgpath, path, plen) != 0) {
if (!path_is_under_taskcg(p.pid, controller, path)) {
nih_error("%s: target cgroup is not below r (%d)'s", __func__,
r.pid);
return -1;
Expand Down Expand Up @@ -622,29 +613,20 @@ int set_value_main(const char *controller, const char *cgroup,
struct ucred r)

{
char pcgpath[MAXPATHLEN], path[MAXPATHLEN];
char path[MAXPATHLEN];

if (!sane_cgroup(cgroup)) {
nih_error("%s: unsafe cgroup", __func__);
return -1;
}

// Get p's current cgroup in pcgpath
if (!compute_pid_cgroup(p.pid, controller, "", pcgpath, NULL)) {
nih_error("%s: Could not determine the proxy's cgroup for %s",
__func__, controller);
return -1;
}

if (!compute_pid_cgroup(r.pid, controller, cgroup, path, NULL)) {
nih_error("%s: Could not determine the requested cgroup (%s:%s)",
__func__, controller, cgroup);
return -1;
}

// Make sure target cgroup is under proxy's
int plen = strlen(pcgpath);
if (strncmp(pcgpath, path, plen) != 0) {
if (!path_is_under_taskcg(p.pid, controller, path)) {
nih_error("%s: target cgroup is not below r (%d)'s", __func__,
r.pid);
return -1;
Expand Down Expand Up @@ -852,7 +834,7 @@ int remove_main(const char *controller, const char *cgroup, struct ucred p,
int get_tasks_main(void *parent, const char *controller, const char *cgroup,
struct ucred p, struct ucred r, int32_t **pids)
{
char pcgpath[MAXPATHLEN], path[MAXPATHLEN];
char path[MAXPATHLEN];
const char *key = "tasks";
int alloced_pids = 0, nrpids = 0;

Expand All @@ -861,22 +843,13 @@ int get_tasks_main(void *parent, const char *controller, const char *cgroup,
return -1;
}

// Get p's current cgroup in pcgpath
if (!compute_pid_cgroup(p.pid, controller, "", pcgpath, NULL)) {
nih_error("%s: Could not determine the proxy's cgroup for %s",
__func__, controller);
return -1;
}

if (!compute_pid_cgroup(r.pid, controller, cgroup, path, NULL)) {
nih_error("%s: Could not determine the requested cgroup (%s:%s)",
__func__, controller, cgroup);
return -1;
}

// Make sure target cgroup is under proxy's
int plen = strlen(pcgpath);
if (strncmp(pcgpath, path, plen) != 0) {
if (!path_is_under_taskcg(p.pid, controller, path)) {
nih_error("%s: target cgroup is not below r (%d)'s", __func__,
r.pid);
return -1;
Expand Down Expand Up @@ -951,30 +924,21 @@ int collect_tasks(void *parent, const char *controller, const char *cgroup,
struct ucred p, struct ucred r, int32_t **pids,
int *alloced_pids, int *nrpids)
{
char pcgpath[MAXPATHLEN], path[MAXPATHLEN];
char path[MAXPATHLEN];
nih_local char *rpath = NULL;

if (!sane_cgroup(cgroup)) {
nih_error("%s: unsafe cgroup", __func__);
return -1;
}

// Get p's current cgroup in pcgpath
if (!compute_pid_cgroup(p.pid, controller, "", pcgpath, NULL)) {
nih_error("%s: Could not determine the proxy's cgroup for %s",
__func__, controller);
return -1;
}

if (!compute_pid_cgroup(r.pid, controller, cgroup, path, NULL)) {
nih_error("%s: Could not determine the requested cgroup (%s:%s)",
__func__, controller, cgroup);
return -2;
}

// Make sure target cgroup is under proxy's
int plen = strlen(pcgpath);
if (strncmp(pcgpath, path, plen) != 0) {
if (!path_is_under_taskcg(p.pid, controller, path)) {
nih_error("%s: target cgroup is not below r (%d)'s", __func__,
r.pid);
return -1;
Expand Down Expand Up @@ -1044,30 +1008,21 @@ int get_tasks_recursive_main(void *parent, const char *controller,
int list_children_main(void *parent, const char *controller, const char *cgroup,
struct ucred p, struct ucred r, char ***output)
{
char pcgpath[MAXPATHLEN], path[MAXPATHLEN];
char path[MAXPATHLEN];

*output = NULL;
if (!sane_cgroup(cgroup)) {
nih_error("%s: unsafe cgroup", __func__);
return -1;
}

// Get p's current cgroup in pcgpath
if (!compute_pid_cgroup(p.pid, controller, "", pcgpath, NULL)) {
nih_error("%s: Could not determine the proxy's cgroup for %s",
__func__, controller);
return -1;
}

if (!compute_pid_cgroup(r.pid, controller, cgroup, path, NULL)) {
nih_error("%s: Could not determine the requested cgroup (%s:%s)",
__func__, controller, cgroup);
return -1;
}

// Make sure target cgroup is under proxy's
int plen = strlen(pcgpath);
if (strncmp(pcgpath, path, plen) != 0) {
if (!path_is_under_taskcg(p.pid, controller, path)) {
nih_error("%s: target cgroup is not below r (%d)'s", __func__,
r.pid);
return -1;
Expand Down
31 changes: 31 additions & 0 deletions fs.c
Expand Up @@ -1899,3 +1899,34 @@ bool was_premounted(const char *controller)
return false;
return all_mounts[i].premounted;
}

/*
* Check that (absolute) @path is under @pid's cgroup for @contr
*/
bool path_is_under_taskcg(pid_t pid, const char *contr,const char *path)
{
char pcgpath[MAXPATHLEN];
size_t plen;

// Get p's current cgroup in pcgpath
if (!compute_pid_cgroup(pid, contr, "", pcgpath, NULL)) {
nih_error("%s: Could not determine the proxy's cgroup for %s",
__func__, contr);
return false;
}
plen = strlen(pcgpath);
// path must start with pcgpath
if (strncmp(pcgpath, path, plen) != 0)
return false;
// If path is equal to pcgpath then that's ok
if (plen == strlen(path))
return true;
/*
* if path is longer than pcpgath, then it must be a subdirectory
* of pcpgpath. I.e. if pcgpath is /xxx then /xxx/a is ok, /xxx2 is
* not.
*/
if (path[plen] == '/')
return true;
return false;
}
1 change: 1 addition & 0 deletions fs.h
Expand Up @@ -57,3 +57,4 @@ bool was_premounted(const char *controller);
void do_prune_comounts(char *controllers);
void do_list_controllers(void *parent, char ***output);
void convert_directory_contents(struct keys_return_type **keys, struct ucred r);
bool path_is_under_taskcg(pid_t pid, const char *contr,const char *path);

0 comments on commit 9c41660

Please sign in to comment.