-
由 Xu Qiang 提交于
ascend inclusion category: bugfix bugzilla: https://gitee.com/openeuler/kernel/issues/I612UG CVE: NA -------------------------------- We increase task->mm->mm_users by one when we add the task to a sharepool group. Correspondingly we should drop the mm_users count when the task exits. Currently we hijack the mmput function and make it return early and decrease mm->mm_users by one (just as mmput would do) if it is not called from a task's exiting process, or we decrease mm->mm_users by the group number the task was added to. This has two problems: 1. It makes mmput and sp_group_exit hard to understand. 2. The process of judging if the task (also its mm) is exiting and decrease its mm_users count is not atomic. We use this condition: mm->mm_users == master->count + MM_WOULD_FREE(1) If someone else change the mm->mm_users during those two steps, the mm->mm_users would be wrong and mm_struct cannot be released anymore. Suppose the following process: proc1 proc2 1) mmput | V 2) enter sp_group_exit and 'mm->mm_users == master->count + 1' is true 3) | mmget V 4) decrease mm->mm_users by master->count | V 5) enter __mmput and release mm_struct if mm->mm_users == 1 6) mmput The statistical structure who has the same id of the task would get leaked together with mm_struct, so the next time we try to create the statistical structure of the same id, we get a failure. We fix this by moving sp_group_exit to do_exit() actually where the task is exiting. We don't need to judge if the task is exiting when someone calling mmput so there is no chance to change mm_users wrongly. Signed-off-by: NXu Qiang <xuqiang36@huawei.com> Signed-off-by: NWang Wensheng <wangwensheng4@huawei.com>
7086bdba