diff -urN -X dontdiff linux/arch/arm/mm/ioremap.c 2328-vma/arch/arm/mm/ioremap.c --- linux/arch/arm/mm/ioremap.c Sun Oct 24 10:07:58 1999 +++ 2328-vma/arch/arm/mm/ioremap.c Sat Nov 13 12:30:58 1999 @@ -136,7 +136,7 @@ /* * Ok, go for it.. */ - area = get_vm_area(size); + area = get_vm_area(size, VM_IOREMAP); if (!area) return NULL; addr = area->addr; diff -urN -X dontdiff linux/arch/i386/mm/ioremap.c 2328-vma/arch/i386/mm/ioremap.c --- linux/arch/i386/mm/ioremap.c Sun Oct 24 10:07:58 1999 +++ 2328-vma/arch/i386/mm/ioremap.c Sat Nov 13 12:29:32 1999 @@ -131,7 +131,7 @@ /* * Ok, go for it.. */ - area = get_vm_area(size); + area = get_vm_area(size, VM_IOREMAP); if (!area) return NULL; addr = area->addr; diff -urN -X dontdiff linux/arch/m68k/mm/kmap.c 2328-vma/arch/m68k/mm/kmap.c --- linux/arch/m68k/mm/kmap.c Wed May 12 16:50:00 1999 +++ 2328-vma/arch/m68k/mm/kmap.c Sat Nov 13 12:30:41 1999 @@ -39,7 +39,7 @@ static inline struct vm_struct *get_io_area(unsigned long size) { - return get_vm_area(size); + return get_vm_area(size, VM_IOREMAP); } diff -urN -X dontdiff linux/arch/ppc/mm/init.c 2328-vma/arch/ppc/mm/init.c --- linux/arch/ppc/mm/init.c Fri Nov 12 19:40:09 1999 +++ 2328-vma/arch/ppc/mm/init.c Sat Nov 13 12:30:22 1999 @@ -422,7 +422,7 @@ if (mem_init_done) { struct vm_struct *area; - area = get_vm_area(size); + area = get_vm_area(size, VM_IOREMAP); if (area == 0) return NULL; v = VMALLOC_VMADDR(area->addr); diff -urN -X dontdiff linux/arch/sh/mm/ioremap.c 2328-vma/arch/sh/mm/ioremap.c --- linux/arch/sh/mm/ioremap.c Sun Oct 24 10:07:59 1999 +++ 2328-vma/arch/sh/mm/ioremap.c Sat Nov 13 12:31:14 1999 @@ -123,7 +123,7 @@ /* * Ok, go for it.. */ - area = get_vm_area(size); + area = get_vm_area(size, VM_IOREMAP); if (!area) return NULL; addr = area->addr; diff -urN -X dontdiff linux/fs/proc/kcore.c 2328-vma/fs/proc/kcore.c --- linux/fs/proc/kcore.c Sat Nov 13 11:36:59 1999 +++ 2328-vma/fs/proc/kcore.c Sat Nov 13 12:50:26 1999 @@ -3,9 +3,9 @@ * * Modelled on fs/exec.c:aout_core_dump() * Jeremy Fitzhardinge - * Implemented by David Howells + * ELF version written by David Howells * Modified and incorporated into 2.3.x by Tigran Aivazian - * Support to dump vmalloc'd data structures (ELF only), Tigran Aivazian + * Support to dump vmalloc'd areas (ELF only), Tigran Aivazian */ #include @@ -42,8 +42,7 @@ }; #ifdef CONFIG_KCORE_AOUT -static ssize_t read_kcore(struct file * file, char * buf, - size_t count, loff_t *ppos) +static ssize_t read_kcore(struct file *file, char *buf, size_t count, loff_t *ppos) { unsigned long long p = *ppos, memsize; ssize_t read; @@ -78,7 +77,8 @@ if (p + count1 > sizeof(struct user)) count1 = sizeof(struct user)-p; pnt = (char *) &dump + p; - copy_to_user(buf,(void *) pnt, count1); + if (copy_to_user(buf,(void *) pnt, count1)) + return -EFAULT; buf += count1; p += count1; count -= count1; @@ -89,14 +89,16 @@ count1 = PAGE_SIZE + FIRST_MAPPED - p; if (count1 > count) count1 = count; - clear_user(buf, count1); + if (clear_user(buf, count1)) + return -EFAULT; buf += count1; p += count1; count -= count1; read += count1; } if (count > 0) { - copy_to_user(buf, (void *) (PAGE_OFFSET+p-PAGE_SIZE), count); + if (copy_to_user(buf, (void *) (PAGE_OFFSET+p-PAGE_SIZE), count)) + return -EFAULT; read += count; } *ppos += read; @@ -129,6 +131,8 @@ } for (m=vmlist; m; m=m->next) { + if (m->flags & VM_IOREMAP) /* don't dump ioremap'd stuff! (TA) */ + continue; try = (size_t)m->addr + m->size; if (try > size) size = try; @@ -247,8 +251,11 @@ phdr->p_filesz = phdr->p_memsz = ((unsigned long)high_memory - PAGE_OFFSET); phdr->p_align = PAGE_SIZE; - /* setup ELF PT_LOAD program headers, one for every kvma range */ + /* setup ELF PT_LOAD program header for every vmalloc'd area */ for (m=vmlist; m; m=m->next) { + if (m->flags & VM_IOREMAP) /* don't dump ioremap'd stuff! (TA) */ + continue; + phdr = (struct elf_phdr *) bufp; bufp += sizeof(struct elf_phdr); offset += sizeof(struct elf_phdr); @@ -315,12 +322,8 @@ { ssize_t acc = 0; size_t size, tsz; - char * elf_buffer; - size_t elf_buflen = 0; - int num_vma = 0; - - if (verify_area(VERIFY_WRITE, buffer, buflen)) - return -EFAULT; + size_t elf_buflen; + int num_vma; /* XXX we need to somehow lock vmlist between here * and after elf_kcore_store_hdr() returns. @@ -336,16 +339,21 @@ /* construct an ELF core header if we'll need some of it */ if (*fpos < elf_buflen) { + char * elf_buf; + tsz = elf_buflen - *fpos; if (buflen < tsz) tsz = buflen; - elf_buffer = kmalloc(elf_buflen, GFP_KERNEL); - if (!elf_buffer) + elf_buf = kmalloc(elf_buflen, GFP_ATOMIC); + if (!elf_buf) return -ENOMEM; - memset(elf_buffer, 0, elf_buflen); - elf_kcore_store_hdr(elf_buffer, num_vma, elf_buflen); - copy_to_user(buffer, elf_buffer + *fpos, tsz); - kfree(elf_buffer); + memset(elf_buf, 0, elf_buflen); + elf_kcore_store_hdr(elf_buf, num_vma, elf_buflen); + if (copy_to_user(buffer, elf_buf + *fpos, tsz)) { + kfree(elf_buf); + return -EFAULT; + } + kfree(elf_buf); buflen -= tsz; *fpos += tsz; buffer += tsz; @@ -365,7 +373,8 @@ tsz = buflen; /* write zeros to buffer */ - clear_user(buffer, tsz); + if (clear_user(buffer, tsz)) + return -EFAULT; buflen -= tsz; *fpos += tsz; buffer += tsz; @@ -376,13 +385,12 @@ return tsz; } #endif - /* fill the remainder of the buffer from kernel VM space */ - copy_to_user(buffer, __va(*fpos - elf_buflen), buflen); + if (copy_to_user(buffer, __va(*fpos - elf_buflen), buflen)) + return -EFAULT; acc += buflen; *fpos += buflen; return acc; - } #endif /* CONFIG_KCORE_AOUT */ diff -urN -X dontdiff linux/include/linux/vmalloc.h 2328-vma/include/linux/vmalloc.h --- linux/include/linux/vmalloc.h Fri Nov 12 19:40:20 1999 +++ 2328-vma/include/linux/vmalloc.h Sat Nov 13 12:33:26 1999 @@ -6,6 +6,10 @@ #include +/* bits in vm_struct->flags */ +#define VM_IOREMAP 0x00000001 /* ioremap() and friends */ +#define VM_ALLOC 0x00000002 /* vmalloc() */ + struct vm_struct { unsigned long flags; void * addr; @@ -13,7 +17,7 @@ struct vm_struct * next; }; -struct vm_struct * get_vm_area(unsigned long size); +struct vm_struct * get_vm_area(unsigned long size, unsigned long flags); void vfree(void * addr); void * vmalloc(unsigned long size); long vread(char *buf, char *addr, unsigned long count); diff -urN -X dontdiff linux/mm/vmalloc.c 2328-vma/mm/vmalloc.c --- linux/mm/vmalloc.c Fri Nov 12 19:40:20 1999 +++ 2328-vma/mm/vmalloc.c Sat Nov 13 12:28:45 1999 @@ -152,7 +152,7 @@ return 0; } -struct vm_struct * get_vm_area(unsigned long size) +struct vm_struct * get_vm_area(unsigned long size, unsigned long flags) { unsigned long addr; struct vm_struct **p, *tmp, *area; @@ -170,6 +170,7 @@ return NULL; } } + area->flags = flags; area->addr = (void *)addr; area->size = size + PAGE_SIZE; area->next = *p; @@ -208,7 +209,7 @@ BUG(); return NULL; } - area = get_vm_area(size); + area = get_vm_area(size, VM_ALLOC); if (!area) { BUG(); return NULL;