Exemple #1
0
static uintptr_t
ReservePoisonArea()
{
  if (sizeof(uintptr_t) == 8) {
    // Use the hardware-inaccessible region.
    // We have to avoid 64-bit constants and shifts by 32 bits, since this
    // code is compiled in 32-bit mode, although it is never executed there.
    uintptr_t result = (((uintptr_t(0x7FFFFFFFu) << 31) << 1 |
                         uintptr_t(0xF0DEAFFFu)) &
                        ~uintptr_t(PageSize()-1));
    printf("INFO | poison area assumed at 0x%.*" PRIxPTR "\n", SIZxPTR, result);
    return result;
  }

  // First see if we can allocate the preferred poison address from the OS.
  uintptr_t candidate = (0xF0DEAFFF & ~(PageSize() - 1));
  void* result = ReserveRegion(candidate, false);
  if (result == reinterpret_cast<void*>(candidate)) {
    // success - inaccessible page allocated
    printf("INFO | poison area allocated at 0x%.*" PRIxPTR
           " (preferred addr)\n", SIZxPTR, reinterpret_cast<uintptr_t>(result));
    return candidate;
  }

  // That didn't work, so see if the preferred address is within a range
  // of permanently inacessible memory.
  if (ProbeRegion(candidate)) {
    // success - selected page cannot be usable memory
    if (result != MAP_FAILED) {
      ReleaseRegion(result);
    }
    printf("INFO | poison area assumed at 0x%.*" PRIxPTR
           " (preferred addr)\n", SIZxPTR, candidate);
    return candidate;
  }

  // The preferred address is already in use.  Did the OS give us a
  // consolation prize?
  if (result != MAP_FAILED) {
    uintptr_t ures = reinterpret_cast<uintptr_t>(result);
    printf("INFO | poison area allocated at 0x%.*" PRIxPTR
           " (consolation prize)\n", SIZxPTR, ures);
    return ures;
  }

  // It didn't, so try to allocate again, without any constraint on
  // the address.
  result = ReserveRegion(0, false);
  if (result != MAP_FAILED) {
    uintptr_t ures = reinterpret_cast<uintptr_t>(result);
    printf("INFO | poison area allocated at 0x%.*" PRIxPTR
           " (fallback)\n", SIZxPTR, ures);
    return ures;
  }

  printf("ERROR | no usable poison area found\n");
  return 0;
}
/* The "negative control" area confirms that our probe logic does detect a
 * page that is readable, writable, or executable.
 */
static uintptr_t
ReserveNegativeControl()
{
  void *result = ReserveRegion(0, true);
  if (result == MAP_FAILED) {
    printf("ERROR | allocating negative control | %s\n", LastErrMsg());
    return 0;
  }

  // Fill the page with return instructions.
  RETURN_INSTR_TYPE *p = (RETURN_INSTR_TYPE *)result;
  RETURN_INSTR_TYPE *limit = (RETURN_INSTR_TYPE *)(((char *)result) + PAGESIZE);
  while (p < limit)
    *p++ = RETURN_INSTR;

  // Now mark it executable as well as readable and writable.
  // (mmap(PROT_EXEC) may fail when applied to anonymous memory.)

  if (MakeRegionExecutable(result)) {
    printf("ERROR | making negative control executable | %s\n", LastErrMsg());
    return 0;
  }

  printf("INFO | negative control allocated at 0x%.*" PRIxPTR "\n",
         SIZxPTR, (uintptr_t)result);
  return (uintptr_t)result;
}
static PRUword
ReservePoisonArea(PRUword rgnsize)
{
  if (sizeof(PRUword) == 8) {
    // Use the hardware-inaccessible region.
    // We have to avoid 64-bit constants and shifts by 32 bits, since this
    // code is compiled in 32-bit mode, although it is never executed there.
    return
      (((PRUword(0x7FFFFFFFu) << 31) << 1 | PRUword(0xF0DEAFFFu))
       & ~(rgnsize-1));

  } else {
    // First see if we can allocate the preferred poison address from the OS.
    PRUword candidate = (0xF0DEAFFF & ~(rgnsize-1));
    void *result = ReserveRegion(candidate, rgnsize);
    if (result == (void *)candidate) {
      // success - inaccessible page allocated
      return candidate;
    }

    // That didn't work, so see if the preferred address is within a range
    // of permanently inacessible memory.
    if (ProbeRegion(candidate, rgnsize)) {
      // success - selected page cannot be usable memory
      if (result != RESERVE_FAILED)
        ReleaseRegion(result, rgnsize);
      return candidate;
    }

    // The preferred address is already in use.  Did the OS give us a
    // consolation prize?
    if (result != RESERVE_FAILED) {
      return PRUword(result);
    }

    // It didn't, so try to allocate again, without any constraint on
    // the address.
    result = ReserveRegion(0, rgnsize);
    if (result != RESERVE_FAILED) {
      return PRUword(result);
    }

    NS_RUNTIMEABORT("no usable poison region identified");
    return 0;
  }
}
/* The "positive control" area confirms that we can allocate a page with the
 * proper characteristics.
 */
static uintptr_t
ReservePositiveControl()
{

  void *result = ReserveRegion(0, false);
  if (result == MAP_FAILED) {
    printf("ERROR | allocating positive control | %s\n", LastErrMsg());
    return 0;
  }
  printf("INFO | positive control allocated at 0x%.*" PRIxPTR "\n",
         SIZxPTR, (uintptr_t)result);
  return (uintptr_t)result;
}