diff options
| -rw-r--r-- | fs/proc/base.c | 23 |
1 files changed, 11 insertions, 12 deletions
diff --git a/fs/proc/base.c b/fs/proc/base.c index 3ce5ae9e3d2d..917f338a6739 100644 --- a/fs/proc/base.c +++ b/fs/proc/base.c | |||
| @@ -237,20 +237,19 @@ struct mm_struct *mm_for_maps(struct task_struct *task) | |||
| 237 | struct mm_struct *mm = get_task_mm(task); | 237 | struct mm_struct *mm = get_task_mm(task); |
| 238 | if (!mm) | 238 | if (!mm) |
| 239 | return NULL; | 239 | return NULL; |
| 240 | if (mm != current->mm) { | ||
| 241 | /* | ||
| 242 | * task->mm can be changed before security check, | ||
| 243 | * in that case we must notice the change after. | ||
| 244 | */ | ||
| 245 | if (!ptrace_may_access(task, PTRACE_MODE_READ) || | ||
| 246 | mm != task->mm) { | ||
| 247 | mmput(mm); | ||
| 248 | return NULL; | ||
| 249 | } | ||
| 250 | } | ||
| 240 | down_read(&mm->mmap_sem); | 251 | down_read(&mm->mmap_sem); |
| 241 | task_lock(task); | ||
| 242 | if (task->mm != mm) | ||
| 243 | goto out; | ||
| 244 | if (task->mm != current->mm && | ||
| 245 | __ptrace_may_access(task, PTRACE_MODE_READ) < 0) | ||
| 246 | goto out; | ||
| 247 | task_unlock(task); | ||
| 248 | return mm; | 252 | return mm; |
| 249 | out: | ||
| 250 | task_unlock(task); | ||
| 251 | up_read(&mm->mmap_sem); | ||
| 252 | mmput(mm); | ||
| 253 | return NULL; | ||
| 254 | } | 253 | } |
| 255 | 254 | ||
| 256 | static int proc_pid_cmdline(struct task_struct *task, char * buffer) | 255 | static int proc_pid_cmdline(struct task_struct *task, char * buffer) |
