Index: src/trusted/service_runtime/arch/mips/sel_addrspace_mips.c |
diff --git a/src/trusted/service_runtime/arch/mips/sel_addrspace_mips.c b/src/trusted/service_runtime/arch/mips/sel_addrspace_mips.c |
new file mode 100644 |
index 0000000000000000000000000000000000000000..d91e6c90dcfec80e5d794b572f7f6673c0e7b1db |
--- /dev/null |
+++ b/src/trusted/service_runtime/arch/mips/sel_addrspace_mips.c |
@@ -0,0 +1,134 @@ |
+/* |
+ * Copyright 2012 The Native Client Authors. All rights reserved. |
+ * Use of this source code is governed by a BSD-style license that can |
+ * be found in the LICENSE file. |
+ */ |
+ |
+#include "native_client/src/include/nacl_platform.h" |
+#include "native_client/src/shared/platform/nacl_check.h" |
+#include "native_client/src/trusted/service_runtime/arch/sel_ldr_arch.h" |
+#include "native_client/src/trusted/service_runtime/nacl_error_code.h" |
+#include "native_client/src/trusted/service_runtime/sel_addrspace.h" |
+#include "native_client/src/trusted/service_runtime/sel_ldr.h" |
+#include "native_client/src/trusted/service_runtime/sel_memory.h" |
+ |
+ |
+/* NOTE: This routine is almost identical to the x86_32 version. |
+ */ |
+NaClErrorCode NaClAllocateSpace(void **mem, size_t addrsp_size) { |
+ int result; |
+ void *tmp_mem = (void *) NACL_TRAMPOLINE_START; |
+ |
+ CHECK(NULL != mem); |
+ |
+ /* |
+ * On Mips, we also cheat slightly: we add two pages to the requested |
+ * allocation! This accomodates the guard region we require at the |
+ * top end of untrusted memory. |
+ */ |
+ addrsp_size += NACL_ADDRSPACE_UPPER_GUARD_SIZE; |
+ |
+ NaClAddrSpaceBeforeAlloc(addrsp_size); |
+ |
+ /* |
+ * On 32 bit Linux, a 1 gigabyte block of address space may be reserved at |
+ * the zero-end of the address space during process creation, to address |
+ * sandbox layout requirements on Mips and performance issues on Intel ATOM. |
+ * Look for this pre-reserved block and if found, pass its address to the |
+ * page allocation function. |
+ */ |
+ if (!NaClFindPrereservedSandboxMemory(mem, addrsp_size)) { |
+ /* On Mips, we should always have prereserved sandbox memory. */ |
+ NaClLog(LOG_ERROR, "NaClAllocateSpace:" |
+ " Could not find correct amount of prereserved memory" |
+ " (looked for 0x%016"NACL_PRIxS" bytes).\n", |
+ addrsp_size); |
+ return LOAD_NO_MEMORY; |
+ } |
+ |
+ /* |
+ * When creating a zero-based sandbox, we do not allocate the first 64K of |
+ * pages beneath the trampolines, because -- on Linux at least -- we cannot. |
+ * Instead, we allocate starting at the trampolines, and then coerce the |
+ * "mem" out parameter. |
+ */ |
+ CHECK(*mem == NULL); |
+ addrsp_size -= NACL_TRAMPOLINE_START; |
+ result = NaCl_page_alloc_at_addr(&tmp_mem, addrsp_size); |
+ |
+ if (0 != result) { |
+ NaClLog(2, |
+ "NaClAllocateSpace: NaCl_page_alloc_at_addr 0x%08"NACL_PRIxPTR |
+ " failed\n", |
+ (uintptr_t) tmp_mem); |
+ return LOAD_NO_MEMORY; |
+ } |
+ NaClLog(4, "NaClAllocateSpace: %"NACL_PRIxPTR", %"NACL_PRIxS"\n", |
+ (uintptr_t) *mem, |
+ addrsp_size); |
+ |
+ return LOAD_OK; |
+} |
+ |
+/* |
+ * In the Mips sandboxing scheme we put the NaCl module at low virtual |
+ * address -- and thus there can only ever be one running NaCl app per |
+ * sel_ldr process -- to simplify the address masking etc needed for |
+ * the sandboxing. All memory below ((uintptr_t) 1) << nap->addr_bits |
+ * is accessible to the NaCl app, and modulo page protection, |
+ * potentially writable. Page protection is, of course, used to |
+ * prevent writing to text and rodata, including the trusted |
+ * trampoline code thunks. To simplify write sandboxing, some |
+ * additional guard pages outside of the address space is needed, so |
+ * that we don't have to additionally check the effective address |
+ * obtained by register-relative addressing modes. |
+ */ |
+NaClErrorCode NaClMprotectGuards(struct NaClApp *nap) { |
Mark Seaborn
2012/09/08 02:43:14
This is gone from the ARM version. Please remove
petarj
2012/09/11 16:58:13
Done.
|
+ int err; |
+ void *guard_base = (void *) (((uintptr_t) 1) << nap->addr_bits); |
+ /* |
+ * In Mips implementation kernel does not allow us to mmap address space at |
+ * address 0x0, so we mmap it at the start of a trampoline region. |
+ * Therefore, there is not need to mprotect at the start_addr. |
+ * |
+ * However, we do create a vmmap entry to describe it. |
+ */ |
+ NaClLog(3, |
+ ("NULL detection region start 0x%08"NACL_PRIxPTR", " |
+ "size 0x%08x, end 0x%08"NACL_PRIxPTR"\n"), |
+ 0, NACL_SYSCALL_START_ADDR, |
+ NACL_SYSCALL_START_ADDR); |
+ |
+ NaClVmmapAdd(&nap->mem_map, |
+ nap->mem_start >> NACL_PAGESHIFT, |
+ NACL_SYSCALL_START_ADDR >> NACL_PAGESHIFT, |
+ PROT_NONE, |
+ NACL_VMMAP_ENTRY_ANONYMOUS); |
+ |
+ /* |
+ * We need to create a two-page guard region at the base of |
+ * trusted memory, for write sandboxing. |
+ */ |
+ NaClLog(4, "NaClMprotectGuards: %"NACL_PRIxPTR", %"NACL_PRIxS"\n", |
+ (uintptr_t) guard_base, |
+ (size_t) NACL_ADDRSPACE_UPPER_GUARD_SIZE); |
+ if ((err = NaCl_mprotect(guard_base, |
+ NACL_ADDRSPACE_UPPER_GUARD_SIZE, |
+ PROT_NONE)) != 0) { |
+ NaClLog(LOG_ERROR, ("NaClMemoryProtection: failed to protect lower guard " |
+ "on trusted memory space (error %d)\n"), |
+ err); |
+ return LOAD_MPROTECT_FAIL; |
+ } |
+ |
+ /* |
+ * NB: the pages just mapped are OUTSIDE of the address space of the |
+ * NaCl module. We should not track them in the Vmmap structure, |
+ * since that's to track addressable memory for mapping and unmapping. |
+ * |
+ * This means that because these pages are implicit and not tracked, |
+ * we should have a hook to tear down these pages as part of the |
+ * NaClApp dtor. |
+ */ |
+ return LOAD_OK; |
+} |