Commit dc5ed406 authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'for-3.15-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/tj/cgroup

Pull cgroup fixes from Tejun Heo:
 "Two patches to fix fallouts from the kernfs conversion:

  Li's patch to stop leaking cgroup_root refs across multiple mounts and
  the other fixes the 90s hang during shutdown caused by always using
  root's uid/gid for new cgroup dirs and files."

* 'for-3.15-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/tj/cgroup:
  cgroup: newly created dirs and files should be owned by the creator
  cgroup: fix top cgroup refcnt leak
parents 467a9e16 49957f8e
...@@ -1487,6 +1487,7 @@ static struct dentry *cgroup_mount(struct file_system_type *fs_type, ...@@ -1487,6 +1487,7 @@ static struct dentry *cgroup_mount(struct file_system_type *fs_type,
struct cgroup_sb_opts opts; struct cgroup_sb_opts opts;
struct dentry *dentry; struct dentry *dentry;
int ret; int ret;
bool new_sb;
/* /*
* The first time anyone tries to mount a cgroup, enable the list * The first time anyone tries to mount a cgroup, enable the list
...@@ -1603,8 +1604,8 @@ static struct dentry *cgroup_mount(struct file_system_type *fs_type, ...@@ -1603,8 +1604,8 @@ static struct dentry *cgroup_mount(struct file_system_type *fs_type,
if (ret) if (ret)
return ERR_PTR(ret); return ERR_PTR(ret);
dentry = kernfs_mount(fs_type, flags, root->kf_root, NULL); dentry = kernfs_mount(fs_type, flags, root->kf_root, &new_sb);
if (IS_ERR(dentry)) if (IS_ERR(dentry) || !new_sb)
cgroup_put(&root->cgrp); cgroup_put(&root->cgrp);
return dentry; return dentry;
} }
...@@ -2345,11 +2346,26 @@ static int cgroup_rename(struct kernfs_node *kn, struct kernfs_node *new_parent, ...@@ -2345,11 +2346,26 @@ static int cgroup_rename(struct kernfs_node *kn, struct kernfs_node *new_parent,
return ret; return ret;
} }
/* set uid and gid of cgroup dirs and files to that of the creator */
static int cgroup_kn_set_ugid(struct kernfs_node *kn)
{
struct iattr iattr = { .ia_valid = ATTR_UID | ATTR_GID,
.ia_uid = current_fsuid(),
.ia_gid = current_fsgid(), };
if (uid_eq(iattr.ia_uid, GLOBAL_ROOT_UID) &&
gid_eq(iattr.ia_gid, GLOBAL_ROOT_GID))
return 0;
return kernfs_setattr(kn, &iattr);
}
static int cgroup_add_file(struct cgroup *cgrp, struct cftype *cft) static int cgroup_add_file(struct cgroup *cgrp, struct cftype *cft)
{ {
char name[CGROUP_FILE_NAME_MAX]; char name[CGROUP_FILE_NAME_MAX];
struct kernfs_node *kn; struct kernfs_node *kn;
struct lock_class_key *key = NULL; struct lock_class_key *key = NULL;
int ret;
#ifdef CONFIG_DEBUG_LOCK_ALLOC #ifdef CONFIG_DEBUG_LOCK_ALLOC
key = &cft->lockdep_key; key = &cft->lockdep_key;
...@@ -2357,7 +2373,13 @@ static int cgroup_add_file(struct cgroup *cgrp, struct cftype *cft) ...@@ -2357,7 +2373,13 @@ static int cgroup_add_file(struct cgroup *cgrp, struct cftype *cft)
kn = __kernfs_create_file(cgrp->kn, cgroup_file_name(cgrp, cft, name), kn = __kernfs_create_file(cgrp->kn, cgroup_file_name(cgrp, cft, name),
cgroup_file_mode(cft), 0, cft->kf_ops, cft, cgroup_file_mode(cft), 0, cft->kf_ops, cft,
NULL, false, key); NULL, false, key);
return PTR_ERR_OR_ZERO(kn); if (IS_ERR(kn))
return PTR_ERR(kn);
ret = cgroup_kn_set_ugid(kn);
if (ret)
kernfs_remove(kn);
return ret;
} }
/** /**
...@@ -3752,6 +3774,10 @@ static long cgroup_create(struct cgroup *parent, const char *name, ...@@ -3752,6 +3774,10 @@ static long cgroup_create(struct cgroup *parent, const char *name,
*/ */
idr_replace(&root->cgroup_idr, cgrp, cgrp->id); idr_replace(&root->cgroup_idr, cgrp, cgrp->id);
err = cgroup_kn_set_ugid(kn);
if (err)
goto err_destroy;
err = cgroup_addrm_files(cgrp, cgroup_base_files, true); err = cgroup_addrm_files(cgrp, cgroup_base_files, true);
if (err) if (err)
goto err_destroy; goto err_destroy;
......
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