diff options
Diffstat (limited to 'kernel/cgroup.c')
-rw-r--r-- | kernel/cgroup.c | 27 |
1 files changed, 26 insertions, 1 deletions
diff --git a/kernel/cgroup.c b/kernel/cgroup.c index 0dfc7324c789..9fcdaa705b6c 100644 --- a/kernel/cgroup.c +++ b/kernel/cgroup.c | |||
@@ -2346,11 +2346,26 @@ static int cgroup_rename(struct kernfs_node *kn, struct kernfs_node *new_parent, | |||
2346 | return ret; | 2346 | return ret; |
2347 | } | 2347 | } |
2348 | 2348 | ||
2349 | /* set uid and gid of cgroup dirs and files to that of the creator */ | ||
2350 | static int cgroup_kn_set_ugid(struct kernfs_node *kn) | ||
2351 | { | ||
2352 | struct iattr iattr = { .ia_valid = ATTR_UID | ATTR_GID, | ||
2353 | .ia_uid = current_fsuid(), | ||
2354 | .ia_gid = current_fsgid(), }; | ||
2355 | |||
2356 | if (uid_eq(iattr.ia_uid, GLOBAL_ROOT_UID) && | ||
2357 | gid_eq(iattr.ia_gid, GLOBAL_ROOT_GID)) | ||
2358 | return 0; | ||
2359 | |||
2360 | return kernfs_setattr(kn, &iattr); | ||
2361 | } | ||
2362 | |||
2349 | static int cgroup_add_file(struct cgroup *cgrp, struct cftype *cft) | 2363 | static int cgroup_add_file(struct cgroup *cgrp, struct cftype *cft) |
2350 | { | 2364 | { |
2351 | char name[CGROUP_FILE_NAME_MAX]; | 2365 | char name[CGROUP_FILE_NAME_MAX]; |
2352 | struct kernfs_node *kn; | 2366 | struct kernfs_node *kn; |
2353 | struct lock_class_key *key = NULL; | 2367 | struct lock_class_key *key = NULL; |
2368 | int ret; | ||
2354 | 2369 | ||
2355 | #ifdef CONFIG_DEBUG_LOCK_ALLOC | 2370 | #ifdef CONFIG_DEBUG_LOCK_ALLOC |
2356 | key = &cft->lockdep_key; | 2371 | key = &cft->lockdep_key; |
@@ -2358,7 +2373,13 @@ static int cgroup_add_file(struct cgroup *cgrp, struct cftype *cft) | |||
2358 | kn = __kernfs_create_file(cgrp->kn, cgroup_file_name(cgrp, cft, name), | 2373 | kn = __kernfs_create_file(cgrp->kn, cgroup_file_name(cgrp, cft, name), |
2359 | cgroup_file_mode(cft), 0, cft->kf_ops, cft, | 2374 | cgroup_file_mode(cft), 0, cft->kf_ops, cft, |
2360 | NULL, false, key); | 2375 | NULL, false, key); |
2361 | return PTR_ERR_OR_ZERO(kn); | 2376 | if (IS_ERR(kn)) |
2377 | return PTR_ERR(kn); | ||
2378 | |||
2379 | ret = cgroup_kn_set_ugid(kn); | ||
2380 | if (ret) | ||
2381 | kernfs_remove(kn); | ||
2382 | return ret; | ||
2362 | } | 2383 | } |
2363 | 2384 | ||
2364 | /** | 2385 | /** |
@@ -3753,6 +3774,10 @@ static long cgroup_create(struct cgroup *parent, const char *name, | |||
3753 | */ | 3774 | */ |
3754 | idr_replace(&root->cgroup_idr, cgrp, cgrp->id); | 3775 | idr_replace(&root->cgroup_idr, cgrp, cgrp->id); |
3755 | 3776 | ||
3777 | err = cgroup_kn_set_ugid(kn); | ||
3778 | if (err) | ||
3779 | goto err_destroy; | ||
3780 | |||
3756 | err = cgroup_addrm_files(cgrp, cgroup_base_files, true); | 3781 | err = cgroup_addrm_files(cgrp, cgroup_base_files, true); |
3757 | if (err) | 3782 | if (err) |
3758 | goto err_destroy; | 3783 | goto err_destroy; |