Expand the scope of cpuset_can_attach_check() by including the setting of setsched flag inside cpuset_can_attach_check() with the new @oldcs and @psetsched argument. As cpuset_can_attach_check() is also called from cpuset_can_fork(), set the new arguments to NULL from that caller.
Unified · Split
| @@ -3022,12 +3022,39 @@ out: · 3021 unmodified lines | |||
| 3022 | * For v1, cpus_allowed and mems_allowed can't be empty. | 3022 | * For v1, cpus_allowed and mems_allowed can't be empty. |
| 3023 | * For v2, effective_cpus can't be empty. | 3023 | * For v2, effective_cpus can't be empty. |
| 3024 | * Note that in v1, effective_cpus = cpus_allowed. | 3024 | * Note that in v1, effective_cpus = cpus_allowed. |
| 3025 | * | ||
| 3026 | * Also set the boolean flag passed in by @psetsched depending on if | ||
| 3027 | * security_task_setscheduler() call is needed and @oldcs is not NULL. | ||
| 3025 | */ | 3028 | */ |
| 3026 | static int cpuset_can_attach_check(struct cpuset *cs) | 3029 | static int cpuset_can_attach_check(struct cpuset *cs, struct cpuset *oldcs, |
| 3030 | bool *psetsched) | ||
| 3027 | { | 3031 | { |
| 3028 | if (cpumask_empty(cs->effective_cpus) || | 3032 | if (cpumask_empty(cs->effective_cpus) || |
| 3029 | (!is_in_v2_mode() && nodes_empty(cs->mems_allowed))) | 3033 | (!is_in_v2_mode() && nodes_empty(cs->mems_allowed))) |
| 3030 | return -ENOSPC; | 3034 | return -ENOSPC; |
| 3035 | |||
| 3036 | if (!oldcs) | ||
| 3037 | return 0; | ||
| 3038 | |||
| 3039 | /* | ||
| 3040 | * Skip rights over task setsched check in v2 when nothing changes, | ||
| 3041 | * migration permission derives from hierarchy ownership in | ||
| 3042 | * cgroup_procs_write_permission()). | ||
| 3043 | */ | ||
| 3044 | *psetsched = !cpuset_v2() || | ||
| 3045 | !cpumask_equal(cs->effective_cpus, oldcs->effective_cpus) || | ||
| 3046 | !nodes_equal(cs->effective_mems, oldcs->effective_mems); | ||
| 3047 | |||
| 3048 | /* | ||
| 3049 | * A v1 cpuset with tasks will have no CPU left only when CPU hotplug | ||
| 3050 | * brings the last online CPU offline as users are not allowed to empty | ||
| 3051 | * cpuset.cpus when there are active tasks inside. When that happens, | ||
| 3052 | * we should allow tasks to migrate out without security check to make | ||
| 3053 | * sure they will be able to run after migration. | ||
| 3054 | */ | ||
| 3055 | if (!is_in_v2_mode() && cpumask_empty(oldcs->effective_cpus)) | ||
| 3056 | *psetsched = false; | ||
| 3057 | |||
| 3031 | return 0; | 3058 | return 0; |
| 3032 | } | 3059 | } |
| 3033 | 3060 | ||
| @@ -3074,29 +3101,10 @@ static int cpuset_can_attach(struct cgroup_taskset *tset) · 40 unmodified lines | |||
| 3074 | mutex_lock(&cpuset_mutex); | 3101 | mutex_lock(&cpuset_mutex); |
| 3075 | 3102 | ||
| 3076 | /* Check to see if task is allowed in the cpuset */ | 3103 | /* Check to see if task is allowed in the cpuset */ |
| 3077 | ret = cpuset_can_attach_check(cs); | 3104 | ret = cpuset_can_attach_check(cs, oldcs, &setsched_check); |
| 3078 | if (ret) | 3105 | if (ret) |
| 3079 | goto out_unlock; | 3106 | goto out_unlock; |
| 3080 | 3107 | ||
| 3081 | /* | ||
| 3082 | * Skip rights over task setsched check in v2 when nothing changes, | ||
| 3083 | * migration permission derives from hierarchy ownership in | ||
| 3084 | * cgroup_procs_write_permission()). | ||
| 3085 | */ | ||
| 3086 | setsched_check = !cpuset_v2() || | ||
| 3087 | !cpumask_equal(cs->effective_cpus, oldcs->effective_cpus) || | ||
| 3088 | !nodes_equal(cs->effective_mems, oldcs->effective_mems); | ||
| 3089 | |||
| 3090 | /* | ||
| 3091 | * A v1 cpuset with tasks will have no CPU left only when CPU hotplug | ||
| 3092 | * brings the last online CPU offline as users are not allowed to empty | ||
| 3093 | * cpuset.cpus when there are active tasks inside. When that happens, | ||
| 3094 | * we should allow tasks to migrate out without security check to make | ||
| 3095 | * sure they will be able to run after migration. | ||
| 3096 | */ | ||
| 3097 | if (!is_in_v2_mode() && cpumask_empty(oldcs->effective_cpus)) | ||
| 3098 | setsched_check = false; | ||
| 3099 | |||
| 3100 | cgroup_taskset_for_each(task, css, tset) { | 3108 | cgroup_taskset_for_each(task, css, tset) { |
| 3101 | ret = task_can_attach(task); | 3109 | ret = task_can_attach(task); |
| 3102 | if (ret) | 3110 | if (ret) |
| @@ -3639,7 +3647,7 @@ static int cpuset_can_fork(struct task_struct *task, struct css_set *cset) · 536 unmodified lines | |||
| 3639 | mutex_lock(&cpuset_mutex); | 3647 | mutex_lock(&cpuset_mutex); |
| 3640 | 3648 | ||
| 3641 | /* Check to see if task is allowed in the cpuset */ | 3649 | /* Check to see if task is allowed in the cpuset */ |
| 3642 | ret = cpuset_can_attach_check(cs); | 3650 | ret = cpuset_can_attach_check(cs, NULL, NULL); |
| 3643 | if (ret) | 3651 | if (ret) |
| 3644 | goto out_unlock; | 3652 | goto out_unlock; |
| 3645 | 3653 | ||