diff options
author | Roland McGrath <roland@redhat.com> | 2008-04-29 04:01:38 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2008-04-29 11:06:17 -0400 |
commit | 638fa202cdb207083a12d6f73e313605a8fc1037 (patch) | |
tree | e049d74e9f7e15a55149dc17482572c8b2aefa18 /fs/proc/base.c | |
parent | 0d5c9f5f59a61cf8e98e2925cb5d81cbe7694305 (diff) |
procfs: mem permission cleanup
This cleans up the permission checks done for /proc/PID/mem i/o calls. It
puts all the logic in a new function, check_mem_permission().
The old code repeated the (!MAY_PTRACE(task) || !ptrace_may_attach(task))
magical expression multiple times. The new function does all that work in one
place, with clear comments.
The old code called security_ptrace() twice on successful checks, once in
MAY_PTRACE() and once in __ptrace_may_attach(). Now it's only called once,
and only if all other checks have succeeded.
Signed-off-by: Roland McGrath <roland@redhat.com>
Cc: Alexey Dobriyan <adobriyan@gmail.com>
Cc: Oleg Nesterov <oleg@tv-sign.ru>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'fs/proc/base.c')
-rw-r--r-- | fs/proc/base.c | 38 |
1 files changed, 29 insertions, 9 deletions
diff --git a/fs/proc/base.c b/fs/proc/base.c index b48ddb119945..fcf02f2deeba 100644 --- a/fs/proc/base.c +++ b/fs/proc/base.c | |||
@@ -195,12 +195,32 @@ static int proc_root_link(struct inode *inode, struct path *path) | |||
195 | return result; | 195 | return result; |
196 | } | 196 | } |
197 | 197 | ||
198 | #define MAY_PTRACE(task) \ | 198 | /* |
199 | (task == current || \ | 199 | * Return zero if current may access user memory in @task, -error if not. |
200 | (task->parent == current && \ | 200 | */ |
201 | (task->ptrace & PT_PTRACED) && \ | 201 | static int check_mem_permission(struct task_struct *task) |
202 | (task_is_stopped_or_traced(task)) && \ | 202 | { |
203 | security_ptrace(current,task) == 0)) | 203 | /* |
204 | * A task can always look at itself, in case it chooses | ||
205 | * to use system calls instead of load instructions. | ||
206 | */ | ||
207 | if (task == current) | ||
208 | return 0; | ||
209 | |||
210 | /* | ||
211 | * If current is actively ptrace'ing, and would also be | ||
212 | * permitted to freshly attach with ptrace now, permit it. | ||
213 | */ | ||
214 | if (task->parent == current && (task->ptrace & PT_PTRACED) && | ||
215 | task_is_stopped_or_traced(task) && | ||
216 | ptrace_may_attach(task)) | ||
217 | return 0; | ||
218 | |||
219 | /* | ||
220 | * Noone else is allowed. | ||
221 | */ | ||
222 | return -EPERM; | ||
223 | } | ||
204 | 224 | ||
205 | struct mm_struct *mm_for_maps(struct task_struct *task) | 225 | struct mm_struct *mm_for_maps(struct task_struct *task) |
206 | { | 226 | { |
@@ -722,7 +742,7 @@ static ssize_t mem_read(struct file * file, char __user * buf, | |||
722 | if (!task) | 742 | if (!task) |
723 | goto out_no_task; | 743 | goto out_no_task; |
724 | 744 | ||
725 | if (!MAY_PTRACE(task) || !ptrace_may_attach(task)) | 745 | if (check_mem_permission(task)) |
726 | goto out; | 746 | goto out; |
727 | 747 | ||
728 | ret = -ENOMEM; | 748 | ret = -ENOMEM; |
@@ -748,7 +768,7 @@ static ssize_t mem_read(struct file * file, char __user * buf, | |||
748 | 768 | ||
749 | this_len = (count > PAGE_SIZE) ? PAGE_SIZE : count; | 769 | this_len = (count > PAGE_SIZE) ? PAGE_SIZE : count; |
750 | retval = access_process_vm(task, src, page, this_len, 0); | 770 | retval = access_process_vm(task, src, page, this_len, 0); |
751 | if (!retval || !MAY_PTRACE(task) || !ptrace_may_attach(task)) { | 771 | if (!retval || check_mem_permission(task)) { |
752 | if (!ret) | 772 | if (!ret) |
753 | ret = -EIO; | 773 | ret = -EIO; |
754 | break; | 774 | break; |
@@ -792,7 +812,7 @@ static ssize_t mem_write(struct file * file, const char __user *buf, | |||
792 | if (!task) | 812 | if (!task) |
793 | goto out_no_task; | 813 | goto out_no_task; |
794 | 814 | ||
795 | if (!MAY_PTRACE(task) || !ptrace_may_attach(task)) | 815 | if (check_mem_permission(task)) |
796 | goto out; | 816 | goto out; |
797 | 817 | ||
798 | copied = -ENOMEM; | 818 | copied = -ENOMEM; |