svn commit: r239342 - in stable/8/sys: compat/freebsd32 kern sys vm

David E. O'Brien obrien at FreeBSD.org
Thu Aug 16 23:52:09 UTC 2012


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 <sys/mutex.h>
 #include <sys/proc.h>
 #include <sys/resourcevar.h>
+#include <sys/sysent.h>
 #include <sys/sysproto.h>
 #include <sys/systm.h>
 
@@ -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;


More information about the svn-src-stable mailing list