summaryrefslogtreecommitdiff
path: root/sys/uvm
diff options
context:
space:
mode:
authorKurt Miller <kurt@cvs.openbsd.org>2008-07-18 16:40:18 +0000
committerKurt Miller <kurt@cvs.openbsd.org>2008-07-18 16:40:18 +0000
commit9d741144290ccbc0fa7905a4b2359a24d7606fbd (patch)
treeaaf5480cc97ddb01e80b6498db6c60b3f8610427 /sys/uvm
parent98b4cba6a75c90bb5103f54759d0b1b7a886ed22 (diff)
Add new uvm function called uvm_map_pie() which takes align as a
parameter and returns an aligned random load address for position independent executables to use. This also adds three new vmparam.h defines to specify the maximum address, minimum address and minimum allowed alignment for uvm_map_pie() to use. The PIE address range for i386 was carefully selected to work well within the i386 W^X framework. With much help and feedback from weingart@. okay weingart@, miod@, kettenis@, drahn@
Diffstat (limited to 'sys/uvm')
-rw-r--r--sys/uvm/uvm_map.c41
-rw-r--r--sys/uvm/uvm_map.h3
2 files changed, 42 insertions, 2 deletions
diff --git a/sys/uvm/uvm_map.c b/sys/uvm/uvm_map.c
index a13a7ce92a6..338ec1fc99e 100644
--- a/sys/uvm/uvm_map.c
+++ b/sys/uvm/uvm_map.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: uvm_map.c,v 1.100 2008/06/09 20:30:23 miod Exp $ */
+/* $OpenBSD: uvm_map.c,v 1.101 2008/07/18 16:40:17 kurt Exp $ */
/* $NetBSD: uvm_map.c,v 1.86 2000/11/27 08:40:03 chs Exp $ */
/*
@@ -1100,6 +1100,45 @@ uvm_map_spacefits(struct vm_map *map, vaddr_t *phint, vsize_t length,
}
/*
+ * uvm_map_pie: return a random load address for a PIE executable
+ * properly aligned.
+ */
+
+#ifndef VM_PIE_MAX_ADDR
+#define VM_PIE_MAX_ADDR (VM_MAXUSER_ADDRESS / 4)
+#endif
+
+#ifndef VM_PIE_MIN_ADDR
+#define VM_PIE_MIN_ADDR VM_MIN_ADDRESS
+#endif
+
+#ifndef VM_PIE_MIN_ALIGN
+#define VM_PIE_MIN_ALIGN PAGE_SIZE
+#endif
+
+vaddr_t
+uvm_map_pie(vaddr_t align)
+{
+ vaddr_t addr, space, min;
+
+ align = MAX(align, VM_PIE_MIN_ALIGN);
+
+ /* round up to next alignment */
+ min = (VM_PIE_MIN_ADDR + align - 1) & ~(align - 1);
+
+ if (align >= VM_PIE_MAX_ADDR || min >= VM_PIE_MAX_ADDR)
+ return (align);
+
+ space = (VM_PIE_MAX_ADDR - min) / align;
+ space = MIN(space, (u_int32_t)-1);
+
+ addr = (vaddr_t)arc4random_uniform((u_int32_t)space) * align;
+ addr += min;
+
+ return (addr);
+}
+
+/*
* uvm_map_hint: return the beginning of the best area suitable for
* creating a new mapping with "prot" protection.
*/
diff --git a/sys/uvm/uvm_map.h b/sys/uvm/uvm_map.h
index 5ed91a71a72..456f9a5e516 100644
--- a/sys/uvm/uvm_map.h
+++ b/sys/uvm/uvm_map.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: uvm_map.h,v 1.38 2007/04/11 12:10:42 art Exp $ */
+/* $OpenBSD: uvm_map.h,v 1.39 2008/07/18 16:40:17 kurt Exp $ */
/* $NetBSD: uvm_map.h,v 1.24 2001/02/18 21:19:08 chs Exp $ */
/*
@@ -294,6 +294,7 @@ int uvm_map_extract(vm_map_t, vaddr_t, vsize_t,
vm_map_t, vaddr_t *, int);
vm_map_entry_t uvm_map_findspace(vm_map_t, vaddr_t, vsize_t, vaddr_t *,
struct uvm_object *, voff_t, vsize_t, int);
+vaddr_t uvm_map_pie(vaddr_t);
vaddr_t uvm_map_hint(struct proc *, vm_prot_t);
int uvm_map_inherit(vm_map_t, vaddr_t, vaddr_t, vm_inherit_t);
int uvm_map_advice(vm_map_t, vaddr_t, vaddr_t, int);