Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 15 Jun 2012 10:38:15 +0000 (UTC)
From:      Konstantin Belousov <kib@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-9@freebsd.org
Subject:   svn commit: r237134 - in stable/9/sys: compat/freebsd32 kern sys vm
Message-ID:  <201206151038.q5FAcFts070560@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: kib
Date: Fri Jun 15 10:38:14 2012
New Revision: 237134
URL: http://svn.freebsd.org/changeset/base/237134

Log:
  MFC r226342 (by marcel):
  In elf32_trans_prot() and when compiling for amd64 or ia64, add
  PROT_EXECUTE when PROT_READ is needed. By default i386 allows
  execution when reading is allowed and JDK 1.4.x depends on that.
  
  MFC r226343 (by marcel):
  In sys_obreak() and when compiling for amd64 or ia64, when the process
  is ILP32 (i.e. i386) grant execute permissions by default. The JDK 1.4.x
  depends on being able to execute from the heap on i386.
  
  MFC r226347 (by marcel):
  In freebsd32_mmap() and when compiling for amd64 or ia64, also
  ask for execute permissions when read permissions are wanted.
  This is needed for JDK 1.4.x on i386.
  
  MFC r226348 (by marcel):
  Wrap mprotect(2).
  
  MFC r226349 (by marcel):
  Wrap mprotect(2) so that we can add execute permissions when read
  permissions are requested. This is needed on amd64 and ia64 for
  JDK 1.4.x.
  
  MFC r226353 (by marcel):
  Use PTRIN().
  
  MFC r226388:
  Control the execution permission of the readable segments for
  i386 binaries on the amd64 and ia64 with the sysctl, instead of
  unconditionally enabling it.
  
  MFC note: the syscall tables were regenerated in r226349 and committed
  together with changes to non-generated files. The merge includes
  syscall tables regenerated after the merge, for stable/9.

Modified:
  stable/9/sys/compat/freebsd32/freebsd32_misc.c
  stable/9/sys/compat/freebsd32/freebsd32_proto.h
  stable/9/sys/compat/freebsd32/freebsd32_syscall.h
  stable/9/sys/compat/freebsd32/freebsd32_syscalls.c
  stable/9/sys/compat/freebsd32/freebsd32_sysent.c
  stable/9/sys/compat/freebsd32/freebsd32_systrace_args.c
  stable/9/sys/compat/freebsd32/syscalls.master
  stable/9/sys/kern/imgact_elf.c
  stable/9/sys/sys/sysent.h
  stable/9/sys/vm/vm_unix.c
Directory Properties:
  stable/9/sys/   (props changed)

