diff options
author | Konstantin Khlebnikov <[email protected]> | 2019-07-11 21:00:07 -0700 |
---|---|---|
committer | Linus Torvalds <[email protected]> | 2019-07-12 11:05:47 -0700 |
commit | 1e426fe28261b03f297992e89da3320b42816f4e (patch) | |
tree | 7b44fe31e28a4dc64053652cca031326935f4b92 | |
parent | cd9e2bb8271c971d9f37c722be2616c7f8ba0664 (diff) |
mm: use down_read_killable for locking mmap_sem in access_remote_vm
This function is used by ptrace and proc files like /proc/pid/cmdline and
/proc/pid/environ.
Access_remote_vm never returns error codes, all errors are ignored and
only size of successfully read data is returned. So, if current task was
killed we'll simply return 0 (bytes read).
Mmap_sem could be locked for a long time or forever if something goes
wrong. Using a killable lock permits cleanup of stuck tasks and
simplifies investigation.
Link: http://lkml.kernel.org/r/156007494202.3335.16782303099589302087.stgit@buzz
Signed-off-by: Konstantin Khlebnikov <[email protected]>
Reviewed-by: Michal Koutný <[email protected]>
Acked-by: Oleg Nesterov <[email protected]>
Acked-by: Michal Hocko <[email protected]>
Cc: Alexey Dobriyan <[email protected]>
Cc: Matthew Wilcox <[email protected]>
Cc: Cyrill Gorcunov <[email protected]>
Cc: Kirill Tkhai <[email protected]>
Cc: Al Viro <[email protected]>
Cc: Roman Gushchin <[email protected]>
Signed-off-by: Andrew Morton <[email protected]>
Signed-off-by: Linus Torvalds <[email protected]>
-rw-r--r-- | mm/memory.c | 4 | ||||
-rw-r--r-- | mm/nommu.c | 3 |
2 files changed, 5 insertions, 2 deletions
diff --git a/mm/memory.c b/mm/memory.c index ad4bf1a1a0ef..53bd59579861 100644 --- a/mm/memory.c +++ b/mm/memory.c @@ -4344,7 +4344,9 @@ int __access_remote_vm(struct task_struct *tsk, struct mm_struct *mm, void *old_buf = buf; int write = gup_flags & FOLL_WRITE; - down_read(&mm->mmap_sem); + if (down_read_killable(&mm->mmap_sem)) + return 0; + /* ignore errors, just check how much was successfully transferred */ while (len) { int bytes, ret, offset; diff --git a/mm/nommu.c b/mm/nommu.c index 07165ad2e548..eb3e2e558da1 100644 --- a/mm/nommu.c +++ b/mm/nommu.c @@ -1704,7 +1704,8 @@ int __access_remote_vm(struct task_struct *tsk, struct mm_struct *mm, struct vm_area_struct *vma; int write = gup_flags & FOLL_WRITE; - down_read(&mm->mmap_sem); + if (down_read_killable(&mm->mmap_sem)) + return 0; /* the access must start within one of the target process's mappings */ vma = find_vma(mm, addr); |