Date: Mon, 14 May 2007 21:51:33 GMT From: John Baldwin <jhb@FreeBSD.org> To: Perforce Change Reviews <perforce@freebsd.org> Subject: PERFORCE change 119857 for review Message-ID: <200705142151.l4ELpXvP068210@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=119857 Change 119857 by jhb@jhb_mutex on 2007/05/14 21:51:29 Change handling of resource limits for 32-bit processes on 64-bit kernels so that we just cap the values on read instead of always creating a new limit structure on exec. The problem with the old approach is that the new limits would be inherited by child 64-bit processes, which has proven to be a significant POLA violation. Affected files ... .. //depot/projects/smpng/sys/amd64/linux32/linux32_sysvec.c#25 edit .. //depot/projects/smpng/sys/compat/ia32/ia32_sysvec.c#16 edit .. //depot/projects/smpng/sys/kern/imgact_elf.c#55 edit .. //depot/projects/smpng/sys/kern/kern_exec.c#104 edit .. //depot/projects/smpng/sys/kern/kern_resource.c#71 edit .. //depot/projects/smpng/sys/sys/sysent.h#26 edit Differences ... ==== //depot/projects/smpng/sys/amd64/linux32/linux32_sysvec.c#25 (text+ko) ==== @@ -119,7 +119,7 @@ static void linux_sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask); static void exec_linux_setregs(struct thread *td, u_long entry, u_long stack, u_long ps_strings); -static void linux32_fixlimits(struct proc *p); +static void linux32_fixlimit(struct rlimit *rl, int which); extern LIST_HEAD(futex_list, futex) futex_list; extern struct sx futex_sx; @@ -963,42 +963,36 @@ SYSCTL_ULONG(_compat_linux32, OID_AUTO, maxvmem, CTLFLAG_RW, &linux32_maxvmem, 0, ""); -/* - * XXX copied from ia32_sysvec.c. - */ static void -linux32_fixlimits(struct proc *p) +linux32_fixlimit(struct rlimit *rl, int which) { - struct plimit *oldlim, *newlim; - if (linux32_maxdsiz == 0 && linux32_maxssiz == 0 && - linux32_maxvmem == 0) - return; - newlim = lim_alloc(); - PROC_LOCK(p); - oldlim = p->p_limit; - lim_copy(newlim, oldlim); - if (linux32_maxdsiz != 0) { - if (newlim->pl_rlimit[RLIMIT_DATA].rlim_cur > linux32_maxdsiz) - newlim->pl_rlimit[RLIMIT_DATA].rlim_cur = linux32_maxdsiz; - if (newlim->pl_rlimit[RLIMIT_DATA].rlim_max > linux32_maxdsiz) - newlim->pl_rlimit[RLIMIT_DATA].rlim_max = linux32_maxdsiz; + switch (which) { + case RLIMIT_DATA: + if (linux32_maxdsiz != 0) { + if (rl->rlim_cur > linux32_maxdsiz) + rl->rlim_cur = linux32_maxdsiz; + if (rl->rlim_max > linux32_maxdsiz) + rl->rlim_max = linux32_maxdsiz; + } + break; + case RLIMIT_STACK: + if (linux32_maxssiz != 0) { + if (rl->rlim_cur > linux32_maxssiz) + rl->rlim_cur = linux32_maxssiz; + if (rl->rlim_max > linux32_maxssiz) + rl->rlim_max = linux32_maxssiz; + } + break; + case RLIMIT_VMEM: + if (linux32_maxvmem != 0) { + if (rl->rlim_cur > linux32_maxvmem) + rl->rlim_cur = linux32_maxvmem; + if (rl->rlim_max > linux32_maxvmem) + rl->rlim_max = linux32_maxvmem; + } + break; } - if (linux32_maxssiz != 0) { - if (newlim->pl_rlimit[RLIMIT_STACK].rlim_cur > linux32_maxssiz) - newlim->pl_rlimit[RLIMIT_STACK].rlim_cur = linux32_maxssiz; - if (newlim->pl_rlimit[RLIMIT_STACK].rlim_max > linux32_maxssiz) - newlim->pl_rlimit[RLIMIT_STACK].rlim_max = linux32_maxssiz; - } - if (linux32_maxvmem != 0) { - if (newlim->pl_rlimit[RLIMIT_VMEM].rlim_cur > linux32_maxvmem) - newlim->pl_rlimit[RLIMIT_VMEM].rlim_cur = linux32_maxvmem; - if (newlim->pl_rlimit[RLIMIT_VMEM].rlim_max > linux32_maxvmem) - newlim->pl_rlimit[RLIMIT_VMEM].rlim_max = linux32_maxvmem; - } - p->p_limit = newlim; - PROC_UNLOCK(p); - lim_free(oldlim); } struct sysentvec elf_linux_sysvec = { @@ -1027,7 +1021,7 @@ VM_PROT_ALL, linux_copyout_strings, exec_linux_setregs, - linux32_fixlimits + linux32_fixlimit }; static Elf32_Brandinfo linux_brand = { ==== //depot/projects/smpng/sys/compat/ia32/ia32_sysvec.c#16 (text+ko) ==== @@ -94,7 +94,7 @@ #endif static register_t *ia32_copyout_strings(struct image_params *imgp); -static void ia32_fixlimits(struct proc *p); +static void ia32_fixlimit(struct rlimit *rl, int which); extern struct sysent freebsd32_sysent[]; @@ -126,7 +126,7 @@ VM_PROT_ALL, ia32_copyout_strings, ia32_setregs, - ia32_fixlimits + ia32_fixlimit }; @@ -281,35 +281,33 @@ SYSCTL_ULONG(_compat_ia32, OID_AUTO, maxvmem, CTLFLAG_RW, &ia32_maxvmem, 0, ""); static void -ia32_fixlimits(struct proc *p) +ia32_fixlimit(struct rlimit *rl, int which) { - struct plimit *oldlim, *newlim; - if (ia32_maxdsiz == 0 && ia32_maxssiz == 0 && ia32_maxvmem == 0) - return; - newlim = lim_alloc(); - PROC_LOCK(p); - oldlim = p->p_limit; - lim_copy(newlim, oldlim); - if (ia32_maxdsiz != 0) { - if (newlim->pl_rlimit[RLIMIT_DATA].rlim_cur > ia32_maxdsiz) - newlim->pl_rlimit[RLIMIT_DATA].rlim_cur = ia32_maxdsiz; - if (newlim->pl_rlimit[RLIMIT_DATA].rlim_max > ia32_maxdsiz) - newlim->pl_rlimit[RLIMIT_DATA].rlim_max = ia32_maxdsiz; + switch (which) { + case RLIMIT_DATA: + if (ia32_maxdsiz != 0) { + if (rl->rlim_cur > ia32_maxdsiz) + rl->rlim_cur = ia32_maxdsiz; + if (rl->rlim_max > ia32_maxdsiz) + rl->rlim_max = ia32_maxdsiz; + } + break; + case RLIMIT_STACK: + if (ia32_maxssiz != 0) { + if (rl->rlim_cur > ia32_maxssiz) + rl->rlim_cur = ia32_maxssiz; + if (rl->rlim_max > ia32_maxssiz) + rl->rlim_max = ia32_maxssiz; + } + break; + case RLIMIT_VMEM: + if (ia32_maxvmem != 0) { + if (rl->rlim_cur > ia32_maxvmem) + rl->rlim_cur = ia32_maxvmem; + if (rl->rlim_max > ia32_maxvmem) + rl->rlim_max = ia32_maxvmem; + } + break; } - if (ia32_maxssiz != 0) { - if (newlim->pl_rlimit[RLIMIT_STACK].rlim_cur > ia32_maxssiz) - newlim->pl_rlimit[RLIMIT_STACK].rlim_cur = ia32_maxssiz; - if (newlim->pl_rlimit[RLIMIT_STACK].rlim_max > ia32_maxssiz) - newlim->pl_rlimit[RLIMIT_STACK].rlim_max = ia32_maxssiz; - } - if (ia32_maxvmem != 0) { - if (newlim->pl_rlimit[RLIMIT_VMEM].rlim_cur > ia32_maxvmem) - newlim->pl_rlimit[RLIMIT_VMEM].rlim_cur = ia32_maxvmem; - if (newlim->pl_rlimit[RLIMIT_VMEM].rlim_max > ia32_maxvmem) - newlim->pl_rlimit[RLIMIT_VMEM].rlim_max = ia32_maxvmem; - } - p->p_limit = newlim; - PROC_UNLOCK(p); - lim_free(oldlim); } ==== //depot/projects/smpng/sys/kern/imgact_elf.c#55 (text+ko) ==== @@ -667,6 +667,7 @@ VOP_UNLOCK(imgp->vp, 0, td); exec_new_vmspace(imgp, sv); + imgp->proc->p_sysent = sv; vn_lock(imgp->vp, LK_EXCLUSIVE | LK_RETRY, td); @@ -784,7 +785,6 @@ imgp->entry_addr = entry; - imgp->proc->p_sysent = sv; if (interp != NULL) { VOP_UNLOCK(imgp->vp, 0, td); if (brand_info->emul_path != NULL && ==== //depot/projects/smpng/sys/kern/kern_exec.c#104 (text+ko) ==== @@ -908,15 +908,6 @@ EVENTHANDLER_INVOKE(process_exec, p, imgp); /* - * Here is as good a place as any to do any resource limit cleanups. - * This is needed if a 64 bit binary exec's a 32 bit binary - the - * data size limit may need to be changed to a value that makes - * sense for the 32 bit binary. - */ - if (sv->sv_fixlimits != NULL) - sv->sv_fixlimits(p); - - /* * Blow away entire process VM, if address space not shared, * otherwise, create a new VM space so that other threads are * not disrupted ==== //depot/projects/smpng/sys/kern/kern_resource.c#71 (text+ko) ==== @@ -701,6 +701,8 @@ limp->rlim_max = 1; break; } + if (td->td_proc->p_sysent->sv_fixlimit != NULL) + td->td_proc->p_sysent->sv_fixlimit(limp, which); *alimp = *limp; p->p_limit = newlim; PROC_UNLOCK(p); @@ -734,12 +736,6 @@ } } - /* - * The data size limit may need to be changed to a value - * that makes sense for the 32 bit binary. - */ - if (p->p_sysent->sv_fixlimits != NULL) - p->p_sysent->sv_fixlimits(p); return (0); } @@ -1062,6 +1058,8 @@ KASSERT(which >= 0 && which < RLIM_NLIMITS, ("request for invalid resource limit")); *rlp = p->p_limit->pl_rlimit[which]; + if (p->p_sysent->sv_fixlimit != NULL) + p->p_sysent->sv_fixlimit(rlp, which); } /* ==== //depot/projects/smpng/sys/sys/sysent.h#26 (text+ko) ==== @@ -34,7 +34,7 @@ #include <bsm/audit.h> -struct proc; +struct rlimit; struct sysent; struct thread; struct ksiginfo; @@ -98,7 +98,7 @@ int sv_stackprot; /* vm protection for stack */ register_t *(*sv_copyout_strings)(struct image_params *); void (*sv_setregs)(struct thread *, u_long, u_long, u_long); - void (*sv_fixlimits)(struct proc *); + void (*sv_fixlimit)(struct rlimit *, int); }; #ifdef _KERNEL
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200705142151.l4ELpXvP068210>