From owner-svn-src-stable@FreeBSD.ORG Thu Aug 16 23:52:09 2012 Return-Path: Delivered-To: svn-src-stable@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [69.147.83.52]) by hub.freebsd.org (Postfix) with ESMTP id 0CE46106566C; Thu, 16 Aug 2012 23:52:09 +0000 (UTC) (envelope-from obrien@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id E0C6D8FC12; Thu, 16 Aug 2012 23:52:08 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.4/8.14.4) with ESMTP id q7GNq881087099; Thu, 16 Aug 2012 23:52:08 GMT (envelope-from obrien@svn.freebsd.org) Received: (from obrien@localhost) by svn.freebsd.org (8.14.4/8.14.4/Submit) id q7GNq8RK087088; Thu, 16 Aug 2012 23:52:08 GMT (envelope-from obrien@svn.freebsd.org) Message-Id: <201208162352.q7GNq8RK087088@svn.freebsd.org> From: "David E. O'Brien" Date: Thu, 16 Aug 2012 23:52:08 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-8@freebsd.org X-SVN-Group: stable-8 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r239342 - in stable/8/sys: compat/freebsd32 kern sys vm X-BeenThere: svn-src-stable@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: SVN commit messages for all the -stable branches of the src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 16 Aug 2012 23:52:09 -0000 Author: obrien Date: Thu Aug 16 23:52:08 2012 New Revision: 239342 URL: http://svn.freebsd.org/changeset/base/239342 Log: MF9: r237134 MFC r226342, r226343, r226347, r226348, r226349, r226353, r226388 When building for amd64 or ia64, add the "kern.elf32.read_exec" sysctl to enable PROT_EXECUTE for elf32 binaries when reading is allowed. The JDK 1.4.x requires the ability to execute in the heap. Modified: stable/8/sys/compat/freebsd32/freebsd32_misc.c stable/8/sys/compat/freebsd32/freebsd32_proto.h stable/8/sys/compat/freebsd32/freebsd32_syscall.h stable/8/sys/compat/freebsd32/freebsd32_syscalls.c stable/8/sys/compat/freebsd32/freebsd32_sysent.c stable/8/sys/compat/freebsd32/freebsd32_systrace_args.c stable/8/sys/compat/freebsd32/syscalls.master stable/8/sys/kern/imgact_elf.c stable/8/sys/sys/sysent.h stable/8/sys/vm/vm_unix.c Directory Properties: stable/8/ (props changed) stable/8/sys/ (props changed) stable/8/sys/compat/ (props changed) stable/8/sys/kern/ (props changed) stable/8/sys/sys/ (props changed) stable/8/sys/vm/ (props changed) Modified: stable/8/sys/compat/freebsd32/freebsd32_misc.c ============================================================================== --- stable/8/sys/compat/freebsd32/freebsd32_misc.c Thu Aug 16 22:33:56 2012 (r239341) +++ stable/8/sys/compat/freebsd32/freebsd32_misc.c Thu Aug 16 23:52:08 2012 (r239342) @@ -440,6 +440,21 @@ freebsd32_mmap_partial(struct thread *td #endif int +freebsd32_mprotect(struct thread *td, struct freebsd32_mprotect_args *uap) +{ + struct mprotect_args ap; + + ap.addr = PTRIN(uap->addr); + ap.len = uap->len; + ap.prot = uap->prot; +#if defined(__amd64__) || defined(__ia64__) + if (i386_read_exec && (ap.prot & PROT_READ) != 0) + ap.prot |= PROT_EXEC; +#endif + return (mprotect(td, &ap)); +} + +int freebsd32_mmap(struct thread *td, struct freebsd32_mmap_args *uap) { struct mmap_args ap; @@ -523,6 +538,11 @@ freebsd32_mmap(struct thread *td, struct } #endif +#if defined(__amd64__) || defined(__ia64__) + if (i386_read_exec && (prot & PROT_READ)) + prot |= PROT_EXEC; +#endif + ap.addr = (void *) addr; ap.len = len; ap.prot = prot; Modified: stable/8/sys/compat/freebsd32/freebsd32_proto.h ============================================================================== --- stable/8/sys/compat/freebsd32/freebsd32_proto.h Thu Aug 16 22:33:56 2012 (r239341) +++ stable/8/sys/compat/freebsd32/freebsd32_proto.h Thu Aug 16 23:52:08 2012 (r239342) @@ -76,6 +76,11 @@ struct freebsd32_execve_args { char argv_l_[PADL_(u_int32_t *)]; u_int32_t * argv; char argv_r_[PADR_(u_int32_t *)]; char envv_l_[PADL_(u_int32_t *)]; u_int32_t * envv; char envv_r_[PADR_(u_int32_t *)]; }; +struct freebsd32_mprotect_args { + char addr_l_[PADL_(const void *)]; const void * addr; char addr_r_[PADR_(const void *)]; + char len_l_[PADL_(size_t)]; size_t len; char len_r_[PADR_(size_t)]; + char prot_l_[PADL_(int)]; int prot; char prot_r_[PADR_(int)]; +}; struct freebsd32_setitimer_args { char which_l_[PADL_(u_int)]; u_int which; char which_r_[PADR_(u_int)]; char itv_l_[PADL_(struct itimerval32 *)]; struct itimerval32 * itv; char itv_r_[PADR_(struct itimerval32 *)]; @@ -593,6 +598,7 @@ int freebsd32_recvfrom(struct thread *, int freebsd32_sigaltstack(struct thread *, struct freebsd32_sigaltstack_args *); int freebsd32_ioctl(struct thread *, struct freebsd32_ioctl_args *); int freebsd32_execve(struct thread *, struct freebsd32_execve_args *); +int freebsd32_mprotect(struct thread *, struct freebsd32_mprotect_args *); int freebsd32_setitimer(struct thread *, struct freebsd32_setitimer_args *); int freebsd32_getitimer(struct thread *, struct freebsd32_getitimer_args *); int freebsd32_select(struct thread *, struct freebsd32_select_args *); @@ -911,6 +917,7 @@ int freebsd7_freebsd32_shmctl(struct thr #define FREEBSD32_SYS_AUE_freebsd32_sigaltstack AUE_SIGALTSTACK #define FREEBSD32_SYS_AUE_freebsd32_ioctl AUE_NULL #define FREEBSD32_SYS_AUE_freebsd32_execve AUE_EXECVE +#define FREEBSD32_SYS_AUE_freebsd32_mprotect AUE_MPROTECT #define FREEBSD32_SYS_AUE_freebsd32_setitimer AUE_SETITIMER #define FREEBSD32_SYS_AUE_freebsd32_getitimer AUE_GETITIMER #define FREEBSD32_SYS_AUE_freebsd32_select AUE_SELECT Modified: stable/8/sys/compat/freebsd32/freebsd32_syscall.h ============================================================================== --- stable/8/sys/compat/freebsd32/freebsd32_syscall.h Thu Aug 16 22:33:56 2012 (r239341) +++ stable/8/sys/compat/freebsd32/freebsd32_syscall.h Thu Aug 16 23:52:08 2012 (r239342) @@ -78,7 +78,7 @@ /* 71 is obsolete ommap */ #define FREEBSD32_SYS_vadvise 72 #define FREEBSD32_SYS_munmap 73 -#define FREEBSD32_SYS_mprotect 74 +#define FREEBSD32_SYS_freebsd32_mprotect 74 #define FREEBSD32_SYS_madvise 75 /* 76 is obsolete vhangup */ /* 77 is obsolete vlimit */ Modified: stable/8/sys/compat/freebsd32/freebsd32_syscalls.c ============================================================================== --- stable/8/sys/compat/freebsd32/freebsd32_syscalls.c Thu Aug 16 22:33:56 2012 (r239341) +++ stable/8/sys/compat/freebsd32/freebsd32_syscalls.c Thu Aug 16 23:52:08 2012 (r239342) @@ -84,7 +84,7 @@ const char *freebsd32_syscallnames[] = { "obs_ommap", /* 71 = obsolete ommap */ "vadvise", /* 72 = vadvise */ "munmap", /* 73 = munmap */ - "mprotect", /* 74 = mprotect */ + "freebsd32_mprotect", /* 74 = freebsd32_mprotect */ "madvise", /* 75 = madvise */ "obs_vhangup", /* 76 = obsolete vhangup */ "obs_vlimit", /* 77 = obsolete vlimit */ Modified: stable/8/sys/compat/freebsd32/freebsd32_sysent.c ============================================================================== --- stable/8/sys/compat/freebsd32/freebsd32_sysent.c Thu Aug 16 22:33:56 2012 (r239341) +++ stable/8/sys/compat/freebsd32/freebsd32_sysent.c Thu Aug 16 23:52:08 2012 (r239342) @@ -121,7 +121,7 @@ struct sysent freebsd32_sysent[] = { { 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0 }, /* 71 = obsolete ommap */ { AS(ovadvise_args), (sy_call_t *)ovadvise, AUE_O_VADVISE, NULL, 0, 0, 0 }, /* 72 = vadvise */ { AS(munmap_args), (sy_call_t *)munmap, AUE_MUNMAP, NULL, 0, 0, 0 }, /* 73 = munmap */ - { AS(mprotect_args), (sy_call_t *)mprotect, AUE_MPROTECT, NULL, 0, 0, 0 }, /* 74 = mprotect */ + { AS(freebsd32_mprotect_args), (sy_call_t *)freebsd32_mprotect, AUE_MPROTECT, NULL, 0, 0, 0 }, /* 74 = freebsd32_mprotect */ { AS(madvise_args), (sy_call_t *)madvise, AUE_MADVISE, NULL, 0, 0, 0 }, /* 75 = madvise */ { 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0 }, /* 76 = obsolete vhangup */ { 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0 }, /* 77 = obsolete vlimit */ Modified: stable/8/sys/compat/freebsd32/freebsd32_systrace_args.c ============================================================================== --- stable/8/sys/compat/freebsd32/freebsd32_systrace_args.c Thu Aug 16 22:33:56 2012 (r239341) +++ stable/8/sys/compat/freebsd32/freebsd32_systrace_args.c Thu Aug 16 23:52:08 2012 (r239342) @@ -464,9 +464,9 @@ systrace_args(int sysnum, void *params, *n_args = 2; break; } - /* mprotect */ + /* freebsd32_mprotect */ case 74: { - struct mprotect_args *p = params; + struct freebsd32_mprotect_args *p = params; uarg[0] = (intptr_t) p->addr; /* const void * */ uarg[1] = p->len; /* size_t */ iarg[2] = p->prot; /* int */ @@ -3656,7 +3656,7 @@ systrace_entry_setargdesc(int sysnum, in break; }; break; - /* mprotect */ + /* freebsd32_mprotect */ case 74: switch(ndx) { case 0: @@ -8156,7 +8156,7 @@ systrace_return_setargdesc(int sysnum, i if (ndx == 0 || ndx == 1) p = "int"; break; - /* mprotect */ + /* freebsd32_mprotect */ case 74: if (ndx == 0 || ndx == 1) p = "int"; Modified: stable/8/sys/compat/freebsd32/syscalls.master ============================================================================== --- stable/8/sys/compat/freebsd32/syscalls.master Thu Aug 16 22:33:56 2012 (r239341) +++ stable/8/sys/compat/freebsd32/syscalls.master Thu Aug 16 23:52:08 2012 (r239342) @@ -168,7 +168,7 @@ 72 AUE_O_VADVISE NOPROTO { int ovadvise(int anom); } vadvise \ ovadvise_args int 73 AUE_MUNMAP NOPROTO { int munmap(void *addr, size_t len); } -74 AUE_MPROTECT NOPROTO { int mprotect(const void *addr, \ +74 AUE_MPROTECT STD { int freebsd32_mprotect(const void *addr, \ size_t len, int prot); } 75 AUE_MADVISE NOPROTO { int madvise(void *addr, size_t len, \ int behav); } Modified: stable/8/sys/kern/imgact_elf.c ============================================================================== --- stable/8/sys/kern/imgact_elf.c Thu Aug 16 22:33:56 2012 (r239341) +++ stable/8/sys/kern/imgact_elf.c Thu Aug 16 23:52:08 2012 (r239342) @@ -103,6 +103,14 @@ static int elf_legacy_coredump = 0; SYSCTL_INT(_debug, OID_AUTO, __elfN(legacy_coredump), CTLFLAG_RW, &elf_legacy_coredump, 0, ""); +#if __ELF_WORD_SIZE == 32 +#if defined(__amd64__) || defined(__ia64__) +int i386_read_exec = 0; +SYSCTL_INT(_kern_elf32, OID_AUTO, read_exec, CTLFLAG_RW, &i386_read_exec, 0, + "enable execution from readable segments"); +#endif +#endif + static Elf_Brandinfo *elf_brand_list[MAX_BRANDS]; #define trunc_page_ps(va, ps) ((va) & ~(ps - 1)) @@ -1495,6 +1503,12 @@ __elfN(trans_prot)(Elf_Word flags) prot |= VM_PROT_WRITE; if (flags & PF_R) prot |= VM_PROT_READ; +#if __ELF_WORD_SIZE == 32 +#if defined(__amd64__) || defined(__ia64__) + if (i386_read_exec && (flags & PF_R)) + prot |= VM_PROT_EXECUTE; +#endif +#endif return (prot); } Modified: stable/8/sys/sys/sysent.h ============================================================================== --- stable/8/sys/sys/sysent.h Thu Aug 16 22:33:56 2012 (r239341) +++ stable/8/sys/sys/sysent.h Thu Aug 16 23:52:08 2012 (r239342) @@ -133,6 +133,10 @@ extern struct sysentvec null_sysvec; extern struct sysent sysent[]; extern const char *syscallnames[]; +#if defined(__amd64__) || defined(__ia64__) +extern int i386_read_exec; +#endif + #define NO_SYSCALL (-1) struct module; Modified: stable/8/sys/vm/vm_unix.c ============================================================================== --- stable/8/sys/vm/vm_unix.c Thu Aug 16 22:33:56 2012 (r239341) +++ stable/8/sys/vm/vm_unix.c Thu Aug 16 23:52:08 2012 (r239342) @@ -36,6 +36,8 @@ * @(#)vm_unix.c 8.1 (Berkeley) 6/11/93 */ +#include "opt_compat.h" + /* * Traditional sbrk/grow interface to VM */ @@ -48,6 +50,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include @@ -74,7 +77,7 @@ obreak(td, uap) struct vmspace *vm = td->td_proc->p_vmspace; vm_offset_t new, old, base; rlim_t datalim, vmemlim; - int rv; + int prot, rv; int error = 0; boolean_t do_map_wirefuture; @@ -116,8 +119,15 @@ obreak(td, uap) error = ENOMEM; goto done; } + prot = VM_PROT_RW; +#ifdef COMPAT_FREEBSD32 +#if defined(__amd64__) || defined(__ia64__) + if (i386_read_exec && SV_PROC_FLAG(td->td_proc, SV_ILP32)) + prot |= VM_PROT_EXECUTE; +#endif +#endif rv = vm_map_insert(&vm->vm_map, NULL, 0, old, new, - VM_PROT_RW, VM_PROT_ALL, 0); + prot, VM_PROT_ALL, 0); if (rv != KERN_SUCCESS) { error = ENOMEM; goto done;