The patch titled Subject: prctl_set_mm: downgrade mmap_sem to read lock has been added to the -mm tree. Its filename is prctl_set_mm-downgrade-mmap_sem-to-read-lock.patch This patch should soon appear at http://ozlabs.org/~akpm/mmots/broken-out/prctl_set_mm-downgrade-mmap_sem-to-read-lock.patch and later at http://ozlabs.org/~akpm/mmotm/broken-out/prctl_set_mm-downgrade-mmap_sem-to-read-lock.patch Before you just go and hit "reply", please: a) Consider who else should be cc'ed b) Prefer to cc a suitable mailing list as well c) Ideally: find the original patch on the mailing list and do a reply-to-all to that, adding suitable additional cc's *** Remember to use Documentation/process/submit-checklist.rst when testing your code *** The -mm tree is included into linux-next and is updated there every 3-4 working days ------------------------------------------------------ From: Michal Koutný <mkoutny@xxxxxxxx> Subject: prctl_set_mm: downgrade mmap_sem to read lock The commit a3b609ef9f8b ("proc read mm's {arg,env}_{start,end} with mmap semaphore taken.") added synchronization of reading argument/environment boundaries under mmap_sem. Later commit 88aa7cc688d4 ("mm: introduce arg_lock to protect arg_start|end and env_start|end in mm_struct") avoided the coarse use of mmap_sem in similar situations. But there still remained two places that (mis)use mmap_sem. get_cmdline should also use arg_lock instead of mmap_sem when it reads the boundaries. The second place that should use arg_lock is in prctl_set_mm. By protecting the boundaries fields with the arg_lock, we can downgrade mmap_sem to reader lock (analogous to what we already do in prctl_set_mm_map). Link: http://lkml.kernel.org/r/20190502125203.24014-3-mkoutny@xxxxxxxx Fixes: 88aa7cc688d4 ("mm: introduce arg_lock to protect arg_start|end and env_start|end in mm_struct") Signed-off-by: Michal Koutný <mkoutny@xxxxxxxx> Signed-off-by: Laurent Dufour <ldufour@xxxxxxxxxxxxx> Co-developed-by: Laurent Dufour <ldufour@xxxxxxxxxxxxx> Reviewed-by: Cyrill Gorcunov <gorcunov@xxxxxxxxx> Acked-by: Michal Hocko <mhocko@xxxxxxxx> Cc: Yang Shi <yang.shi@xxxxxxxxxxxxxxxxx> Cc: Mateusz Guzik <mguzik@xxxxxxxxxx> Cc: Kirill Tkhai <ktkhai@xxxxxxxxxxxxx> Signed-off-by: Andrew Morton <akpm@xxxxxxxxxxxxxxxxxxxx> --- kernel/sys.c | 10 ++++++++-- mm/util.c | 4 ++-- 2 files changed, 10 insertions(+), 4 deletions(-) --- a/kernel/sys.c~prctl_set_mm-downgrade-mmap_sem-to-read-lock +++ a/kernel/sys.c @@ -2122,9 +2122,14 @@ static int prctl_set_mm(int opt, unsigne error = -EINVAL; - down_write(&mm->mmap_sem); + /* + * arg_lock protects concurent updates of arg boundaries, we need mmap_sem for + * a) concurrent sys_brk, b) finding VMA for addr validation. + */ + down_read(&mm->mmap_sem); vma = find_vma(mm, addr); + spin_lock(&mm->arg_lock); prctl_map.start_code = mm->start_code; prctl_map.end_code = mm->end_code; prctl_map.start_data = mm->start_data; @@ -2212,7 +2217,8 @@ static int prctl_set_mm(int opt, unsigne error = 0; out: - up_write(&mm->mmap_sem); + spin_unlock(&mm->arg_lock); + up_read(&mm->mmap_sem); return error; } --- a/mm/util.c~prctl_set_mm-downgrade-mmap_sem-to-read-lock +++ a/mm/util.c @@ -717,12 +717,12 @@ int get_cmdline(struct task_struct *task if (!mm->arg_end) goto out_mm; /* Shh! No looking before we're done */ - down_read(&mm->mmap_sem); + spin_lock(&mm->arg_lock); arg_start = mm->arg_start; arg_end = mm->arg_end; env_start = mm->env_start; env_end = mm->env_end; - up_read(&mm->mmap_sem); + spin_unlock(&mm->arg_lock); len = arg_end - arg_start; _ Patches currently in -mm which might be from mkoutny@xxxxxxxx are prctl_set_mm-refactor-checks-from-validate_prctl_map.patch prctl_set_mm-downgrade-mmap_sem-to-read-lock.patch