Consolidate C++ Pool Allocators And Add ASAN Poison Support

  • Consolidate the PoolAllocator and ObjectPool classes

    • The ObjectPool is nothing but a PoolAllocator with a fixed size, so make it use that instead.
    • Fix up the documentation for these classes.
  • Add AddressSanitizer support to PoolAllocator:

    • Add PetscPoisonMemoryRegion()
    • Add PetscUnpoisonMemoryRegion()

    Since you don't free() the memory in the pool until the end the usual canary protections used by the system allocators or Valgrind no longer work. It would be possible to buffer overrun or use-after-free pool-allocated objects. ASAN let's you "poison" regions of memory, effectively marking them as free'd without doing so. Any attempt to derefence these regions results in an error.

    So the strategy is to poison a region once it is reclaimed by the pool and unpoison it when re-allocated.

    https://github.com/google/sanitizers/wiki/AddressSanitizerManualPoisoning

Given the following:

#include <petscdevice.h>

int main(int argc, char *argv[])
{
  const char        *name;
  PetscDeviceContext dctx, dctx_backup;

  PetscCall(PetscInitialize(&argc, &argv, nullptr, nullptr));
  PetscCall(PetscDeviceContextCreate(&dctx));
  dctx_backup = dctx;
  PetscCall(PetscDeviceContextDestroy(&dctx));
  // boom
  PetscCall(PetscObjectGetName((PetscObject)dctx_backup, &name));
  PetscCall(PetscFinalize());
}

Gives

image

Edited by Jacob Faibussowitsch

Merge request reports

Loading