diff options
| -rw-r--r-- | Documentation/cgroup-v2.txt | 12 | ||||
| -rw-r--r-- | kernel/cgroup/cgroup.c | 27 |
2 files changed, 19 insertions, 20 deletions
diff --git a/Documentation/cgroup-v2.txt b/Documentation/cgroup-v2.txt index 227ce4883720..1d101423ca92 100644 --- a/Documentation/cgroup-v2.txt +++ b/Documentation/cgroup-v2.txt | |||
| @@ -332,14 +332,12 @@ a process with a non-root euid to migrate a target process into a | |||
| 332 | cgroup by writing its PID to the "cgroup.procs" file, the following | 332 | cgroup by writing its PID to the "cgroup.procs" file, the following |
| 333 | conditions must be met. | 333 | conditions must be met. |
| 334 | 334 | ||
| 335 | - The writer's euid must match either uid or suid of the target process. | ||
| 336 | |||
| 337 | - The writer must have write access to the "cgroup.procs" file. | 335 | - The writer must have write access to the "cgroup.procs" file. |
| 338 | 336 | ||
| 339 | - The writer must have write access to the "cgroup.procs" file of the | 337 | - The writer must have write access to the "cgroup.procs" file of the |
| 340 | common ancestor of the source and destination cgroups. | 338 | common ancestor of the source and destination cgroups. |
| 341 | 339 | ||
| 342 | The above three constraints ensure that while a delegatee may migrate | 340 | The above two constraints ensure that while a delegatee may migrate |
| 343 | processes around freely in the delegated sub-hierarchy it can't pull | 341 | processes around freely in the delegated sub-hierarchy it can't pull |
| 344 | in from or push out to outside the sub-hierarchy. | 342 | in from or push out to outside the sub-hierarchy. |
| 345 | 343 | ||
| @@ -354,10 +352,10 @@ all processes under C0 and C1 belong to U0. | |||
| 354 | 352 | ||
| 355 | Let's also say U0 wants to write the PID of a process which is | 353 | Let's also say U0 wants to write the PID of a process which is |
| 356 | currently in C10 into "C00/cgroup.procs". U0 has write access to the | 354 | currently in C10 into "C00/cgroup.procs". U0 has write access to the |
| 357 | file and uid match on the process; however, the common ancestor of the | 355 | file; however, the common ancestor of the source cgroup C10 and the |
| 358 | source cgroup C10 and the destination cgroup C00 is above the points | 356 | destination cgroup C00 is above the points of delegation and U0 would |
| 359 | of delegation and U0 would not have write access to its "cgroup.procs" | 357 | not have write access to its "cgroup.procs" files and thus the write |
| 360 | files and thus the write will be denied with -EACCES. | 358 | will be denied with -EACCES. |
| 361 | 359 | ||
| 362 | 360 | ||
| 363 | 2-6. Guidelines | 361 | 2-6. Guidelines |
diff --git a/kernel/cgroup/cgroup.c b/kernel/cgroup/cgroup.c index a99b15f9b577..fe374f803b20 100644 --- a/kernel/cgroup/cgroup.c +++ b/kernel/cgroup/cgroup.c | |||
| @@ -2349,20 +2349,9 @@ static int cgroup_procs_write_permission(struct task_struct *task, | |||
| 2349 | struct cgroup *dst_cgrp, | 2349 | struct cgroup *dst_cgrp, |
| 2350 | struct kernfs_open_file *of) | 2350 | struct kernfs_open_file *of) |
| 2351 | { | 2351 | { |
| 2352 | const struct cred *cred = current_cred(); | ||
| 2353 | const struct cred *tcred = get_task_cred(task); | ||
| 2354 | int ret = 0; | 2352 | int ret = 0; |
| 2355 | 2353 | ||
| 2356 | /* | 2354 | if (cgroup_on_dfl(dst_cgrp)) { |
| 2357 | * even if we're attaching all tasks in the thread group, we only | ||
| 2358 | * need to check permissions on one of them. | ||
| 2359 | */ | ||
| 2360 | if (!uid_eq(cred->euid, GLOBAL_ROOT_UID) && | ||
| 2361 | !uid_eq(cred->euid, tcred->uid) && | ||
| 2362 | !uid_eq(cred->euid, tcred->suid)) | ||
| 2363 | ret = -EACCES; | ||
| 2364 | |||
| 2365 | if (!ret && cgroup_on_dfl(dst_cgrp)) { | ||
| 2366 | struct super_block *sb = of->file->f_path.dentry->d_sb; | 2355 | struct super_block *sb = of->file->f_path.dentry->d_sb; |
| 2367 | struct cgroup *cgrp; | 2356 | struct cgroup *cgrp; |
| 2368 | struct inode *inode; | 2357 | struct inode *inode; |
| @@ -2380,9 +2369,21 @@ static int cgroup_procs_write_permission(struct task_struct *task, | |||
| 2380 | ret = inode_permission(inode, MAY_WRITE); | 2369 | ret = inode_permission(inode, MAY_WRITE); |
| 2381 | iput(inode); | 2370 | iput(inode); |
| 2382 | } | 2371 | } |
| 2372 | } else { | ||
| 2373 | const struct cred *cred = current_cred(); | ||
| 2374 | const struct cred *tcred = get_task_cred(task); | ||
| 2375 | |||
| 2376 | /* | ||
| 2377 | * even if we're attaching all tasks in the thread group, | ||
| 2378 | * we only need to check permissions on one of them. | ||
| 2379 | */ | ||
| 2380 | if (!uid_eq(cred->euid, GLOBAL_ROOT_UID) && | ||
| 2381 | !uid_eq(cred->euid, tcred->uid) && | ||
| 2382 | !uid_eq(cred->euid, tcred->suid)) | ||
| 2383 | ret = -EACCES; | ||
| 2384 | put_cred(tcred); | ||
| 2383 | } | 2385 | } |
| 2384 | 2386 | ||
| 2385 | put_cred(tcred); | ||
| 2386 | return ret; | 2387 | return ret; |
| 2387 | } | 2388 | } |
| 2388 | 2389 | ||
