Esempio n. 1
0
// Scan shadow memory to calculate the number of cache lines being accessed,
// i.e., the number of non-zero bits indexed by BitIdx in each shadow byte.
// We also clear the lowest bits (most recent working set snapshot).
static u32 computeWorkingSizeAndReset(u32 BitIdx) {
  u32 WorkingSetSize = 0;
  MemoryMappingLayout MemIter(true/*cache*/);
  uptr Start, End, Prot;
  while (MemIter.Next(&Start, &End, nullptr/*offs*/, nullptr/*file*/,
                      0/*file size*/, &Prot)) {
    VPrintf(4, "%s: considering %p-%p app=%d shadow=%d prot=%u\n",
            __FUNCTION__, Start, End, Prot, isAppMem(Start),
            isShadowMem(Start));
    if (isShadowMem(Start) && (Prot & MemoryMappingLayout::kProtectionWrite)) {
      VPrintf(3, "%s: walking %p-%p\n", __FUNCTION__, Start, End);
      WorkingSetSize += countAndClearShadowValues(BitIdx, Start, End);
    }
  }
  return WorkingSetSize;
}
// 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");
}
Esempio n. 3
0
static bool verifyShadowScheme() {
  // Sanity checks for our shadow mapping scheme.
  uptr AppStart, AppEnd;
  if (Verbosity() >= 3) {
    for (int i = 0; getAppRegion(i, &AppStart, &AppEnd); ++i) {
      VPrintf(3, "App #%d: [%zx-%zx) (%zuGB)\n", i, AppStart, AppEnd,
              (AppEnd - AppStart) >> 30);
    }
  }
  for (int Scale = 0; Scale < 8; ++Scale) {
    Mapping.initialize(Scale);
    if (Verbosity() >= 3) {
      VPrintf(3, "\nChecking scale %d\n", Scale);
      uptr ShadowStart, ShadowEnd;
      for (int i = 0; getShadowRegion(i, &ShadowStart, &ShadowEnd); ++i) {
        VPrintf(3, "Shadow #%d: [%zx-%zx) (%zuGB)\n", i, ShadowStart,
                ShadowEnd, (ShadowEnd - ShadowStart) >> 30);
      }
      for (int i = 0; getShadowRegion(i, &ShadowStart, &ShadowEnd); ++i) {
        VPrintf(3, "Shadow(Shadow) #%d: [%zx-%zx)\n", i,
                appToShadow(ShadowStart), appToShadow(ShadowEnd - 1)+1);
      }
    }
    for (int i = 0; getAppRegion(i, &AppStart, &AppEnd); ++i) {
      DCHECK(isAppMem(AppStart));
      DCHECK(!isAppMem(AppStart - 1));
      DCHECK(isAppMem(AppEnd - 1));
      DCHECK(!isAppMem(AppEnd));
      DCHECK(!isShadowMem(AppStart));
      DCHECK(!isShadowMem(AppEnd - 1));
      DCHECK(isShadowMem(appToShadow(AppStart)));
      DCHECK(isShadowMem(appToShadow(AppEnd - 1)));
      // Double-shadow checks.
      DCHECK(!isShadowMem(appToShadow(appToShadow(AppStart))));
      DCHECK(!isShadowMem(appToShadow(appToShadow(AppEnd - 1))));
    }
    // Ensure no shadow regions overlap each other.
    uptr ShadowAStart, ShadowBStart, ShadowAEnd, ShadowBEnd;
    for (int i = 0; getShadowRegion(i, &ShadowAStart, &ShadowAEnd); ++i) {
      for (int j = 0; getShadowRegion(j, &ShadowBStart, &ShadowBEnd); ++j) {
        DCHECK(i == j || ShadowAStart >= ShadowBEnd ||
               ShadowAEnd <= ShadowBStart);
      }
    }
  }