void *hwasan_pvalloc(uptr size, StackTrace *stack) { uptr PageSize = GetPageSizeCached(); if (UNLIKELY(CheckForPvallocOverflow(size, PageSize))) { errno = errno_ENOMEM; if (AllocatorMayReturnNull()) return nullptr; ReportPvallocOverflow(size, stack); } // pvalloc(0) should allocate one page. size = size ? RoundUpTo(size, PageSize) : PageSize; return SetErrnoOnNull(HwasanAllocate(stack, size, PageSize, false)); }
// If this is a shadow fault, we handle it here; otherwise, we pass it to the // app to handle it just as the app would do without our tool in place. static void handleMemoryFault(int SigNum, __sanitizer_siginfo *Info, void *Ctx) { if (SigNum == SIGSEGV) { // We rely on si_addr being filled in (thus we do not support old kernels). siginfo_t *SigInfo = (siginfo_t *)Info; uptr Addr = (uptr)SigInfo->si_addr; if (isShadowMem(Addr)) { VPrintf(3, "Shadow fault @%p\n", Addr); uptr PageSize = GetPageSizeCached(); int Res = internal_mprotect((void *)RoundDownTo(Addr, PageSize), PageSize, PROT_READ|PROT_WRITE); CHECK(Res == 0); } else if (AppSigAct.sigaction) { // FIXME: For simplicity we ignore app options including its signal stack // (we just use ours) and all the delivery flags. AppSigAct.sigaction(SigNum, Info, Ctx); } else { // Crash instead of spinning with infinite faults. reinstateDefaultHandler(SigNum); } } else UNREACHABLE("signal not registered"); }
void *hwasan_valloc(uptr size, StackTrace *stack) { return SetErrnoOnNull( HwasanAllocate(stack, size, GetPageSizeCached(), false)); }