diff options
author | David Howells <dhowells@redhat.com> | 2006-09-27 04:50:15 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-09-27 11:26:14 -0400 |
commit | 0ec76a110f432e98277e464b82ace8dd66571689 (patch) | |
tree | 3ed8de0ea6869fe17bec7689c493a2db02f73f4a /kernel/ptrace.c | |
parent | 361f6ed1d00f666a1a7c33f3e9aaccb713f9b9e4 (diff) |
[PATCH] NOMMU: Check that access_process_vm() has a valid target
Check that access_process_vm() is accessing a valid mapping in the target
process.
This limits ptrace() accesses and accesses through /proc/<pid>/maps to only
those regions actually mapped by a program.
Signed-off-by: David Howells <dhowells@redhat.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'kernel/ptrace.c')
-rw-r--r-- | kernel/ptrace.c | 54 |
1 files changed, 0 insertions, 54 deletions
diff --git a/kernel/ptrace.c b/kernel/ptrace.c index 9a111f70145c..8aad0331d82e 100644 --- a/kernel/ptrace.c +++ b/kernel/ptrace.c | |||
@@ -241,60 +241,6 @@ int ptrace_detach(struct task_struct *child, unsigned int data) | |||
241 | return 0; | 241 | return 0; |
242 | } | 242 | } |
243 | 243 | ||
244 | /* | ||
245 | * Access another process' address space. | ||
246 | * Source/target buffer must be kernel space, | ||
247 | * Do not walk the page table directly, use get_user_pages | ||
248 | */ | ||
249 | |||
250 | int access_process_vm(struct task_struct *tsk, unsigned long addr, void *buf, int len, int write) | ||
251 | { | ||
252 | struct mm_struct *mm; | ||
253 | struct vm_area_struct *vma; | ||
254 | struct page *page; | ||
255 | void *old_buf = buf; | ||
256 | |||
257 | mm = get_task_mm(tsk); | ||
258 | if (!mm) | ||
259 | return 0; | ||
260 | |||
261 | down_read(&mm->mmap_sem); | ||
262 | /* ignore errors, just check how much was sucessfully transfered */ | ||
263 | while (len) { | ||
264 | int bytes, ret, offset; | ||
265 | void *maddr; | ||
266 | |||
267 | ret = get_user_pages(tsk, mm, addr, 1, | ||
268 | write, 1, &page, &vma); | ||
269 | if (ret <= 0) | ||
270 | break; | ||
271 | |||
272 | bytes = len; | ||
273 | offset = addr & (PAGE_SIZE-1); | ||
274 | if (bytes > PAGE_SIZE-offset) | ||
275 | bytes = PAGE_SIZE-offset; | ||
276 | |||
277 | maddr = kmap(page); | ||
278 | if (write) { | ||
279 | copy_to_user_page(vma, page, addr, | ||
280 | maddr + offset, buf, bytes); | ||
281 | set_page_dirty_lock(page); | ||
282 | } else { | ||
283 | copy_from_user_page(vma, page, addr, | ||
284 | buf, maddr + offset, bytes); | ||
285 | } | ||
286 | kunmap(page); | ||
287 | page_cache_release(page); | ||
288 | len -= bytes; | ||
289 | buf += bytes; | ||
290 | addr += bytes; | ||
291 | } | ||
292 | up_read(&mm->mmap_sem); | ||
293 | mmput(mm); | ||
294 | |||
295 | return buf - old_buf; | ||
296 | } | ||
297 | |||
298 | int ptrace_readdata(struct task_struct *tsk, unsigned long src, char __user *dst, int len) | 244 | int ptrace_readdata(struct task_struct *tsk, unsigned long src, char __user *dst, int len) |
299 | { | 245 | { |
300 | int copied = 0; | 246 | int copied = 0; |