aboutsummaryrefslogtreecommitdiff
path: root/kernel
diff options
context:
space:
mode:
authorAndrei Homescu <ahomescu@google.com>2022-01-25 03:35:17 +0000
committerAndrei Homescu <ahomescu@google.com>2022-02-02 00:59:00 +0000
commitdba26b57548799af73efb686d159bf4ab55236ab (patch)
treea6e5df2d7cccc66e64f7d89c0a4a9543cdd74dbc /kernel
parentd3220e29a3932cfe0e612b24b9df1f589a6bc298 (diff)
downloadcommon-dba26b57548799af73efb686d159bf4ab55236ab.tar.gz
[kernel][vm] Implement generic KASLR code
Implements the generic part of KASLR which randomly selects a load bias and shifts the virtual address of the kernel by that bias. Bug: 80147716 Change-Id: If25dbd1138a77009ce047400354943cd56e1e818
Diffstat (limited to 'kernel')
-rw-r--r--kernel/vm/aslr.c63
-rw-r--r--kernel/vm/rules.mk4
2 files changed, 67 insertions, 0 deletions
diff --git a/kernel/vm/aslr.c b/kernel/vm/aslr.c
new file mode 100644
index 00000000..41065f10
--- /dev/null
+++ b/kernel/vm/aslr.c
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2020 Google Inc. All rights reserved
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files
+ * (the "Software"), to deal in the Software without restriction,
+ * including without limitation the rights to use, copy, modify, merge,
+ * publish, distribute, sublicense, and/or sell copies of the Software,
+ * and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include <arch/defines.h>
+#include <arch/mmu.h>
+#include <assert.h>
+#include <endian.h>
+#include <inttypes.h>
+#include <kernel/vm.h>
+#include <lib/rand/rand.h>
+#include <trace.h>
+
+#define LOCAL_TRACE 0
+
+vaddr_t aslr_randomize_kernel_base(vaddr_t kernel_base) {
+ STATIC_ASSERT(!(KERNEL_ASPACE_BASE & (PAGE_SIZE - 1)));
+ STATIC_ASSERT(!(KERNEL_ASPACE_SIZE & (PAGE_SIZE - 1)));
+
+ struct mmu_initial_mapping* second_mapping = &mmu_initial_mappings[1];
+ if (second_mapping->size) {
+ LTRACEF("non-kernel mapping phys:0x%" PRIxPTR " virt:0x%" PRIxPTR
+ " size:%zu\n",
+ second_mapping->phys, second_mapping->virt,
+ second_mapping->size);
+ return kernel_base;
+ }
+
+ struct mmu_initial_mapping* kernel_mapping = mmu_initial_mappings;
+ kernel_base -= KERNEL_LOAD_OFFSET;
+ ASSERT(kernel_mapping->virt == kernel_base);
+ ASSERT(kernel_mapping->size);
+ ASSERT(!(kernel_mapping->size & (PAGE_SIZE - 1)));
+
+ const size_t aspace_pages = KERNEL_ASPACE_SIZE / PAGE_SIZE;
+ size_t kernel_pages = kernel_mapping->size / PAGE_SIZE;
+ /* Include 2 guard pages for the kernel */
+ kernel_pages += 2;
+ ASSERT(kernel_pages <= aspace_pages);
+
+ size_t pick = rand_get_size(aspace_pages - kernel_pages);
+ kernel_mapping->virt = KERNEL_ASPACE_BASE + ((1 + pick) * PAGE_SIZE);
+ return kernel_mapping->virt + KERNEL_LOAD_OFFSET;
+}
diff --git a/kernel/vm/rules.mk b/kernel/vm/rules.mk
index db338042..29ec29b6 100644
--- a/kernel/vm/rules.mk
+++ b/kernel/vm/rules.mk
@@ -11,6 +11,10 @@ MODULE_SRCS += \
$(LOCAL_DIR)/vm.c \
$(LOCAL_DIR)/vmm.c \
+ifeq ($(call TOBOOL,$(KERNEL_BASE_ASLR)), true)
+MODULE_SRCS += $(LOCAL_DIR)/aslr.c
+endif
+
MODULE_DEPS += \
lib/binary_search_tree \