Skip to content

Commit

Permalink
proc: use down_read_killable mmap_sem for /proc/pid/map_files
Browse files Browse the repository at this point in the history
Do not remain stuck forever if something goes wrong.  Using a killable
lock permits cleanup of stuck tasks and simplifies investigation.

It seems ->d_revalidate() could return any error (except ECHILD) to abort
validation and pass error as result of lookup sequence.

[[email protected]: fix proc_map_files_lookup() return value, per Andrei]
Link: http://lkml.kernel.org/r/156007493995.3335.9595044802115356911.stgit@buzz
Signed-off-by: Konstantin Khlebnikov <[email protected]>
Reviewed-by: Roman Gushchin <[email protected]>
Reviewed-by: Cyrill Gorcunov <[email protected]>
Reviewed-by: Kirill Tkhai <[email protected]>
Acked-by: Michal Hocko <[email protected]>
Cc: Alexey Dobriyan <[email protected]>
Cc: Al Viro <[email protected]>
Cc: Matthew Wilcox <[email protected]>
Cc: Michal Koutný <[email protected]>
Cc: Oleg Nesterov <[email protected]>
Signed-off-by: Andrew Morton <[email protected]>
Signed-off-by: Linus Torvalds <[email protected]>
  • Loading branch information
koct9i authored and torvalds committed Jul 12, 2019
1 parent c460380 commit cd9e2bb
Showing 1 changed file with 22 additions and 6 deletions.
28 changes: 22 additions & 6 deletions fs/proc/base.c
Original file line number Diff line number Diff line change
Expand Up @@ -1962,9 +1962,12 @@ static int map_files_d_revalidate(struct dentry *dentry, unsigned int flags)
goto out;

if (!dname_to_vma_addr(dentry, &vm_start, &vm_end)) {
down_read(&mm->mmap_sem);
exact_vma_exists = !!find_exact_vma(mm, vm_start, vm_end);
up_read(&mm->mmap_sem);
status = down_read_killable(&mm->mmap_sem);
if (!status) {
exact_vma_exists = !!find_exact_vma(mm, vm_start,
vm_end);
up_read(&mm->mmap_sem);
}
}

mmput(mm);
Expand Down Expand Up @@ -2010,8 +2013,11 @@ static int map_files_get_link(struct dentry *dentry, struct path *path)
if (rc)
goto out_mmput;

rc = down_read_killable(&mm->mmap_sem);
if (rc)
goto out_mmput;

rc = -ENOENT;
down_read(&mm->mmap_sem);
vma = find_exact_vma(mm, vm_start, vm_end);
if (vma && vma->vm_file) {
*path = vma->vm_file->f_path;
Expand Down Expand Up @@ -2107,7 +2113,11 @@ static struct dentry *proc_map_files_lookup(struct inode *dir,
if (!mm)
goto out_put_task;

down_read(&mm->mmap_sem);
result = ERR_PTR(-EINTR);
if (down_read_killable(&mm->mmap_sem))
goto out_put_mm;

result = ERR_PTR(-ENOENT);
vma = find_exact_vma(mm, vm_start, vm_end);
if (!vma)
goto out_no_vma;
Expand All @@ -2118,6 +2128,7 @@ static struct dentry *proc_map_files_lookup(struct inode *dir,

out_no_vma:
up_read(&mm->mmap_sem);
out_put_mm:
mmput(mm);
out_put_task:
put_task_struct(task);
Expand Down Expand Up @@ -2160,7 +2171,12 @@ proc_map_files_readdir(struct file *file, struct dir_context *ctx)
mm = get_task_mm(task);
if (!mm)
goto out_put_task;
down_read(&mm->mmap_sem);

ret = down_read_killable(&mm->mmap_sem);
if (ret) {
mmput(mm);
goto out_put_task;
}

nr_files = 0;

Expand Down

0 comments on commit cd9e2bb

Please sign in to comment.