Index: i386/include/vmparam.h =================================================================== RCS file: /home/cvsroot/jsn/sys/i386/include/vmparam.h,v retrieving revision 1.1.1.1 retrieving revision 1.2 diff -u -r1.1.1.1 -r1.2 --- i386/include/vmparam.h 2000/04/17 10:30:27 1.1.1.1 +++ i386/include/vmparam.h 2000/04/26 12:17:00 1.2 @@ -69,6 +69,9 @@ #define SGROWSIZ (128UL*1024) /* amount to grow stack */ #endif +#define MAXVSIZ (MAXTSIZ + MAXDSIZ + MAXSSIZ) /* default for VMEM */ +#define DFLVSIZ (DFLDSIZ + DFLSSIZ + MAXTSIZ) /* initial VMEM */ + #define USRTEXT (1*PAGE_SIZE) /* base of user text XXX bogus */ /* Index: i386/linux/imgact_linux.c =================================================================== RCS file: /home/cvsroot/jsn/sys/i386/linux/imgact_linux.c,v retrieving revision 1.1.1.1 diff -u -r1.1.1.1 imgact_linux.c --- i386/linux/imgact_linux.c 2000/04/17 10:30:34 1.1.1.1 +++ i386/linux/imgact_linux.c 2000/05/10 14:07:39 @@ -107,7 +107,9 @@ * text/data/bss must not exceed limits */ if (a_out->a_text > MAXTSIZ || - a_out->a_data + bss_size > imgp->proc->p_rlimit[RLIMIT_DATA].rlim_cur) + a_out->a_data + bss_size > imgp->proc->p_rlimit[RLIMIT_DATA].rlim_cur || + a_out->a_data + bss_size + a_out->a_text > + imgp->proc->p_rlimit[RLIMIT_VMEM].rlim_cur ) return (ENOMEM); /* copy in arguments and/or environment from old process */ Index: i386/linux/linux_misc.c =================================================================== RCS file: /home/cvsroot/jsn/sys/i386/linux/linux_misc.c,v retrieving revision 1.1.1.1 diff -u -r1.1.1.1 linux_misc.c --- i386/linux/linux_misc.c 2000/04/17 10:30:34 1.1.1.1 +++ i386/linux/linux_misc.c 2000/04/28 15:10:30 @@ -312,7 +312,8 @@ * the resources needed by this library. */ if (a_out->a_text > MAXTSIZ || - a_out->a_data + bss_size > p->p_rlimit[RLIMIT_DATA].rlim_cur) { + a_out->a_data + bss_size > p->p_rlimit[RLIMIT_DATA].rlim_cur || + a_out->a_text + a_out->a_data + bss_size > p->p_rlimit[RLIMIT_VMEM].rlim_cur) { error = ENOMEM; goto cleanup; } Index: kern/imgact_aout.c =================================================================== RCS file: /home/cvsroot/jsn/sys/kern/imgact_aout.c,v retrieving revision 1.1.1.1 diff -u -r1.1.1.1 imgact_aout.c --- kern/imgact_aout.c 2000/04/17 10:30:39 1.1.1.1 +++ kern/imgact_aout.c 2000/04/28 15:43:56 @@ -159,7 +159,10 @@ /* data + bss can't exceed rlimit */ a_out->a_data + bss_size > - imgp->proc->p_rlimit[RLIMIT_DATA].rlim_cur) + imgp->proc->p_rlimit[RLIMIT_DATA].rlim_cur || + + a_out->a_text + a_out->a_data + bss_size > + imgp->proc->p_rlimit[RLIMIT_VMEM].rlim_cur) return (ENOMEM); /* copy in arguments and/or environment from old process */ Index: kern/imgact_elf.c =================================================================== RCS file: /home/cvsroot/jsn/sys/kern/imgact_elf.c,v retrieving revision 1.1.1.1 retrieving revision 1.5 diff -u -r1.1.1.1 -r1.5 --- kern/imgact_elf.c 2000/04/17 10:30:39 1.1.1.1 +++ kern/imgact_elf.c 2000/04/26 12:17:05 1.5 @@ -451,7 +451,39 @@ return ENOEXEC; } phdr = (const Elf_Phdr*)(imgp->image_header + hdr->e_phoff); + + /* we better check rlimits *before* new vmspace is exec()-ed */ + for (i = 0; i < hdr->e_phnum; i++) { + if (phdr[i].p_type == PT_LOAD) { /* Loadable segment */ + /* + * Is this .text or .data ?? + * + * We only handle one each of those yet XXX + */ + if (hdr->e_entry >= phdr[i].p_vaddr && + hdr->e_entry <(phdr[i].p_vaddr+phdr[i].p_memsz)) { + text_addr = trunc_page(phdr[i].p_vaddr); + text_size = round_page(phdr[i].p_memsz + + phdr[i].p_vaddr - + text_addr); + entry = (u_long)hdr->e_entry; + } else { + data_addr = trunc_page(phdr[i].p_vaddr); + data_size = round_page(phdr[i].p_memsz + + phdr[i].p_vaddr - + data_addr); + } + } + } + + if (text_size > MAXTSIZ || + data_size > imgp->proc->p_rlimit[RLIMIT_DATA].rlim_cur || + text_size+data_size > imgp->proc->p_rlimit[RLIMIT_VMEM].rlim_cur ) { + error = ENOMEM ; + goto fail ; + } + /* * From this point on, we may have resources that need to be freed. */ @@ -481,25 +513,6 @@ phdr[i].p_memsz, phdr[i].p_filesz, prot)) != 0) goto fail; - - /* - * Is this .text or .data ?? - * - * We only handle one each of those yet XXX - */ - if (hdr->e_entry >= phdr[i].p_vaddr && - hdr->e_entry <(phdr[i].p_vaddr+phdr[i].p_memsz)) { - text_addr = trunc_page(phdr[i].p_vaddr); - text_size = round_page(phdr[i].p_memsz + - phdr[i].p_vaddr - - text_addr); - entry = (u_long)hdr->e_entry; - } else { - data_addr = trunc_page(phdr[i].p_vaddr); - data_size = round_page(phdr[i].p_memsz + - phdr[i].p_vaddr - - data_addr); - } break; case PT_INTERP: /* Path to interpreter */ if (phdr[i].p_filesz > MAXPATHLEN || Index: kern/imgact_gzip.c =================================================================== RCS file: /home/cvsroot/jsn/sys/kern/imgact_gzip.c,v retrieving revision 1.1.1.1 diff -u -r1.1.1.1 imgact_gzip.c --- kern/imgact_gzip.c 2000/04/17 10:30:39 1.1.1.1 +++ kern/imgact_gzip.c 2000/04/28 15:11:46 @@ -211,7 +211,10 @@ /* data + bss can't exceed rlimit */ gz->a_out.a_data + gz->bss_size > - gz->ip->proc->p_rlimit[RLIMIT_DATA].rlim_cur) { + gz->ip->proc->p_rlimit[RLIMIT_DATA].rlim_cur || + /* data + bss can't exceed RLIMIT_VMEM */ + gz->a_out.a_text + gz->a_out.a_data + gz->bss_size > + gz->ip->proc->p_rlimit[RLIMIT_VMEM].rlim_cur ) { gz->where = __LINE__; return (ENOMEM); } Index: kern/kern_resource.c =================================================================== RCS file: /home/cvsroot/jsn/sys/kern/kern_resource.c,v retrieving revision 1.1.1.1 retrieving revision 1.2 diff -u -r1.1.1.1 -r1.2 --- kern/kern_resource.c 2000/04/17 10:30:39 1.1.1.1 +++ kern/kern_resource.c 2000/04/26 12:17:05 1.2 @@ -411,6 +411,14 @@ limp->rlim_max = MAXDSIZ; break; + case RLIMIT_VMEM: + if (limp->rlim_cur > MAXVSIZ) + limp->rlim_cur = MAXVSIZ; + if (limp->rlim_max > MAXVSIZ) + limp->rlim_max = MAXVSIZ; + break; + + case RLIMIT_STACK: if (limp->rlim_cur > MAXSSIZ) limp->rlim_cur = MAXSSIZ; Index: svr4/imgact_svr4.c =================================================================== RCS file: /home/cvsroot/jsn/sys/svr4/imgact_svr4.c,v retrieving revision 1.1.1.1 diff -u -r1.1.1.1 imgact_svr4.c --- svr4/imgact_svr4.c 2000/04/17 10:31:22 1.1.1.1 +++ svr4/imgact_svr4.c 2000/04/28 15:12:30 @@ -105,7 +105,8 @@ * text/data/bss must not exceed limits */ if (a_out->a_text > MAXTSIZ || - a_out->a_data + bss_size > imgp->proc->p_rlimit[RLIMIT_DATA].rlim_cur) + a_out->a_data + bss_size > imgp->proc->p_rlimit[RLIMIT_DATA].rlim_cur || + a_out->a_text + a_out->a_data + bss_size > imgp->proc->p_rlimit[RLIMIT_VMEM].rlim_cur) return (ENOMEM); /* copy in arguments and/or environment from old process */ Index: svr4/svr4_misc.c =================================================================== RCS file: /home/cvsroot/jsn/sys/svr4/svr4_misc.c,v retrieving revision 1.1.1.1 diff -u -r1.1.1.1 svr4_misc.c --- svr4/svr4_misc.c 2000/04/17 10:31:22 1.1.1.1 +++ svr4/svr4_misc.c 2000/04/28 15:21:42 @@ -805,6 +805,14 @@ if (new > old) { vm_size_t diff; + + /* check RLIMIT_VMEM */ + + if (vm->vm_map.size + (new - old) > + (unsigned) p->p_rlimit[RLIMIT_VMEM].rlim_cur) { + return (ENOMEM) ; + } + if (swap_pager_full) { return (ENOMEM); } Index: sys/resource.h =================================================================== RCS file: /home/cvsroot/jsn/sys/sys/resource.h,v retrieving revision 1.1.1.1 retrieving revision 1.2 diff -u -r1.1.1.1 -r1.2 --- sys/resource.h 2000/04/17 10:31:25 1.1.1.1 +++ sys/resource.h 2000/04/26 12:17:12 1.2 @@ -88,8 +88,9 @@ #define RLIMIT_NPROC 7 /* number of processes */ #define RLIMIT_NOFILE 8 /* number of open files */ #define RLIMIT_SBSIZE 9 /* maximum size of all socket buffers */ +#define RLIMIT_VMEM 10 /* virtual process size */ -#define RLIM_NLIMITS 10 /* number of resource limits */ +#define RLIM_NLIMITS 11 /* number of resource limits */ #define RLIM_INFINITY ((rlim_t)(((u_quad_t)1 << 63) - 1)) @@ -110,6 +111,7 @@ "nproc", "nofile", "sbsize", + "vmem", }; #endif Index: vm/vm_glue.c =================================================================== RCS file: /home/cvsroot/jsn/sys/vm/vm_glue.c,v retrieving revision 1.1.1.1 retrieving revision 1.2 diff -u -r1.1.1.1 -r1.2 --- vm/vm_glue.c 2000/04/17 10:31:27 1.1.1.1 +++ vm/vm_glue.c 2000/04/26 12:17:14 1.2 @@ -301,6 +301,8 @@ p->p_rlimit[RLIMIT_STACK].rlim_max = MAXSSIZ; p->p_rlimit[RLIMIT_DATA].rlim_cur = DFLDSIZ; p->p_rlimit[RLIMIT_DATA].rlim_max = MAXDSIZ; + p->p_rlimit[RLIMIT_VMEM].rlim_cur = DFLVSIZ; + p->p_rlimit[RLIMIT_VMEM].rlim_max = MAXVSIZ; /* limit the limit to no less than 2MB */ rss_limit = max(cnt.v_free_count, 512); p->p_rlimit[RLIMIT_RSS].rlim_cur = ptoa(rss_limit); Index: vm/vm_mmap.c =================================================================== RCS file: /home/cvsroot/jsn/sys/vm/vm_mmap.c,v retrieving revision 1.1.1.1 diff -u -r1.1.1.1 vm_mmap.c --- vm/vm_mmap.c 2000/04/17 10:31:28 1.1.1.1 +++ vm/vm_mmap.c 2000/05/10 13:31:51 @@ -49,6 +49,8 @@ #include "opt_rlimit.h" #include +#include +#include #include #include #include @@ -1016,6 +1018,11 @@ return (0); objsize = size = round_page(size); + + if (p->p_vmspace->vm_map.size + size > + p->p_rlimit[RLIMIT_VMEM].rlim_cur) { + return (ENOMEM) ; + } /* * We currently can only deal with page aligned file offsets. Index: vm/vm_unix.c =================================================================== RCS file: /home/cvsroot/jsn/sys/vm/vm_unix.c,v retrieving revision 1.1.1.1 diff -u -r1.1.1.1 vm_unix.c --- vm/vm_unix.c 2000/04/17 10:31:28 1.1.1.1 +++ vm/vm_unix.c 2000/04/28 15:21:30 @@ -93,6 +93,14 @@ vm_size_t diff; diff = new - old; + + /* check RLIMIT_VMEM */ + + if (vm->vm_map.size + diff > + (unsigned) p->p_rlimit[RLIMIT_VMEM].rlim_cur) { + return (ENOMEM) ; + } + rv = vm_map_find(&vm->vm_map, NULL, 0, &old, diff, FALSE, VM_PROT_ALL, VM_PROT_ALL, 0); if (rv != KERN_SUCCESS) {