Example #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;
}
/* NOTE: This routine is almost identical to the x86_32 version.
 */
NaClErrorCode NaClAllocateSpaceAslr(void **mem, size_t addrsp_size,
                                    enum NaClAslrMode aslr_mode) {
  int result;
  void *tmp_mem = (void *) NACL_TRAMPOLINE_START;

  UNREFERENCED_PARAMETER(aslr_mode);
  CHECK(NULL != mem);

  /*
   * On ARM, we 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 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)) {
    /* On ARM, 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;
}