diff options
author | KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com> | 2009-09-21 20:02:35 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-09-22 10:17:34 -0400 |
commit | 73d7c33e81aed92ac185950a20407c1a2ea65a83 (patch) | |
tree | e178b87c69034a6487db9bdfbf7ffc932056002f | |
parent | d0107eb07320b5d37c0f8a9f015534caebb28a48 (diff) |
kcore: /proc/kcore should use vread
/proc/kcore has its own routine to access vmallc area. It can be replaced
with vread(). And by this, /proc/kcore can do safe access to vmalloc
area.
Signed-off-by: KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com>
Cc: WANG Cong <xiyou.wangcong@gmail.com>
Cc: Mike Smith <scgtrp@gmail.com>
Cc: Nick Piggin <nickpiggin@yahoo.com.au>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r-- | fs/proc/kcore.c | 35 |
1 files changed, 2 insertions, 33 deletions
diff --git a/fs/proc/kcore.c b/fs/proc/kcore.c index 59b43a068872..f06f45b42181 100644 --- a/fs/proc/kcore.c +++ b/fs/proc/kcore.c | |||
@@ -328,43 +328,12 @@ read_kcore(struct file *file, char __user *buffer, size_t buflen, loff_t *fpos) | |||
328 | return -EFAULT; | 328 | return -EFAULT; |
329 | } else if (is_vmalloc_addr((void *)start)) { | 329 | } else if (is_vmalloc_addr((void *)start)) { |
330 | char * elf_buf; | 330 | char * elf_buf; |
331 | struct vm_struct *m; | ||
332 | unsigned long curstart = start; | ||
333 | unsigned long cursize = tsz; | ||
334 | 331 | ||
335 | elf_buf = kzalloc(tsz, GFP_KERNEL); | 332 | elf_buf = kzalloc(tsz, GFP_KERNEL); |
336 | if (!elf_buf) | 333 | if (!elf_buf) |
337 | return -ENOMEM; | 334 | return -ENOMEM; |
338 | 335 | vread(elf_buf, (char *)start, tsz); | |
339 | read_lock(&vmlist_lock); | 336 | /* we have to zero-fill user buffer even if no read */ |
340 | for (m=vmlist; m && cursize; m=m->next) { | ||
341 | unsigned long vmstart; | ||
342 | unsigned long vmsize; | ||
343 | unsigned long msize = m->size - PAGE_SIZE; | ||
344 | |||
345 | if (((unsigned long)m->addr + msize) < | ||
346 | curstart) | ||
347 | continue; | ||
348 | if ((unsigned long)m->addr > (curstart + | ||
349 | cursize)) | ||
350 | break; | ||
351 | vmstart = (curstart < (unsigned long)m->addr ? | ||
352 | (unsigned long)m->addr : curstart); | ||
353 | if (((unsigned long)m->addr + msize) > | ||
354 | (curstart + cursize)) | ||
355 | vmsize = curstart + cursize - vmstart; | ||
356 | else | ||
357 | vmsize = (unsigned long)m->addr + | ||
358 | msize - vmstart; | ||
359 | curstart = vmstart + vmsize; | ||
360 | cursize -= vmsize; | ||
361 | /* don't dump ioremap'd stuff! (TA) */ | ||
362 | if (m->flags & VM_IOREMAP) | ||
363 | continue; | ||
364 | memcpy(elf_buf + (vmstart - start), | ||
365 | (char *)vmstart, vmsize); | ||
366 | } | ||
367 | read_unlock(&vmlist_lock); | ||
368 | if (copy_to_user(buffer, elf_buf, tsz)) { | 337 | if (copy_to_user(buffer, elf_buf, tsz)) { |
369 | kfree(elf_buf); | 338 | kfree(elf_buf); |
370 | return -EFAULT; | 339 | return -EFAULT; |