Index: linux-2.6.10-ckdev/arch/mips/kernel/irixelf.c =================================================================== --- linux-2.6.10-ckdev.orig/arch/mips/kernel/irixelf.c 2004-12-25 10:14:47.000000000 +1100 +++ linux-2.6.10-ckdev/arch/mips/kernel/irixelf.c 2005-01-10 14:36:17.823328848 +1100 @@ -127,7 +127,7 @@ end = PAGE_ALIGN(end); if (end <= start) return; - do_brk(start, end - start); + do_brk_locked(start, end - start); } Index: linux-2.6.10-ckdev/arch/x86_64/ia32/ia32_aout.c =================================================================== --- linux-2.6.10-ckdev.orig/arch/x86_64/ia32/ia32_aout.c 2004-12-25 10:14:47.000000000 +1100 +++ linux-2.6.10-ckdev/arch/x86_64/ia32/ia32_aout.c 2005-01-10 14:36:17.824328696 +1100 @@ -114,7 +114,7 @@ end = PAGE_ALIGN(end); if (end <= start) return; - do_brk(start, end - start); + do_brk_locked(start, end - start); } #if CORE_DUMP @@ -324,7 +324,7 @@ pos = 32; map_size = ex.a_text+ex.a_data; - error = do_brk(text_addr & PAGE_MASK, map_size); + error = do_brk_locked(text_addr & PAGE_MASK, map_size); if (error != (text_addr & PAGE_MASK)) { send_sig(SIGKILL, current, 0); return error; @@ -360,7 +360,7 @@ if (!bprm->file->f_op->mmap||((fd_offset & ~PAGE_MASK) != 0)) { loff_t pos = fd_offset; - do_brk(N_TXTADDR(ex), ex.a_text+ex.a_data); + do_brk_locked(N_TXTADDR(ex), ex.a_text+ex.a_data); bprm->file->f_op->read(bprm->file,(char *)N_TXTADDR(ex), ex.a_text+ex.a_data, &pos); flush_icache_range((unsigned long) N_TXTADDR(ex), @@ -469,7 +469,7 @@ } #endif - do_brk(start_addr, ex.a_text + ex.a_data + ex.a_bss); + do_brk_locked(start_addr, ex.a_text + ex.a_data + ex.a_bss); file->f_op->read(file, (char *)start_addr, ex.a_text + ex.a_data, &pos); @@ -493,7 +493,7 @@ len = PAGE_ALIGN(ex.a_text + ex.a_data); bss = ex.a_text + ex.a_data + ex.a_bss; if (bss > len) { - error = do_brk(start_addr + len, bss - len); + error = do_brk_locked(start_addr + len, bss - len); retval = error; if (error != start_addr + len) goto out; Index: linux-2.6.10-ckdev/fs/binfmt_aout.c =================================================================== --- linux-2.6.10-ckdev.orig/fs/binfmt_aout.c 2004-12-25 10:14:50.000000000 +1100 +++ linux-2.6.10-ckdev/fs/binfmt_aout.c 2005-01-10 14:36:17.824328696 +1100 @@ -50,7 +50,7 @@ start = PAGE_ALIGN(start); end = PAGE_ALIGN(end); if (end > start) { - unsigned long addr = do_brk(start, end - start); + unsigned long addr = do_brk_locked(start, end - start); if (BAD_ADDR(addr)) return addr; } @@ -323,10 +323,10 @@ loff_t pos = fd_offset; /* Fuck me plenty... */ /* */ - error = do_brk(N_TXTADDR(ex), ex.a_text); + error = do_brk_locked(N_TXTADDR(ex), ex.a_text); bprm->file->f_op->read(bprm->file, (char *) N_TXTADDR(ex), ex.a_text, &pos); - error = do_brk(N_DATADDR(ex), ex.a_data); + error = do_brk_locked(N_DATADDR(ex), ex.a_data); bprm->file->f_op->read(bprm->file, (char *) N_DATADDR(ex), ex.a_data, &pos); goto beyond_if; @@ -347,7 +347,7 @@ map_size = ex.a_text+ex.a_data; #endif - error = do_brk(text_addr & PAGE_MASK, map_size); + error = do_brk_locked(text_addr & PAGE_MASK, map_size); if (error != (text_addr & PAGE_MASK)) { send_sig(SIGKILL, current, 0); return error; @@ -382,7 +382,7 @@ if (!bprm->file->f_op->mmap||((fd_offset & ~PAGE_MASK) != 0)) { loff_t pos = fd_offset; - do_brk(N_TXTADDR(ex), ex.a_text+ex.a_data); + do_brk_locked(N_TXTADDR(ex), ex.a_text+ex.a_data); bprm->file->f_op->read(bprm->file, (char __user *)N_TXTADDR(ex), ex.a_text+ex.a_data, &pos); @@ -488,7 +488,7 @@ error_time = jiffies; } - do_brk(start_addr, ex.a_text + ex.a_data + ex.a_bss); + do_brk_locked(start_addr, ex.a_text + ex.a_data + ex.a_bss); file->f_op->read(file, (char __user *)start_addr, ex.a_text + ex.a_data, &pos); @@ -512,7 +512,7 @@ len = PAGE_ALIGN(ex.a_text + ex.a_data); bss = ex.a_text + ex.a_data + ex.a_bss; if (bss > len) { - error = do_brk(start_addr + len, bss - len); + error = do_brk_locked(start_addr + len, bss - len); retval = error; if (error != start_addr + len) goto out; Index: linux-2.6.10-ckdev/fs/binfmt_elf.c =================================================================== --- linux-2.6.10-ckdev.orig/fs/binfmt_elf.c 2004-12-25 10:14:50.000000000 +1100 +++ linux-2.6.10-ckdev/fs/binfmt_elf.c 2005-01-10 14:36:17.825328544 +1100 @@ -88,7 +88,7 @@ start = ELF_PAGEALIGN(start); end = ELF_PAGEALIGN(end); if (end > start) { - unsigned long addr = do_brk(start, end - start); + unsigned long addr = do_brk_locked(start, end - start); if (BAD_ADDR(addr)) return addr; } @@ -408,7 +408,7 @@ /* Map the last of the bss segment */ if (last_bss > elf_bss) { - error = do_brk(elf_bss, last_bss - elf_bss); + error = do_brk_locked(elf_bss, last_bss - elf_bss); if (BAD_ADDR(error)) goto out_close; } @@ -448,7 +448,7 @@ goto out; } - do_brk(0, text_data); + do_brk_locked(0, text_data); if (!interpreter->f_op || !interpreter->f_op->read) goto out; if (interpreter->f_op->read(interpreter, addr, text_data, &offset) < 0) @@ -456,7 +456,7 @@ flush_icache_range((unsigned long)addr, (unsigned long)addr + text_data); - do_brk(ELF_PAGESTART(text_data + ELF_MIN_ALIGN - 1), + do_brk_locked(ELF_PAGESTART(text_data + ELF_MIN_ALIGN - 1), interp_ex->a_bss); elf_entry = interp_ex->a_entry; @@ -1025,7 +1025,7 @@ len = ELF_PAGESTART(elf_phdata->p_filesz + elf_phdata->p_vaddr + ELF_MIN_ALIGN - 1); bss = elf_phdata->p_memsz + elf_phdata->p_vaddr; if (bss > len) - do_brk(len, bss - len); + do_brk_locked(len, bss - len); error = 0; out_free_ph: Index: linux-2.6.10-ckdev/include/linux/mm.h =================================================================== --- linux-2.6.10-ckdev.orig/include/linux/mm.h 2005-01-10 14:34:36.844679936 +1100 +++ linux-2.6.10-ckdev/include/linux/mm.h 2005-01-10 14:36:17.826328392 +1100 @@ -710,6 +710,7 @@ extern int do_munmap(struct mm_struct *, unsigned long, size_t); extern unsigned long do_brk(unsigned long, unsigned long); +extern unsigned long do_brk_locked(unsigned long, unsigned long); /* filemap.c */ extern unsigned long page_unuse(struct page *); Index: linux-2.6.10-ckdev/mm/mmap.c =================================================================== --- linux-2.6.10-ckdev.orig/mm/mmap.c 2005-01-10 14:30:30.056197488 +1100 +++ linux-2.6.10-ckdev/mm/mmap.c 2005-01-10 14:36:17.827328240 +1100 @@ -1827,6 +1827,20 @@ EXPORT_SYMBOL(do_brk); +/* locking version of do_brk. */ +unsigned long do_brk_locked(unsigned long addr, unsigned long len) +{ + unsigned long ret; + + down_write(¤t->mm->mmap_sem); + ret = do_brk(addr, len); + up_write(¤t->mm->mmap_sem); + + return ret; +} + +EXPORT_SYMBOL(do_brk_locked); + /* Release all mmaps. */ void exit_mmap(struct mm_struct *mm) { Index: linux-2.6.10-ckdev/mm/nommu.c =================================================================== --- linux-2.6.10-ckdev.orig/mm/nommu.c 2004-12-25 10:14:51.000000000 +1100 +++ linux-2.6.10-ckdev/mm/nommu.c 2005-01-10 14:36:17.827328240 +1100 @@ -237,6 +237,11 @@ return mm->brk = brk; } +unsigned long do_brk_locked(unsigned long addr, unsigned long len) +{ + return -ENOMEM; +} + /* * Combine the mmap "prot" and "flags" argument into one "vm_flags" used * internally. Essentially, translate the "PROT_xxx" and "MAP_xxx" bits