Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(854)

Unified Diff: src/trusted/service_runtime/arch/x86_32/sel_addrspace_x86_32.c

Issue 7677036: Enable the service runtime to use a zero-based sandbox on Linux. (Closed) Base URL: svn://svn.chromium.org/native_client/trunk/src/native_client
Patch Set: Fixes for Mark and Bennet's reviews Created 9 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: src/trusted/service_runtime/arch/x86_32/sel_addrspace_x86_32.c
diff --git a/src/trusted/service_runtime/arch/x86_32/sel_addrspace_x86_32.c b/src/trusted/service_runtime/arch/x86_32/sel_addrspace_x86_32.c
index 8cd92a7f65ac7e0af13ff80f6d0f496e22f41e84..5d753a3999a669e9903b0fd434881cbf28de42c4 100644
--- a/src/trusted/service_runtime/arch/x86_32/sel_addrspace_x86_32.c
+++ b/src/trusted/service_runtime/arch/x86_32/sel_addrspace_x86_32.c
@@ -4,29 +4,63 @@
* be found in the LICENSE file.
*/
+#if NACL_LINUX
+#include <errno.h>
+#include <sys/mman.h>
+#endif
+
#include "native_client/src/include/nacl_platform.h"
#include "native_client/src/shared/platform/nacl_check.h"
+#include "native_client/src/trusted/service_runtime/include/sys/errno.h"
#include "native_client/src/trusted/service_runtime/sel_memory.h"
#include "native_client/src/trusted/service_runtime/sel_ldr.h"
NaClErrorCode NaClAllocateSpace(void **mem, size_t addrsp_size) {
+#if NACL_LINUX
+ const void *ONE_MEGABYTE = (void *)(1024*1024);
+#endif
int result;
CHECK(NULL != mem);
-#ifdef NACL_SANDBOX_FIXED_AT_ZERO
+#if NACL_LINUX
/*
- * 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
- * out parameter.
+ * 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 ARM and performance issues on Intel ATOM.
+ * Look for this pre-reserved block and if found, pass its address to the
+ * page allocation function.
*/
- addrsp_size -= NACL_TRAMPOLINE_START;
- *mem = (void *) NACL_TRAMPOLINE_START;
- result = NaCl_page_alloc_at_addr(mem, addrsp_size);
- *mem = 0;
-#elif NACL_WINDOWS && NACL_BUILD_SUBARCH == 32
+ if (NaCl_find_prereserved_sandbox_memory(mem, addrsp_size)) {
+ /* Sanity check zero sandbox base address.
+ * It should be within a few pages above the 64KB boundary. See
+ * chrome/nacl/nacl_helper_bootstrap.c in the Chromium repository
+ * for more details.
+ */
+ if (0 == *mem || ONE_MEGABYTE < *mem) {
+ NaClLog(LOG_ERROR, "NaClAllocateSpace:"
+ "Can't handle sandbox at high address"
bsy 2011/08/23 21:34:20 ditto
Brad Chen 2011/08/23 22:29:52 Done.
+ "0x%08"NACL_PRIxPTR"\n",
+ (uintptr_t)*mem);
+ 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.
+ */
+ addrsp_size -= NACL_TRAMPOLINE_START;
+ *mem = (void *) NACL_TRAMPOLINE_START;
+ result = NaCl_page_alloc_at_addr(mem, addrsp_size);
+ *mem = 0;
+ } else {
+ /* Zero-based sandbox not pre-reserved. Attempt to allocate anyway. */
+ result = NaCl_page_alloc(mem, addrsp_size);
+ }
+#elif NACL_WINDOWS
/*
* On 32 bit Windows, a 1 gigabyte block of address space is reserved before
* starting up this process to make sure we can create the sandbox. Look for
@@ -60,6 +94,10 @@ NaClErrorCode NaClAllocateSpace(void **mem, size_t addrsp_size) {
NaClErrorCode NaClMprotectGuards(struct NaClApp *nap) {
uintptr_t start_addr;
int err;
+#if NACL_LINUX
+ uintptr_t page_addr;
+ void *mmap_rval;
+#endif
start_addr = nap->mem_start;
@@ -68,16 +106,53 @@ NaClErrorCode NaClMprotectGuards(struct NaClApp *nap) {
"size 0x%08x, end 0x%08"NACL_PRIxPTR"\n"),
start_addr, NACL_SYSCALL_START_ADDR,
start_addr + NACL_SYSCALL_START_ADDR);
- if ((err = NaCl_mprotect((void *) start_addr,
- NACL_SYSCALL_START_ADDR,
- PROT_NONE)) != 0) {
- NaClLog(LOG_ERROR, ("NaClMemoryProtection: "
- "NaCl_mprotect(0x%08"NACL_PRIxPTR", "
- "0x%08x, 0x%x) failed, "
- "error %d (NULL pointer guard page)\n"),
- start_addr, NACL_SYSCALL_START_ADDR, PROT_NONE,
- err);
- return LOAD_MPROTECT_FAIL;
+ if (0 == start_addr) {
+#if !NACL_LINUX
+ NaClLog(LOG_FATAL, ("NaClMprotectGuards: zero-based sandbox is"
+ " supported on Linux only.\n"));
+#else
+ /* Attempt to protect one page at a time. It is normal for
bsy 2011/08/23 21:34:20 maybe update to something along the lines of: Att
Brad Chen 2011/08/23 22:29:52 Done.
+ * these attempts to fail if the page is in the reserved low
+ * part of the address space. Note the 0 page can never be
+ * protected so start at NACL_PAGESIZE.
+ */
+ for (page_addr = NACL_PAGESIZE;
+ page_addr < NACL_SYSCALL_START_ADDR;
+ page_addr += NACL_PAGESIZE) {
+ mmap_rval = mmap((void *)page_addr,
+ NACL_SYSCALL_START_ADDR - page_addr,
+ PROT_NONE,
+ MAP_PRIVATE | MAP_FIXED | MAP_ANONYMOUS | MAP_NORESERVE,
+ -1, 0);
+ if (page_addr == (uintptr_t)mmap_rval) {
+ /* Success; the page is now protected. */
bsy 2011/08/23 21:34:20 pages are
Brad Chen 2011/08/23 22:29:52 Done.
+ break;
+ } else if (MAP_FAILED == mmap_rval && EPERM == errno) {
+ /* Normal; this is an invalid page for this process and
+ * doesn't need to be protected. Keep checking by page.
+ */
+ } else {
+ NaClLog(LOG_ERROR, ("NaClMemoryProtection: "
+ "mmap(0x%08"NACL_PRIxPTR") failed, "
+ "error %d (NULL pointer guard page)\n"),
+ page_addr, errno);
+ return LOAD_MPROTECT_FAIL;
+ }
+ }
+#endif
+ } else {
+ err = NaCl_mprotect((void *) start_addr,
+ NACL_SYSCALL_START_ADDR,
+ PROT_NONE);
+ if (err != 0) {
+ NaClLog(LOG_ERROR, ("NaClMemoryProtection: "
+ "NaCl_mprotect(0x%08"NACL_PRIxPTR", "
+ "0x%08x, 0x%x) failed, "
+ "error %d (NULL pointer guard page)\n"),
+ start_addr, NACL_SYSCALL_START_ADDR, PROT_NONE,
+ err);
+ return LOAD_MPROTECT_FAIL;
+ }
}
if (!NaClVmmapAdd(&nap->mem_map,
(start_addr - nap->mem_start) >> NACL_PAGESHIFT,

Powered by Google App Engine
This is Rietveld 408576698