summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKonstantin Belousov <kib@FreeBSD.org>2011-10-15 12:35:18 +0000
committerKonstantin Belousov <kib@FreeBSD.org>2011-10-15 12:35:18 +0000
commit126b36a21e95b0e34e5e138f80f0eb2bd2034bff (patch)
tree10ce3b912b307ff0aab5766c25781e0abda0ab10
parent2b6ae84b632d50cb1f3689e953c2e1a268abbad9 (diff)
Notes
-rw-r--r--sys/compat/freebsd32/freebsd32_misc.c4
-rw-r--r--sys/kern/imgact_elf.c10
-rw-r--r--sys/sys/sysent.h4
-rw-r--r--sys/vm/vm_unix.c2
4 files changed, 16 insertions, 4 deletions
diff --git a/sys/compat/freebsd32/freebsd32_misc.c b/sys/compat/freebsd32/freebsd32_misc.c
index 6638ec859ec6..fc2932b923ff 100644
--- a/sys/compat/freebsd32/freebsd32_misc.c
+++ b/sys/compat/freebsd32/freebsd32_misc.c
@@ -445,7 +445,7 @@ freebsd32_mprotect(struct thread *td, struct freebsd32_mprotect_args *uap)
ap.len = uap->len;
ap.prot = uap->prot;
#if defined(__amd64__) || defined(__ia64__)
- if (ap.prot & PROT_READ)
+ if (i386_read_exec && (ap.prot & PROT_READ) != 0)
ap.prot |= PROT_EXEC;
#endif
return (sys_mprotect(td, &ap));
@@ -536,7 +536,7 @@ freebsd32_mmap(struct thread *td, struct freebsd32_mmap_args *uap)
#endif
#if defined(__amd64__) || defined(__ia64__)
- if (prot & PROT_READ)
+ if (i386_read_exec && (prot & PROT_READ))
prot |= PROT_EXEC;
#endif
diff --git a/sys/kern/imgact_elf.c b/sys/kern/imgact_elf.c
index 669c652ba43c..8455f4854803 100644
--- a/sys/kern/imgact_elf.c
+++ b/sys/kern/imgact_elf.c
@@ -123,6 +123,14 @@ SYSCTL_INT(__CONCAT(_kern_elf, __ELF_WORD_SIZE), OID_AUTO,
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))
@@ -1666,7 +1674,7 @@ __elfN(trans_prot)(Elf_Word flags)
prot |= VM_PROT_READ;
#if __ELF_WORD_SIZE == 32
#if defined(__amd64__) || defined(__ia64__)
- if (flags & PF_R)
+ if (i386_read_exec && (flags & PF_R))
prot |= VM_PROT_EXECUTE;
#endif
#endif
diff --git a/sys/sys/sysent.h b/sys/sys/sysent.h
index 6a4b485ce29f..d916cf1388b9 100644
--- a/sys/sys/sysent.h
+++ b/sys/sys/sysent.h
@@ -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;
diff --git a/sys/vm/vm_unix.c b/sys/vm/vm_unix.c
index d4ea3b736da0..253ab775d8ba 100644
--- a/sys/vm/vm_unix.c
+++ b/sys/vm/vm_unix.c
@@ -141,7 +141,7 @@ sys_obreak(td, uap)
prot = VM_PROT_RW;
#ifdef COMPAT_FREEBSD32
#if defined(__amd64__) || defined(__ia64__)
- if (SV_PROC_FLAG(td->td_proc, SV_ILP32))
+ if (i386_read_exec && SV_PROC_FLAG(td->td_proc, SV_ILP32))
prot |= VM_PROT_EXECUTE;
#endif
#endif