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 /fs/proc/base.c | |
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>
Diffstat (limited to 'fs/proc/base.c')
-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) |