Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F144174623
D35349.id106731.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
10 KB
Referenced Files
None
Subscribers
None
D35349.id106731.diff
View Options
Index: sys/kern/imgact_elf.c
===================================================================
--- sys/kern/imgact_elf.c
+++ sys/kern/imgact_elf.c
@@ -209,6 +209,12 @@
__XSTRING(__CONCAT(ELF, __ELF_WORD_SIZE))
": enable stack address randomization");
+static int __elfN(aslr_shared_page) = __ELF_WORD_SIZE == 64;
+SYSCTL_INT(ASLR_NODE_OID, OID_AUTO, shared_page, CTLFLAG_RWTUN,
+ &__elfN(aslr_shared_page), 0,
+ __XSTRING(__CONCAT(ELF, __ELF_WORD_SIZE))
+ ": enable shared page address randomization");
+
static int __elfN(sigfastblock) = 1;
SYSCTL_INT(__CONCAT(_kern_elf, __ELF_WORD_SIZE), OID_AUTO, sigfastblock,
CTLFLAG_RWTUN, &__elfN(sigfastblock), 0,
@@ -1305,6 +1311,8 @@
imgp->map_flags |= MAP_ASLR_IGNSTART;
if (__elfN(aslr_stack))
imgp->map_flags |= MAP_ASLR_STACK;
+ if (__elfN(aslr_shared_page))
+ imgp->imgp_flags |= IMGP_ASLR_SHARED_PAGE;
}
if ((!__elfN(allow_wx) && (fctl0 & NT_FREEBSD_FCTL_WXNEEDED) == 0 &&
Index: sys/kern/kern_exec.c
===================================================================
--- sys/kern/kern_exec.c
+++ sys/kern/kern_exec.c
@@ -1110,8 +1110,7 @@
}
/*
- * Run down the current address space and install a new one. Map the shared
- * page.
+ * Run down the current address space and install a new one.
*/
int
exec_new_vmspace(struct image_params *imgp, struct sysentvec *sv)
@@ -1120,7 +1119,6 @@
struct proc *p = imgp->proc;
struct vmspace *vmspace = p->p_vmspace;
struct thread *td = curthread;
- vm_object_t obj;
vm_offset_t sv_minuser;
vm_map_t map;
@@ -1168,27 +1166,12 @@
}
map->flags |= imgp->map_flags;
- /* Map a shared page */
- obj = sv->sv_shared_page_obj;
- if (obj != NULL) {
- vm_object_reference(obj);
- error = vm_map_fixed(map, obj, 0,
- sv->sv_shared_page_base, sv->sv_shared_page_len,
- VM_PROT_READ | VM_PROT_EXECUTE,
- VM_PROT_READ | VM_PROT_EXECUTE,
- MAP_INHERIT_SHARE | MAP_ACC_NO_CHARGE);
- if (error != KERN_SUCCESS) {
- vm_object_deallocate(obj);
- return (vm_mmap_to_errno(error));
- }
- vmspace->vm_shp_base = sv->sv_shared_page_base;
- }
-
return (sv->sv_onexec != NULL ? sv->sv_onexec(p, imgp) : 0);
}
/*
* Compute the stack size limit and map the main process stack.
+ * Map the shared page.
*/
int
exec_map_stack(struct image_params *imgp)
@@ -1199,9 +1182,11 @@
vm_map_t map;
struct vmspace *vmspace;
vm_offset_t stack_addr, stack_top;
+ vm_offset_t sharedpage_addr;
u_long ssiz;
int error, find_space, stack_off;
vm_prot_t stack_prot;
+ vm_object_t obj;
p = imgp->proc;
sv = p->p_sysent;
@@ -1253,6 +1238,57 @@
stack_top -= rounddown2(stack_off & PAGE_MASK, sizeof(void *));
}
+ /* Map a shared page */
+ obj = sv->sv_shared_page_obj;
+ if (obj == NULL) {
+ sharedpage_addr = 0;
+ goto out;
+ }
+
+ sharedpage_addr = sv->sv_shared_page_base;
+ /*
+ * If randomization is disabled the vm logic maps it exactly
+ * to the specific address (VMFS_NO_SPACE).
+ * Otherwise it can choose any address above .data section.
+ * Same logic is used for stack address randomization.
+ * If the address randomization is applied map a guard page
+ * to the usual location of the shared page.
+ */
+ if ((imgp->imgp_flags & IMGP_ASLR_SHARED_PAGE) != 0) {
+ error = vm_map_find(map, NULL, 0,
+ &sharedpage_addr, sv->sv_shared_page_len,
+ sv->sv_maxuser, VMFS_NO_SPACE,
+ VM_PROT_NONE, VM_PROT_NONE, MAP_CREATE_GUARD);
+ if (error != KERN_SUCCESS) {
+ /*
+ * This is not fatal, so let's just print a warning
+ * and continue.
+ */
+ uprintf("%s: Mapping guard page at the usual location"
+ "of the shared page mach error %d errno %d",
+ __func__, error, vm_mmap_to_errno(error));
+ }
+ sharedpage_addr = round_page((vm_offset_t)p->p_vmspace->vm_daddr +
+ lim_max(curthread, RLIMIT_DATA));
+ find_space = VMFS_ANY_SPACE;
+ } else {
+ find_space = VMFS_NO_SPACE;
+ }
+ vm_object_reference(obj);
+ error = vm_map_find(map, obj, 0,
+ &sharedpage_addr, sv->sv_shared_page_len,
+ sv->sv_maxuser, find_space,
+ VM_PROT_READ | VM_PROT_EXECUTE,
+ VM_PROT_READ | VM_PROT_EXECUTE,
+ MAP_INHERIT_SHARE | MAP_ACC_NO_CHARGE);
+ if (error != KERN_SUCCESS) {
+ uprintf("%s: mapping shared page at addr: %p"
+ "failed, mach error %d errno %d\n", __func__,
+ (void *)sharedpage_addr, error, vm_mmap_to_errno(error));
+ vm_object_deallocate(obj);
+ return (vm_mmap_to_errno(error));
+ }
+out:
/*
* vm_ssize and vm_maxsaddr are somewhat antiquated concepts, but they
* are still used to enforce the stack rlimit on the process stack.
@@ -1260,6 +1296,7 @@
vmspace->vm_maxsaddr = (char *)stack_addr;
vmspace->vm_stacktop = stack_top;
vmspace->vm_ssize = sgrowsiz >> PAGE_SHIFT;
+ vmspace->vm_shp_base = sharedpage_addr;
return (0);
}
Index: sys/kern/kern_proc.c
===================================================================
--- sys/kern/kern_proc.c
+++ sys/kern/kern_proc.c
@@ -3245,6 +3245,9 @@
kvm.kvm_map_flags |= KMAP_FLAG_WXORX;
if ((vmspace->vm_map.flags & MAP_ASLR_STACK) != 0)
kvm.kvm_map_flags |= KMAP_FLAG_ASLR_STACK;
+ if (vmspace->vm_shp_base != p->p_sysent->sv_shared_page_base &&
+ PROC_HAS_SHP(p))
+ kvm.kvm_map_flags |= KMAP_FLAG_ASLR_SHARED_PAGE;
#ifdef COMPAT_FREEBSD32
if (SV_CURPROC_FLAG(SV_ILP32)) {
Index: sys/sys/imgact.h
===================================================================
--- sys/sys/imgact.h
+++ sys/sys/imgact.h
@@ -92,6 +92,8 @@
bool opened; /* we have opened executable vnode */
bool textset;
u_int map_flags;
+#define IMGP_ASLR_SHARED_PAGE 0x1
+ uint32_t imgp_flags;
};
#ifdef _KERNEL
Index: sys/sys/user.h
===================================================================
--- sys/sys/user.h
+++ sys/sys/user.h
@@ -625,6 +625,7 @@
#define KMAP_FLAG_ASLR_IGNSTART 0x04 /* ASLR may map into sbrk grow region */
#define KMAP_FLAG_WXORX 0x08 /* W^X mapping policy is enforced */
#define KMAP_FLAG_ASLR_STACK 0x10 /* the stack location is randomized */
+#define KMAP_FLAG_ASLR_SHARED_PAGE 0x20 /* the shared page location is randomized */
struct kinfo_vm_layout {
uintptr_t kvm_min_user_addr;
Index: tests/sys/kern/Makefile
===================================================================
--- tests/sys/kern/Makefile
+++ tests/sys/kern/Makefile
@@ -15,7 +15,6 @@
# No support for atomic_load_64 on i386 or (32-bit) powerpc
ATF_TESTS_C+= kcov
.endif
-ATF_TESTS_C+= kern_copyin
ATF_TESTS_C+= kern_descrip_test
ATF_TESTS_C+= fdgrowtable_test
ATF_TESTS_C+= kill_zombie
Index: tests/sys/kern/kern_copyin.c
===================================================================
--- tests/sys/kern/kern_copyin.c
+++ /dev/null
@@ -1,151 +0,0 @@
-/*-
- * Copyright (c) 2015, 2020 The FreeBSD Foundation
- * All rights reserved.
- *
- * This software was developed by Konstantin Belousov <kib@FreeBSD.org>
- * under sponsorship from the FreeBSD Foundation.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-#include <sys/param.h>
-#include <sys/exec.h>
-#include <sys/sysctl.h>
-#include <sys/user.h>
-
-#include <errno.h>
-#include <fcntl.h>
-#include <limits.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <atf-c.h>
-#include <vm/vm.h>
-#include <vm/pmap.h>
-#include <machine/vmparam.h>
-
-static int scratch_file;
-
-static int
-copyin_checker(uintptr_t uaddr, size_t len)
-{
- ssize_t ret;
-
- ret = write(scratch_file, (const void *)uaddr, len);
- return (ret == -1 ? errno : 0);
-}
-
-#if __SIZEOF_POINTER__ == 8
-/*
- * A slightly more direct path to calling copyin(), but without the ability
- * to specify a length.
- */
-static int
-copyin_checker2(uintptr_t uaddr)
-{
- int ret;
-
- ret = fcntl(scratch_file, F_GETLK, (const void *)uaddr);
- return (ret == -1 ? errno : 0);
-}
-#endif
-
-#ifdef __amd64__
-static uintptr_t
-get_maxuser_address(void)
-{
- struct kinfo_vm_layout kvm;
- size_t len;
- int error, mib[4];
-
- mib[0] = CTL_KERN;
- mib[1] = KERN_PROC;
- mib[2] = KERN_PROC_VM_LAYOUT;
- mib[3] = getpid();
- len = sizeof(kvm);
- error = sysctl(mib, nitems(mib), &kvm, &len, NULL, 0);
- if (error != 0)
- return (0);
-
- return (kvm.kvm_max_user_addr);
-}
-#endif
-
-#define FMAX ULONG_MAX
-#if __SIZEOF_POINTER__ == 8
-/* PR 257193 */
-#define ADDR_SIGNED 0x800000c000000000
-#endif
-
-ATF_TC_WITHOUT_HEAD(kern_copyin);
-ATF_TC_BODY(kern_copyin, tc)
-{
- char template[] = "copyin.XXXXXX";
- uintptr_t maxuser;
-
-#if defined(__mips__)
- /*
- * MIPS has different VM layout: the UVA map on mips ends the
- * highest mapped entry at the VM_MAXUSER_ADDRESS - PAGE_SIZE,
- * while all other arches map either stack or shared page up
- * to the VM_MAXUSER_ADDRESS.
- */
- maxuser = VM_MAXUSER_ADDRESS - PAGE_SIZE;
-#elif defined(__amd64__)
- maxuser = get_maxuser_address();
- ATF_REQUIRE(maxuser != 0);
-#else
- maxuser = VM_MAXUSER_ADDRESS;
-#endif
-
- scratch_file = mkstemp(template);
- ATF_REQUIRE(scratch_file != -1);
- unlink(template);
-
- ATF_CHECK(copyin_checker(0, 0) == 0);
- ATF_CHECK(copyin_checker(maxuser - 10, 9) == 0);
- ATF_CHECK(copyin_checker(maxuser - 10, 10) == 0);
- ATF_CHECK(copyin_checker(maxuser - 10, 11) == EFAULT);
- ATF_CHECK(copyin_checker(maxuser - 1, 1) == 0);
- ATF_CHECK(copyin_checker(maxuser, 0) == 0);
- ATF_CHECK(copyin_checker(maxuser, 1) == EFAULT);
- ATF_CHECK(copyin_checker(maxuser, 2) == EFAULT);
- ATF_CHECK(copyin_checker(maxuser + 1, 0) == 0);
- ATF_CHECK(copyin_checker(maxuser + 1, 2) == EFAULT);
- ATF_CHECK(copyin_checker(FMAX - 10, 9) == EFAULT);
- ATF_CHECK(copyin_checker(FMAX - 10, 10) == EFAULT);
- ATF_CHECK(copyin_checker(FMAX - 10, 11) == EFAULT);
-#if __SIZEOF_POINTER__ == 8
- ATF_CHECK(copyin_checker(ADDR_SIGNED, 1) == EFAULT);
- ATF_CHECK(copyin_checker2(ADDR_SIGNED) == EFAULT);
-#endif
-}
-
-ATF_TP_ADD_TCS(tp)
-{
-
- ATF_TP_ADD_TC(tp, kern_copyin);
- return (atf_no_error());
-}
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Fri, Feb 6, 11:13 PM (10 h, 2 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
28451233
Default Alt Text
D35349.id106731.diff (10 KB)
Attached To
Mode
D35349: [RFC] Shared page address randomization
Attached
Detach File
Event Timeline
Log In to Comment