Modified: stable/9/sys/compat/freebsd32/freebsd32_misc.c
==============================================================================
--- stable/9/sys/compat/freebsd32/freebsd32_misc.c	Fri Jun 15 10:00:29 2012	(r237133)
+++ stable/9/sys/compat/freebsd32/freebsd32_misc.c	Fri Jun 15 10:38:14 2012	(r237134)
@@ -437,6 +437,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 (sys_mprotect(td, &ap));
+}
+
+int
 freebsd32_mmap(struct thread *td, struct freebsd32_mmap_args *uap)
 {
 	struct mmap_args ap;
@@ -520,6 +535,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/9/sys/compat/freebsd32/freebsd32_proto.h
==============================================================================
--- stable/9/sys/compat/freebsd32/freebsd32_proto.h	Fri Jun 15 10:00:29 2012	(r237133)
+++ stable/9/sys/compat/freebsd32/freebsd32_proto.h	Fri Jun 15 10:38:14 2012	(r237134)
@@ -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 *);
@@ -952,6 +958,7 @@ int	freebsd7_freebsd32_shmctl(struct thr
 #define	FREEBSD32_SYS_AUE_freebsd32_execve	AUE_EXECVE
 #define	FREEBSD32_SYS_AUE_ofreebsd32_fstat	AUE_FSTAT
 #define	FREEBSD32_SYS_AUE_ofreebsd32_getpagesize	AUE_NULL
+#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/9/sys/compat/freebsd32/freebsd32_syscall.h
==============================================================================
--- stable/9/sys/compat/freebsd32/freebsd32_syscall.h	Fri Jun 15 10:00:29 2012	(r237133)
+++ stable/9/sys/compat/freebsd32/freebsd32_syscall.h	Fri Jun 15 10:38:14 2012	(r237134)
@@ -80,7 +80,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/9/sys/compat/freebsd32/freebsd32_syscalls.c
==============================================================================
--- stable/9/sys/compat/freebsd32/freebsd32_syscalls.c	Fri Jun 15 10:00:29 2012	(r237133)
+++ stable/9/sys/compat/freebsd32/freebsd32_syscalls.c	Fri Jun 15 10:38:14 2012	(r237134)
@@ -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/9/sys/compat/freebsd32/freebsd32_sysent.c
==============================================================================
--- stable/9/sys/compat/freebsd32/freebsd32_sysent.c	Fri Jun 15 10:00:29 2012	(r237133)
+++ stable/9/sys/compat/freebsd32/freebsd32_sysent.c	Fri Jun 15 10:38:14 2012	(r237134)
@@ -121,7 +121,7 @@ struct sysent freebsd32_sysent[] = {
 	{ 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0, SY_THR_ABSENT },			/* 71 = obsolete ommap */
 	{ AS(ovadvise_args), (sy_call_t *)sys_ovadvise, AUE_O_VADVISE, NULL, 0, 0, 0, SY_THR_STATIC },	/* 72 = vadvise */
 	{ AS(munmap_args), (sy_call_t *)sys_munmap, AUE_MUNMAP, NULL, 0, 0, 0, SY_THR_STATIC },	/* 73 = munmap */
-	{ AS(mprotect_args), (sy_call_t *)sys_mprotect, AUE_MPROTECT, NULL, 0, 0, 0, SY_THR_STATIC },	/* 74 = mprotect */
+	{ AS(freebsd32_mprotect_args), (sy_call_t *)freebsd32_mprotect, AUE_MPROTECT, NULL, 0, 0, 0, SY_THR_STATIC },	/* 74 = freebsd32_mprotect */
 	{ AS(madvise_args), (sy_call_t *)sys_madvise, AUE_MADVISE, NULL, 0, 0, 0, SY_THR_STATIC },	/* 75 = madvise */
 	{ 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0, SY_THR_ABSENT },			/* 76 = obsolete vhangup */
 	{ 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0, SY_THR_ABSENT },			/* 77 = obsolete vlimit */

Modified: stable/9/sys/compat/freebsd32/freebsd32_systrace_args.c
==============================================================================
--- stable/9/sys/compat/freebsd32/freebsd32_systrace_args.c	Fri Jun 15 10:00:29 2012	(r237133)
+++ stable/9/sys/compat/freebsd32/freebsd32_systrace_args.c	Fri Jun 15 10:38:14 2012	(r237134)
@@ -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 */
@@ -3749,7 +3749,7 @@ systrace_setargdesc(int sysnum, int ndx,
 			break;
 		};
 		break;
-	/* mprotect */
+	/* freebsd32_mprotect */
 	case 74:
 		switch(ndx) {
 		case 0:

Modified: stable/9/sys/compat/freebsd32/syscalls.master
==============================================================================
--- stable/9/sys/compat/freebsd32/syscalls.master	Fri Jun 15 10:00:29 2012	(r237133)
+++ stable/9/sys/compat/freebsd32/syscalls.master	Fri Jun 15 10:38:14 2012	(r237134)
@@ -172,7 +172,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/9/sys/kern/imgact_elf.c
==============================================================================
--- stable/9/sys/kern/imgact_elf.c	Fri Jun 15 10:00:29 2012	(r237133)
+++ stable/9/sys/kern/imgact_elf.c	Fri Jun 15 10:38:14 2012	(r237134)
@@ -123,6 +123,14 @@ SYSCTL_INT(__CONCAT(_kern_elf, __ELF_WOR
     nxstack, CTLFLAG_RW, &__elfN(nxstack), 0,
     __XSTRING(__CONCAT(ELF, __ELF_WORD_SIZE)) ": enable non-executable stack");
 
+#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))
@@ -1671,6 +1679,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/9/sys/sys/sysent.h
==============================================================================
--- stable/9/sys/sys/sysent.h	Fri Jun 15 10:00:29 2012	(r237133)
+++ stable/9/sys/sys/sysent.h	Fri Jun 15 10:38:14 2012	(r237134)
@@ -151,6 +151,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/9/sys/vm/vm_unix.c
==============================================================================
--- stable/9/sys/vm/vm_unix.c	Fri Jun 15 10:00:29 2012	(r237133)
+++ stable/9/sys/vm/vm_unix.c	Fri Jun 15 10:38:14 2012	(r237134)
@@ -36,6 +36,8 @@
  *	@(#)vm_unix.c	8.1 (Berkeley) 6/11/93
  */
 
+#include "opt_compat.h"
+
 /*
  * Traditional sbrk/grow interface to VM
  */
@@ -49,6 +51,7 @@ __FBSDID("$FreeBSD$");
 #include <sys/proc.h>
 #include <sys/racct.h>
 #include <sys/resourcevar.h>
+#include <sys/sysent.h>
 #include <sys/sysproto.h>
 #include <sys/systm.h>
 
@@ -75,7 +78,7 @@ sys_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;
 
@@ -135,8 +138,15 @@ sys_obreak(td, uap)
 		}
 		PROC_UNLOCK(td->td_proc);
 #endif
+		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) {
 #ifdef RACCT
 			PROC_LOCK(td->td_proc);



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201206151038.q5FAcFts070560>