diff options
| author | Oleg Nesterov <oleg@redhat.com> | 2009-06-23 15:25:32 -0400 |
|---|---|---|
| committer | James Morris <jmorris@namei.org> | 2009-08-10 06:47:42 -0400 |
| commit | 13f0feafa6b8aead57a2a328e2fca6a5828bf286 (patch) | |
| tree | fb396118339319406daf7f6782782eaef31b3b53 | |
| parent | f4b9a988685da6386d7f9a72df3098bcc3270526 (diff) | |
mm_for_maps: simplify, use ptrace_may_access()
It would be nice to kill __ptrace_may_access(). It requires task_lock(),
but this lock is only needed to read mm->flags in the middle.
Convert mm_for_maps() to use ptrace_may_access(), this also simplifies
the code a little bit.
Also, we do not need to take ->mmap_sem in advance. In fact I think
mm_for_maps() should not play with ->mmap_sem at all, the caller should
take this lock.
With or without this patch, without ->cred_guard_mutex held we can race
with exec() and get the new ->mm but check old creds.
Signed-off-by: Oleg Nesterov <oleg@redhat.com>
Reviewed-by: Serge Hallyn <serue@us.ibm.com>
Signed-off-by: James Morris <jmorris@namei.org>
| -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) |
