diff -urN clean/arch/mips/kernel/irixelf.c linux-2.6.5-SLES9_SP1_BRANCH_91/arch/mips/kernel/irixelf.c --- clean/arch/mips/kernel/irixelf.c 2005-01-09 12:25:26.000000000 -0500 +++ linux-2.6.5-SLES9_SP1_BRANCH_91/arch/mips/kernel/irixelf.c 2005-01-19 19:29:59.909824951 -0500 @@ -128,7 +128,7 @@ end = PAGE_ALIGN(end); if (end <= start) return; - do_brk(start, end - start); + do_brk_locked(start, end - start); } diff -urN clean/arch/x86_64/ia32/ia32_aout.c linux-2.6.5-SLES9_SP1_BRANCH_91/arch/x86_64/ia32/ia32_aout.c --- clean/arch/x86_64/ia32/ia32_aout.c 2005-01-09 12:25:33.000000000 -0500 +++ linux-2.6.5-SLES9_SP1_BRANCH_91/arch/x86_64/ia32/ia32_aout.c 2005-01-19 19:30:50.255145196 -0500 @@ -114,7 +114,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; } @@ -327,7 +327,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; @@ -363,7 +363,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), @@ -476,7 +476,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); @@ -500,7 +500,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; diff -urN clean/fs/binfmt_aout.c linux-2.6.5-SLES9_SP1_BRANCH_91/fs/binfmt_aout.c --- clean/fs/binfmt_aout.c 2005-01-09 12:25:33.000000000 -0500 +++ linux-2.6.5-SLES9_SP1_BRANCH_91/fs/binfmt_aout.c 2005-01-19 19:31:40.480490745 -0500 @@ -51,7 +51,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; @@ -381,7 +381,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), @@ -486,7 +486,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 *)start_addr, ex.a_text + ex.a_data, &pos); @@ -510,7 +510,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; diff -urN clean/fs/binfmt_elf.c linux-2.6.5-SLES9_SP1_BRANCH_91/fs/binfmt_elf.c --- clean/fs/binfmt_elf.c 2005-01-09 12:25:33.000000000 -0500 +++ linux-2.6.5-SLES9_SP1_BRANCH_91/fs/binfmt_elf.c 2005-01-19 19:29:59.914823791 -0500 @@ -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; } @@ -406,7 +406,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; } @@ -446,7 +446,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) @@ -454,7 +454,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; @@ -1006,7 +1006,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: diff -urN clean/include/linux/mm.h linux-2.6.5-SLES9_SP1_BRANCH_91/include/linux/mm.h --- clean/include/linux/mm.h 2005-01-09 12:25:34.000000000 -0500 +++ linux-2.6.5-SLES9_SP1_BRANCH_91/include/linux/mm.h 2005-01-19 19:29:59.915823559 -0500 @@ -821,6 +821,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); /* vma merging helpers */ static inline void diff -urN clean/mm/mmap.c linux-2.6.5-SLES9_SP1_BRANCH_91/mm/mmap.c --- clean/mm/mmap.c 2005-01-09 12:25:34.000000000 -0500 +++ linux-2.6.5-SLES9_SP1_BRANCH_91/mm/mmap.c 2005-01-19 19:29:59.917823095 -0500 @@ -1658,6 +1658,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) { diff -urN clean/mm/nommu.c linux-2.6.5-SLES9_SP1_BRANCH_91/mm/nommu.c --- clean/mm/nommu.c 2005-01-09 12:25:27.000000000 -0500 +++ linux-2.6.5-SLES9_SP1_BRANCH_91/mm/nommu.c 2005-01-19 19:29:59.918822864 -0500 @@ -227,6 +227,11 @@ return audit_lresult(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