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; }