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.
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. */
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;