kcore: /proc/kcore should use vread
authorKAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com>
Tue, 22 Sep 2009 00:02:35 +0000 (17:02 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Tue, 22 Sep 2009 14:17:34 +0000 (07:17 -0700)
/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>
fs/proc/kcore.c

index 59b43a068872de286df70b7632ae982f4ce149ab..f06f45b421810b4d13069b65f06782daa246e55c 100644 (file)
@@ -328,43 +328,12 @@ read_kcore(struct file *file, char __user *buffer, size_t buflen, loff_t *fpos)
                                return -EFAULT;
                } else if (is_vmalloc_addr((void *)start)) {
                        char * elf_buf;
-                       struct vm_struct *m;
-                       unsigned long curstart = start;
-                       unsigned long cursize = tsz;
 
                        elf_buf = kzalloc(tsz, GFP_KERNEL);
                        if (!elf_buf)
                                return -ENOMEM;
-
-                       read_lock(&vmlist_lock);
-                       for (m=vmlist; m && cursize; m=m->next) {
-                               unsigned long vmstart;
-                               unsigned long vmsize;
-                               unsigned long msize = m->size - PAGE_SIZE;
-
-                               if (((unsigned long)m->addr + msize) < 
-                                                               curstart)
-                                       continue;
-                               if ((unsigned long)m->addr > (curstart + 
-                                                               cursize))
-                                       break;
-                               vmstart = (curstart < (unsigned long)m->addr ? 
-                                       (unsigned long)m->addr : curstart);
-                               if (((unsigned long)m->addr + msize) > 
-                                                       (curstart + cursize))
-                                       vmsize = curstart + cursize - vmstart;
-                               else
-                                       vmsize = (unsigned long)m->addr + 
-                                                       msize - vmstart;
-                               curstart = vmstart + vmsize;
-                               cursize -= vmsize;
-                               /* don't dump ioremap'd stuff! (TA) */
-                               if (m->flags & VM_IOREMAP)
-                                       continue;
-                               memcpy(elf_buf + (vmstart - start),
-                                       (char *)vmstart, vmsize);
-                       }
-                       read_unlock(&vmlist_lock);
+                       vread(elf_buf, (char *)start, tsz);
+                       /* we have to zero-fill user buffer even if no read */
                        if (copy_to_user(buffer, elf_buf, tsz)) {
                                kfree(elf_buf);
                                return -EFAULT;