Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F173795387
D56711.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
4 KB
Referenced Files
None
Subscribers
None
D56711.diff
View Options
diff --git a/sys/kern/kern_exec.c b/sys/kern/kern_exec.c
--- a/sys/kern/kern_exec.c
+++ b/sys/kern/kern_exec.c
@@ -1435,7 +1435,8 @@
mtx_init(&exec_args_kva_mtx, "exec args kva", NULL, MTX_DEF);
for (i = 0; i < exec_map_entries; i++) {
argkva = malloc(sizeof(*argkva), M_PARGS, M_WAITOK);
- argkva->addr = kmap_alloc_wait(exec_map, exec_map_entry_size);
+ argkva->addr = kmap_alloc_wait(exec_map, exec_map_entry_size,
+ ptoa(exec_map_guard_pages));
argkva->gen = exec_args_gen;
SLIST_INSERT_HEAD(&exec_args_kva_freelist, argkva, next);
}
diff --git a/sys/vm/vm_extern.h b/sys/vm/vm_extern.h
--- a/sys/vm/vm_extern.h
+++ b/sys/vm/vm_extern.h
@@ -51,7 +51,7 @@
void kva_free(void *, vm_size_t);
/* These operate on pageable virtual addresses. */
-void *kmap_alloc_wait(vm_map_t, vm_size_t);
+void *kmap_alloc_wait(vm_map_t, vm_size_t, vm_size_t);
void kmap_free_wakeup(vm_map_t, void *, vm_size_t);
/* These operate on virtual addresses backed by memory. */
diff --git a/sys/vm/vm_init.c b/sys/vm/vm_init.c
--- a/sys/vm/vm_init.c
+++ b/sys/vm/vm_init.c
@@ -274,8 +274,12 @@
exec_map_entries = 2 * mp_ncpus + 4;
#endif
exec_map_entry_size = round_page(PATH_MAX + ARG_MAX);
- kmem_subinit(exec_map, kernel_map, &minaddr, &maxaddr,
- exec_map_entries * exec_map_entry_size + 64 * PAGE_SIZE, false);
+ exec_map_guard_pages = 1;
+ TUNABLE_INT_FETCH("vm.exec_map_guard_pages", &exec_map_guard_pages);
+ size = exec_map_entries *
+ (exec_map_entry_size + 2 * ptoa(exec_map_guard_pages)) +
+ 64 * PAGE_SIZE;
+ kmem_subinit(exec_map, kernel_map, &minaddr, &maxaddr, size, false);
kmem_subinit(pipe_map, kernel_map, &minaddr, &maxaddr, maxpipekva,
false);
TSEXIT();
diff --git a/sys/vm/vm_kern.h b/sys/vm/vm_kern.h
--- a/sys/vm/vm_kern.h
+++ b/sys/vm/vm_kern.h
@@ -75,4 +75,5 @@
extern u_long vm_kmem_size;
extern u_int exec_map_entries;
extern u_int exec_map_entry_size;
+extern u_int exec_map_guard_pages;
#endif /* _VM_VM_KERN_H_ */
diff --git a/sys/vm/vm_kern.c b/sys/vm/vm_kern.c
--- a/sys/vm/vm_kern.c
+++ b/sys/vm/vm_kern.c
@@ -107,6 +107,7 @@
const u_long vm_maxuser_address = VM_MAXUSER_ADDRESS;
u_int exec_map_entry_size;
+u_int exec_map_guard_pages;
u_int exec_map_entries;
SYSCTL_ULONG(_vm, OID_AUTO, min_kernel_address, CTLFLAG_RD,
@@ -706,34 +707,52 @@
vmem_free(arena, (uintptr_t)addr, size);
}
+static void
+kmap_alloc_map(vm_map_t map, vm_offset_t addr, vm_size_t size,
+ vm_prot_t prot, int flags)
+{
+ int error __diagused;
+
+ error = vm_map_insert(map, NULL, 0,
+ addr, addr + size, prot, prot, flags);
+ KASSERT(error == KERN_SUCCESS,
+ ("%s: unexpected error %d", __func__, error));
+}
+
/*
* kmap_alloc_wait:
*
* Allocates pageable memory from a sub-map of the kernel. If the submap
* has no room, the caller sleeps waiting for more memory in the submap.
+ * If "guard_size" is non-zero, then unmapped KVA is left at the beginning
+ * and end of the allocated range.
*
* This routine may block.
*/
void *
-kmap_alloc_wait(vm_map_t map, vm_size_t size)
+kmap_alloc_wait(vm_map_t map, vm_size_t size, vm_size_t guard_size)
{
vm_offset_t addr;
+ vm_size_t total_size;
+
+ KASSERT(size % PAGE_SIZE == 0 && guard_size % PAGE_SIZE == 0,
+ ("%s: size %zu guard_size %zu", __func__, size, guard_size));
- size = round_page(size);
if (!swap_reserve(size))
return (NULL);
+ total_size = size + 2 * guard_size;
for (;;) {
/*
* To make this work for more than one map, use the map's lock
* to lock out sleepers/wakers.
*/
vm_map_lock(map);
- addr = vm_map_findspace(map, vm_map_min(map), size);
- if (addr + size <= vm_map_max(map))
+ addr = vm_map_findspace(map, vm_map_min(map), total_size);
+ if (addr + total_size <= vm_map_max(map))
break;
/* no space now; see if we can ever get space */
- if (vm_map_max(map) - vm_map_min(map) < size) {
+ if (vm_map_max(map) - vm_map_min(map) < total_size) {
vm_map_unlock(map);
swap_release(size);
return (0);
@@ -741,10 +760,16 @@
vm_map_modflags(map, MAP_NEEDS_WAKEUP, 0);
vm_map_unlock_and_wait(map, 0);
}
- vm_map_insert(map, NULL, 0, addr, addr + size, VM_PROT_RW, VM_PROT_RW,
+ if (guard_size != 0) {
+ kmap_alloc_map(map, addr, guard_size,
+ VM_PROT_NONE, MAP_CREATE_GUARD);
+ kmap_alloc_map(map, addr + guard_size + size, guard_size,
+ VM_PROT_NONE, MAP_CREATE_GUARD);
+ }
+ kmap_alloc_map(map, addr + guard_size, size, VM_PROT_RW,
MAP_ACC_CHARGED);
vm_map_unlock(map);
- return ((void *)addr);
+ return ((void *)(addr + guard_size));
}
/*
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Tue, Sep 29, 12:00 PM (7 h, 11 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
39874781
Default Alt Text
D56711.diff (4 KB)
Attached To
Mode
D56711: execve: Add guard pages around execve KVA buffers
Attached
Detach File
Event Timeline
Log In to Comment