]> git.kaiwu.me - njs.git/commitdiff
Memory pool: allocate the block descriptor separately with the sanitizer
authorDmitry Volyntsev <xeioex@nginx.com>
Wed, 2 Sep 2026 23:12:01 +0000 (16:12 -0700)
committerDmitry Volyntsev <xeioexception@gmail.com>
Fri, 4 Sep 2026 20:54:20 +0000 (13:54 -0700)
Previously, njs_mp_alloc_large() embedded the block descriptor at the end of
the allocation for sizes which are not a power of two, so a read past the end
of an object stayed inside the malloc()ed region and was not detected by the
address sanitizer.

The fix is to always allocate the descriptor separately when the address
sanitizer is enabled.

src/njs_mp.c

index 4288343e9addaf041c6c1f562b3ae22c25a86037..f7e0df1d1110d1e7e3ec0bbfb8b2ac5026ffd4c2 100644 (file)
@@ -585,6 +585,7 @@ njs_mp_alloc_large(njs_mp_t *mp, size_t alignment, size_t size)
     u_char          *p;
     size_t          aligned_size;
     uint8_t         type;
+    njs_bool_t      discrete;
     njs_mp_block_t  *block;
 
     /* Allocation must be less than 4G. */
@@ -600,7 +601,14 @@ njs_mp_alloc_large(njs_mp_t *mp, size_t alignment, size_t size)
     size += size == 0;
 #endif
 
-    if (njs_is_power_of_two(size)) {
+    discrete = njs_is_power_of_two(size);
+
+#if (NJS_HAVE_ADDRESS_SANITIZER)
+    /* Keep the sanitizer redzone right after the object. */
+    discrete = 1;
+#endif
+
+    if (discrete) {
         block = njs_malloc(sizeof(njs_mp_block_t));
         if (njs_slow_path(block == NULL)) {
             return NULL;