Пример #1
0
NaClErrorCode NaClAllocateSpace(void **mem, size_t addrsp_size) {
  int result;

  CHECK(NULL != mem);

  NaClAddrSpaceBeforeAlloc(addrsp_size);

#if NACL_LINUX
  /*
   * 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 prereserved block and if found, pass its address to the
   * page allocation function.
   */
  if (NaClFindPrereservedSandboxMemory(mem, addrsp_size)) {
    void *tmp_mem = (void *) NACL_TRAMPOLINE_START;
    CHECK(*mem == 0);
    addrsp_size -= NACL_TRAMPOLINE_START;
    result = NaCl_page_alloc_at_addr(&tmp_mem, addrsp_size);
  } else {
    /* Zero-based sandbox not prereserved. 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
   * this prereserved block and if found, pass its address to the page
   * allocation function.
   */
  if (0 == NaClFindPrereservedSandboxMemory(mem, addrsp_size)) {
    result = NaCl_page_alloc_at_addr(mem, addrsp_size);
  } else {
    result = NaCl_page_alloc(mem, addrsp_size);
  }
#else
  result = NaCl_page_alloc(mem, addrsp_size);
#endif

  if (0 != result) {
    NaClLog(2,
        "NaClAllocateSpace: NaCl_page_alloc 0x%08"NACL_PRIxPTR
        " failed\n",
        (uintptr_t) *mem);
    return LOAD_NO_MEMORY;
  }
  NaClLog(4, "NaClAllocateSpace: %"NACL_PRIxPTR", %"NACL_PRIxS"\n",
          (uintptr_t) *mem,
          addrsp_size);

  return LOAD_OK;
}
Пример #2
0
void TestDEPCheckFailurePath(void) {
  size_t size = NACL_PAGESIZE;
  void *page;
  CHECK(NaCl_page_alloc(&page, size) == 0);

  CHECK(NaCl_mprotect(page, size, PROT_READ | PROT_WRITE | PROT_EXEC) == 0);
  CHECK(!NaClAttemptToExecuteDataAtAddr(page, size));

  /* DEP is not guaranteed to work on x86-32. */
  if (!(NACL_ARCH(NACL_BUILD_ARCH) == NACL_x86 && NACL_BUILD_SUBARCH == 32)) {
    CHECK(NaCl_mprotect(page, size, PROT_READ | PROT_WRITE) == 0);
    CHECK(NaClAttemptToExecuteDataAtAddr(page, size));
  }

  NaCl_page_free(page, size);
}
/*
 * Create thunk for use by syscall trampoline code.
 */
int NaClMakePcrelThunk(struct NaClApp *nap) {
  int                   retval = 0;  /* fail */
  int                   error;
  void                  *thunk_addr = NULL;
  struct NaClPatchInfo  patch_info;
  uintptr_t             patch_rel32[1];  /* NaClSyscallSeg */
  struct NaClPatch      patch_abs32[2];  /* ds, nacl_user */

  /* idempotent */
  nacl_pcrel_globals.user = nacl_user;
  nacl_pcrel_globals.sys = nacl_sys;

  if (0 != (error = NaCl_page_alloc(&thunk_addr, NACL_MAP_PAGESIZE))) {
    NaClLog(LOG_INFO,
            "NaClMakePcrelThunk::NaCl_page_alloc failed, errno %d\n",
            -error);
    retval = 0;
    goto cleanup;
  }

  patch_rel32[0] = ((uintptr_t) &NaClPcrelThunk_end) - 4;

  patch_abs32[0].target = ((uintptr_t) &NaClPcrelThunk_dseg_patch) - 4;
  patch_abs32[0].value = NaClGetGlobalDs();
  patch_abs32[1].target = ((uintptr_t) &NaClPcrelThunk_globals_patch) - 4;
  patch_abs32[1].value = (uintptr_t) &nacl_pcrel_globals;

  NaClPatchInfoCtor(&patch_info);

  patch_info.rel32 = patch_rel32;
  patch_info.num_rel32 = NACL_ARRAY_SIZE(patch_rel32);

  patch_info.abs32 = patch_abs32;
  patch_info.num_abs32 = NACL_ARRAY_SIZE(patch_abs32);

  patch_info.dst = (uintptr_t) thunk_addr;
  patch_info.src = (uintptr_t) &NaClPcrelThunk;
  patch_info.nbytes = ((uintptr_t) &NaClPcrelThunk_end
                       - (uintptr_t) &NaClPcrelThunk);

  NaClApplyPatchToMemory(&patch_info);

  if (0 != (error = NaCl_mprotect(thunk_addr,
                                  NACL_MAP_PAGESIZE,
                                  PROT_EXEC|PROT_READ))) {
    NaClLog(LOG_INFO,
            "NaClMakePcrelThunk::NaCl_mprotect failed, errno %d\n",
            -error);
    retval = 0;
    goto cleanup;
  }
  retval = 1;
cleanup:
  if (0 == retval) {
    if (NULL != thunk_addr) {
      NaCl_page_free(thunk_addr, NACL_MAP_PAGESIZE);
      thunk_addr = NULL;
    }
  } else {
    nap->pcrel_thunk = (uintptr_t) thunk_addr;
  }
  return retval;
}