diff -Nur linux-2.4.17.old/fs/exec.c linux-2.4.17.new/fs/exec.c --- linux-2.4.17.old/fs/exec.c Sat Jan 19 16:00:53 2002 +++ linux-2.4.17.new/fs/exec.c Sun Jan 20 17:48:41 2002 @@ -21,6 +21,8 @@ * trying until we recognize the file or we run out of supported binary * formats. */ +/* per process task_unmapped_base (C) 2002 Kasper Dupont + */ #include #include @@ -571,6 +573,29 @@ if (bprm->e_uid != current->euid || bprm->e_gid != current->egid || permission(bprm->file->f_dentry->d_inode,MAY_READ)) current->mm->dumpable = 0; + + /* FIXME FIXME FIXME! This is probably too late. + * We need to use RLIM_INFINITY while setting up + * the executable, but at that time dumpable is + * not yet computed. We probably need to reorder + * parts of the code. + * + * Perhaps I was wrong, perhaps this is actually + * the right place to do all this. Somebody please + * verify this. [KD] + */ + { + int base=vm_task_unmapped_base; + if (current->mm->dumpable) { + base=current->rlim[RLIMIT_TUMB].rlim_cur; + if (base==RLIM_INFINITY) base=vm_task_unmapped_base; + } else { + current->rlim[RLIMIT_TUMB].rlim_max=RLIM_INFINITY; + } + current->rlim[RLIMIT_TUMB].rlim_cur=current->rlim[RLIMIT_TUMB].rlim_max; + if ((base<1)||(base>TUMB_MAX)) base=TUMB_DEF; + current->mm->task_unmapped_base=base<>((unsigned long)PAGE_SHIFT)) +#define TUMB_MAX (BYTE2PAGE(PAGE_OFFSET)-3) +#define TUMB_DEF (BYTE2PAGE(TASK_UNMAPPED_BASE)) +extern int vm_task_unmapped_base; + /* * mapping from the currently active vm_flags protection bits (the * low four bits) to a page protection mask.. diff -Nur linux-2.4.17.old/include/linux/sched.h linux-2.4.17.new/include/linux/sched.h --- linux-2.4.17.old/include/linux/sched.h Sat Jan 19 16:02:15 2002 +++ linux-2.4.17.new/include/linux/sched.h Sat Jan 19 16:04:34 2002 @@ -227,6 +227,8 @@ unsigned dumpable:1; + unsigned long task_unmapped_base; + /* Architecture-specific MM context */ mm_context_t context; }; diff -Nur linux-2.4.17.old/include/linux/sysctl.h linux-2.4.17.new/include/linux/sysctl.h --- linux-2.4.17.old/include/linux/sysctl.h Sat Jan 19 16:02:34 2002 +++ linux-2.4.17.new/include/linux/sysctl.h Sat Jan 19 16:04:47 2002 @@ -140,8 +140,9 @@ VM_PAGERDAEMON=8, /* struct: Control kswapd behaviour */ VM_PGT_CACHE=9, /* struct: Set page table cache parameters */ VM_PAGE_CLUSTER=10, /* int: set number of pages to swap together */ - VM_MIN_READAHEAD=12, /* Min file readahead */ - VM_MAX_READAHEAD=13 /* Max file readahead */ + VM_MIN_READAHEAD=12, /* Min file readahead */ + VM_MAX_READAHEAD=13, /* Max file readahead */ + VM_TASK_UNMAPPED_BASE=14/* task_unmapped_base */ }; diff -Nur linux-2.4.17.old/kernel/sys.c linux-2.4.17.new/kernel/sys.c --- linux-2.4.17.old/kernel/sys.c Sat Jan 19 16:01:54 2002 +++ linux-2.4.17.new/kernel/sys.c Sun Jan 20 21:58:44 2002 @@ -3,6 +3,8 @@ * * Copyright (C) 1991, 1992 Linus Torvalds */ +/* per process task_unmapped_base (C) 2002 Kasper Dupont + */ #include #include @@ -1112,6 +1114,8 @@ #endif +#define TUMB_INVAL(x) (((x<1)||(x>TUMB_MAX))&&(x!=RLIM_INFINITY)) + asmlinkage long sys_setrlimit(unsigned int resource, struct rlimit *rlim) { struct rlimit new_rlim, *old_rlim; @@ -1121,10 +1125,15 @@ if(copy_from_user(&new_rlim, rlim, sizeof(*rlim))) return -EFAULT; old_rlim = current->rlim + resource; - if (((new_rlim.rlim_cur > old_rlim->rlim_max) || - (new_rlim.rlim_max > old_rlim->rlim_max)) && - !capable(CAP_SYS_RESOURCE)) - return -EPERM; + if (resource == RLIMIT_TUMB) { + if (TUMB_INVAL(new_rlim.rlim_cur)|| + TUMB_INVAL(new_rlim.rlim_max)) return -EINVAL; + } else { + if (((new_rlim.rlim_cur > old_rlim->rlim_max) || + (new_rlim.rlim_max > old_rlim->rlim_max)) && + !capable(CAP_SYS_RESOURCE)) + return -EPERM; + } if (resource == RLIMIT_NOFILE) { if (new_rlim.rlim_cur > NR_OPEN || new_rlim.rlim_max > NR_OPEN) return -EPERM; diff -Nur linux-2.4.17.old/kernel/sysctl.c linux-2.4.17.new/kernel/sysctl.c --- linux-2.4.17.old/kernel/sysctl.c Sat Jan 19 16:01:58 2002 +++ linux-2.4.17.new/kernel/sysctl.c Sun Jan 20 14:08:56 2002 @@ -17,6 +17,8 @@ * The list_for_each() macro wasn't appropriate for the sysctl loop. * Removed it and replaced it with older style, 03/23/00, Bill Wendling */ +/* per process task_unmapped_base (C) 2002 Kasper Dupont + */ #include #include @@ -275,6 +277,8 @@ &vm_min_readahead,sizeof(int), 0644, NULL, &proc_dointvec}, {VM_MAX_READAHEAD, "max-readahead", &vm_max_readahead,sizeof(int), 0644, NULL, &proc_dointvec}, + {VM_TASK_UNMAPPED_BASE, "task_unmapped_base", + &vm_task_unmapped_base,sizeof(int), 0644, NULL, &proc_dointvec}, {0} }; diff -Nur linux-2.4.17.old/mm/mmap.c linux-2.4.17.new/mm/mmap.c --- linux-2.4.17.old/mm/mmap.c Sat Jan 19 16:11:17 2002 +++ linux-2.4.17.new/mm/mmap.c Sun Jan 20 17:42:35 2002 @@ -3,6 +3,8 @@ * * Written by obz. */ +/* per process task_unmapped_base (C) 2002 Kasper Dupont + */ #include #include #include @@ -45,6 +47,8 @@ }; int sysctl_overcommit_memory; +int vm_task_unmapped_base = TUMB_DEF; +EXPORT_SYMBOL(vm_task_unmapped_base); /* Check that a process has enough memory to allocate a * new virtual mapping. @@ -601,7 +605,7 @@ (!vma || addr + len <= vma->vm_start)) return addr; } - addr = PAGE_ALIGN(TASK_UNMAPPED_BASE); + addr = PAGE_ALIGN(current->mm->task_unmapped_base); for (vma = find_vma(current->mm, addr); ; vma = vma->vm_next) { /* At this point: (!vma || addr < vma->vm_end). */