]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
Add mempool get/put tracking with AddressSanitizer
authorOndřej Surý <ondrej@sury.org>
Thu, 25 Feb 2021 10:08:34 +0000 (11:08 +0100)
committerEvan Hunt <each@isc.org>
Fri, 26 Feb 2021 18:05:42 +0000 (10:05 -0800)
When AddressSanitizer is in use, disable the internal mempool
implementation and redirect the isc_mempool_get to isc_mem_get
(and similarly for isc_mempool_put).  This is the method recommended
by the AddressSanitizer authors for tracking allocations and
deallocations instead of custom poison/unpoison code (see
https://github.com/google/sanitizers/wiki/AddressSanitizerManualPoisoning).

lib/isc/mem.c
lib/isc/tests/mem_test.c

index 9291d89630855df8270d5cd05fc6cfc0cf9c3fb3..a2579fbaa6ded79af6f7eb51f8f2651296d4213c 100644 (file)
@@ -1294,18 +1294,50 @@ void
 isc_mempool_associatelock(isc_mempool_t *mpctx, isc_mutex_t *lock) {
        REQUIRE(VALID_MEMPOOL(mpctx));
        REQUIRE(lock != NULL);
-
        REQUIRE(mpctx->lock == NULL);
 
        mpctx->lock = lock;
 }
 
+#if __SANITIZE_ADDRESS__
 void *
 isc__mempool_get(isc_mempool_t *mpctx FLARG) {
        REQUIRE(VALID_MEMPOOL(mpctx));
 
-       element *item;
+       size_t allocated = atomic_fetch_add_release(&mpctx->allocated, 1);
+       size_t maxalloc = atomic_load_acquire(&mpctx->maxalloc);
+
+       /*
+        * Don't let the caller go over quota.
+        */
+       if (ISC_UNLIKELY(allocated >= maxalloc)) {
+               atomic_fetch_sub_release(&mpctx->allocated, 1);
+               return (NULL);
+       }
+
+       atomic_fetch_add_relaxed(&mpctx->gets, 1);
+
+       return (isc__mem_get(mpctx->mctx, mpctx->size FLARG_PASS));
+}
+
+void
+isc__mempool_put(isc_mempool_t *mpctx, void *mem FLARG) {
+       REQUIRE(VALID_MEMPOOL(mpctx));
+       REQUIRE(mem != NULL);
+
+       INSIST(atomic_fetch_sub_release(&mpctx->allocated, 1) > 0);
+
+       isc__mem_put(mpctx->mctx, mem, mpctx->size FLARG_PASS);
+}
+
+#else /* __SANITIZE_ADDRESS__ */
+void *
+isc__mempool_get(isc_mempool_t *mpctx FLARG) {
+       element *item = NULL;
        unsigned int i;
+
+       REQUIRE(VALID_MEMPOOL(mpctx));
+
        size_t allocated = atomic_fetch_add_release(&mpctx->allocated, 1);
        size_t maxalloc = atomic_load_acquire(&mpctx->maxalloc);
 
@@ -1359,11 +1391,12 @@ out:
 /* coverity[+free : arg-1] */
 void
 isc__mempool_put(isc_mempool_t *mpctx, void *mem FLARG) {
+       element *item = NULL;
+
        REQUIRE(VALID_MEMPOOL(mpctx));
        REQUIRE(mem != NULL);
 
        isc_mem_t *mctx = mpctx->mctx;
-       element *item;
        size_t freecount = atomic_load_acquire(&mpctx->freecount);
        size_t freemax = atomic_load_acquire(&mpctx->freemax);
 
@@ -1393,6 +1426,8 @@ isc__mempool_put(isc_mempool_t *mpctx, void *mem FLARG) {
        MPCTXUNLOCK(mpctx);
 }
 
+#endif /* __SANITIZE_ADDRESS__ */
+
 /*
  * Quotas
  */
index a39b59c19b16756801ae3ca36e9c0a1f7746d20f..4b42b39de08a337d53b8738a5a8e9cd1d0b56135 100644 (file)
@@ -107,8 +107,10 @@ isc_mem_test(void **state) {
                items1[i] = NULL;
        }
 
+#if !__SANITIZE_ADDRESS__
        rval = isc_mempool_getfreecount(mp1);
        assert_int_equal(rval, 10);
+#endif /* !__SANITIZE_ADDRESS__ */
 
        rval = isc_mempool_getallocated(mp1);
        assert_int_equal(rval, 19);