aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEvgeny Grin (Karlson2k) <k2k@narod.ru>2021-10-10 21:16:25 +0300
committerEvgeny Grin (Karlson2k) <k2k@narod.ru>2021-10-10 21:16:25 +0300
commit50c9e5efea6913cf97b4b1afd8c57f886f552d32 (patch)
treeae6e689a7f9a61b1cfd5ee88bf3299837af37ee9
parentfe8a9c6181424520383dd7ff7e30a082158e4b04 (diff)
downloadlibmicrohttpd-50c9e5efea6913cf97b4b1afd8c57f886f552d32.tar.gz
libmicrohttpd-50c9e5efea6913cf97b4b1afd8c57f886f552d32.zip
Added custom memory poisoning for MemoryPool
-rw-r--r--configure.ac111
-rw-r--r--src/include/mhd_options.h27
-rw-r--r--src/microhttpd/memorypool.c75
-rw-r--r--src/testcurl/test_toolarge.c6
4 files changed, 203 insertions, 16 deletions
diff --git a/configure.ac b/configure.ac
index f013ecb1..67b18c5f 100644
--- a/configure.ac
+++ b/configure.ac
@@ -2648,6 +2648,8 @@ AS_VAR_IF([enable_sanitizers], ["yes"],
2648 ) 2648 )
2649 AS_VAR_IF([mhd_cv_cc_sanitizer_address],["yes"], 2649 AS_VAR_IF([mhd_cv_cc_sanitizer_address],["yes"],
2650 [ 2650 [
2651 AC_DEFINE([MHD_ASAN_ACTIVE], [1], [Define to '1' if you have address sanitizer enabled])
2652 AC_CHECK_HEADERS([sanitizer/asan_interface.h], [], [], [AC_INCLUDES_DEFAULT])
2651 AX_APPEND_FLAG([-fsanitize=address], [san_FLAGS]) 2653 AX_APPEND_FLAG([-fsanitize=address], [san_FLAGS])
2652 enabled_sanitizers="${enabled_sanitizers}${enabled_sanitizers:+, }address" 2654 enabled_sanitizers="${enabled_sanitizers}${enabled_sanitizers:+, }address"
2653 AC_CACHE_CHECK([whether leak detect is supported], [mhd_cv_cc_sanitizer_address_leak], 2655 AC_CACHE_CHECK([whether leak detect is supported], [mhd_cv_cc_sanitizer_address_leak],
@@ -2691,6 +2693,104 @@ AS_VAR_IF([enable_sanitizers], ["yes"],
2691 enabled_sanitizers="${enabled_sanitizers}${enabled_sanitizers:+, }pointer subtract" 2693 enabled_sanitizers="${enabled_sanitizers}${enabled_sanitizers:+, }pointer subtract"
2692 ] 2694 ]
2693 ) 2695 )
2696 AS_VAR_IF([ac_cv_header_sanitizer_asan_interface_h],["yes"],
2697 [
2698 AC_CACHE_CHECK([whether '__attribute__((no_sanitize("pointer-compare","pointer-subtract")))' works], [mhd_cv_func_attribute_nosanitize_ptr],
2699 [
2700 ASAN_OPTIONS="exitcode=88:detect_invalid_pointer_pairs=3:halt_on_error=1"
2701 export ASAN_OPTIONS
2702 CFLAGS="${saved_CFLAGS} ${san_CFLAGS} ${san_FLAGS} ${errattr_CFLAGS}"
2703 AC_RUN_IFELSE(
2704 [
2705 AC_LANG_PROGRAM(
2706 [[
2707#include <stdlib.h>
2708
2709__attribute__((no_sanitize("pointer-compare","pointer-subtract")))
2710int ptr_process(void *ptr1, void *ptr2)
2711{
2712 if ((char*)ptr1 <= (char*)ptr2)
2713 return (int) ((char*)ptr2 - (char*)ptr1);
2714 return (int) ((char*)ptr1 - (char*)ptr2);
2715}
2716 ]],
2717 [[
2718 int *a = (int*) malloc (sizeof(int)*4);
2719 int *b = (int*) malloc (sizeof(long)*6);
2720 int c = ptr_process(a, b);
2721 if (c)
2722 {
2723 free (b);
2724 free (a);
2725 return 0;
2726 }
2727 free (a);
2728 free (b);
2729 ]]
2730 )
2731 ],
2732 [mhd_cv_func_attribute_nosanitize_ptr=yes], [mhd_cv_func_attribute_nosanitize_ptr=no],
2733 [
2734 # Cross-compiling with sanitizers??
2735 mhd_cv_func_attribute_nosanitize_ptr=no
2736 ]
2737 )
2738 AS_UNSET([ASAN_OPTIONS])
2739 ]
2740 )
2741 AS_VAR_IF([mhd_cv_func_attribute_nosanitize_ptr], ["yes"],
2742 [AC_DEFINE([FUNC_ATTR_PTRCOMPARE_WOKRS],[1],[Define to '1' if '__attribute__((no_sanitize("pointer-compare","pointer-subtract")))' works])],
2743 [
2744 AC_CACHE_CHECK([whether '__attribute__((no_sanitize("address")))' works for pointers compare], [mhd_cv_func_attribute_nosanitize_addr],
2745 [
2746 ASAN_OPTIONS="exitcode=88:detect_invalid_pointer_pairs=3:halt_on_error=1"
2747 export ASAN_OPTIONS
2748 CFLAGS="${saved_CFLAGS} ${san_CFLAGS} ${san_FLAGS} ${errattr_CFLAGS}"
2749 AC_RUN_IFELSE(
2750 [
2751 AC_LANG_PROGRAM(
2752 [[
2753#include <stdlib.h>
2754
2755__attribute__((no_sanitize("address")))
2756int ptr_process(void *ptr1, void *ptr2)
2757{
2758 if ((char*)ptr1 <= (char*)ptr2)
2759 return (int) ((char*)ptr2 - (char*)ptr1);
2760 return (int) ((char*)ptr1 - (char*)ptr2);
2761}
2762 ]],
2763 [[
2764 int *a = (int*) malloc (sizeof(int)*4);
2765 int *b = (int*) malloc (sizeof(long)*6);
2766 int c = ptr_process(a, b);
2767 if (c)
2768 {
2769 free (b);
2770 free (a);
2771 return 0;
2772 }
2773 free (a);
2774 free (b);
2775 ]]
2776 )
2777 ],
2778 [mhd_cv_func_attribute_nosanitize_addr=yes], [mhd_cv_func_attribute_nosanitize_addr=no],
2779 [
2780 # Cross-compiling with sanitizers??
2781 mhd_cv_func_attribute_nosanitize_addr=no
2782 ]
2783 )
2784 AS_UNSET([ASAN_OPTIONS])
2785 ]
2786 )
2787 AS_VAR_IF([mhd_cv_func_attribute_nosanitize_addr], ["yes"],
2788 [AC_DEFINE([FUNC_ATTR_NOSANITIZE_WORKS],[1],[Define to '1' if '__attribute__((no_sanitize("address")))' works for pointers compare])]
2789 )
2790 ]
2791 )
2792 ]
2793 )
2694 ] 2794 ]
2695 ) 2795 )
2696 dnl Ensure that '#' will be processed correctly 2796 dnl Ensure that '#' will be processed correctly
@@ -2812,6 +2912,15 @@ int main(void)
2812 ) 2912 )
2813 AS_IF([test -z "${enabled_sanitizers}"], 2913 AS_IF([test -z "${enabled_sanitizers}"],
2814 [AC_MSG_ERROR([cannot find any sanitizer supported by $CC])]) 2914 [AC_MSG_ERROR([cannot find any sanitizer supported by $CC])])
2915 AC_MSG_CHECKING([whether to enable user memory poisoning])
2916 AS_IF([test "x${mhd_cv_cc_sanitizer_address}" = "xyes" && test "x${ac_cv_header_sanitizer_asan_interface_h}" = "xyes" && \
2917 (test "x${mhd_cv_func_attribute_nosanitize_ptr}" = "xyes" || test "x${mhd_cv_func_attribute_nosanitize_addr}" = "xyes")],
2918 [
2919 AC_DEFINE([MHD_ASAN_POISON_ACTIVE], [1], [Define to '1' if user memory poison is used])
2920 enabled_sanitizers="${enabled_sanitizers}${enabled_sanitizers:+, }user-poison"
2921 AC_MSG_RESULT([yes])
2922 ], [AC_MSG_RESULT([no])]
2923 )
2815 AS_VAR_IF([mhd_cv_cc_sanitizer_address],["yes"], 2924 AS_VAR_IF([mhd_cv_cc_sanitizer_address],["yes"],
2816 [ 2925 [
2817 AX_APPEND_FLAG([-D_FORTIFY_SOURCE=0], [san_CFLAGS]) 2926 AX_APPEND_FLAG([-D_FORTIFY_SOURCE=0], [san_CFLAGS])
@@ -2829,7 +2938,7 @@ int main(void)
2829 AM_ASAN_OPTIONS="exitcode=88:strict_string_checks=1:detect_stack_use_after_return=1" 2938 AM_ASAN_OPTIONS="exitcode=88:strict_string_checks=1:detect_stack_use_after_return=1"
2830 AM_ASAN_OPTIONS="${AM_ASAN_OPTIONS}:check_initialization_order=1:strict_init_order=1:redzone=64" 2939 AM_ASAN_OPTIONS="${AM_ASAN_OPTIONS}:check_initialization_order=1:strict_init_order=1:redzone=64"
2831 AM_ASAN_OPTIONS="${AM_ASAN_OPTIONS}:max_free_fill_size=1024:detect_invalid_pointer_pairs=3" 2940 AM_ASAN_OPTIONS="${AM_ASAN_OPTIONS}:max_free_fill_size=1024:detect_invalid_pointer_pairs=3"
2832 AM_ASAN_OPTIONS="${AM_ASAN_OPTIONS}:handle_ioctl=1:halt_on_error=1" 2941 AM_ASAN_OPTIONS="${AM_ASAN_OPTIONS}:handle_ioctl=1:allow_user_poisoning=1:halt_on_error=1"
2833 AS_VAR_IF([mhd_cv_cc_sanitizer_address_leak], ["yes"], 2942 AS_VAR_IF([mhd_cv_cc_sanitizer_address_leak], ["yes"],
2834 [AM_ASAN_OPTIONS="${AM_ASAN_OPTIONS}:detect_leaks=1"]) 2943 [AM_ASAN_OPTIONS="${AM_ASAN_OPTIONS}:detect_leaks=1"])
2835 AM_UBSAN_OPTIONS="exitcode=87:print_stacktrace=1:halt_on_error=1" 2944 AM_UBSAN_OPTIONS="exitcode=87:print_stacktrace=1:halt_on_error=1"
diff --git a/src/include/mhd_options.h b/src/include/mhd_options.h
index 0e803451..e405fd23 100644
--- a/src/include/mhd_options.h
+++ b/src/include/mhd_options.h
@@ -1,6 +1,6 @@
1/* 1/*
2 This file is part of libmicrohttpd 2 This file is part of libmicrohttpd
3 Copyright (C) 2016 Karlson2k (Evgeny Grin) 3 Copyright (C) 2016-2021 Karlson2k (Evgeny Grin)
4 4
5 This library is free software; you can redistribute it and/or 5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public 6 modify it under the terms of the GNU Lesser General Public
@@ -142,4 +142,29 @@
142#define MHD_FAVOR_FAST_CODE 1 142#define MHD_FAVOR_FAST_CODE 1
143#endif /* !MHD_FAVOR_FAST_CODE && !MHD_FAVOR_SMALL_CODE */ 143#endif /* !MHD_FAVOR_FAST_CODE && !MHD_FAVOR_SMALL_CODE */
144 144
145#ifndef MHD_ASAN_ACTIVE
146#if (defined(__GNUC__) || defined(_MSC_VER)) && defined(__SANITIZE_ADDRESS__)
147#define MHD_ASAN_ACTIVE 1
148#elif defined(__has_feature)
149#if __has_feature (address_sanitizer)
150#define MHD_ASAN_ACTIVE 1
151#endif /* __has_feature(address_sanitizer) */
152#endif /* __has_feature */
153#endif /* MHD_ASAN_ACTIVE */
154
155#if defined(MHD_ASAN_ACTIVE) && defined(HAVE_SANITIZER_ASAN_INTERFACE_H) && \
156 (defined(FUNC_ATTR_PTRCOMPARE_WOKRS) || defined(FUNC_ATTR_NOSANITIZE_WORKS))
157#ifndef MHD_ASAN_POISON_ACTIVE
158/* Manual ASAN poisoning could be used */
159#warning User memory poisoning is not active
160#endif /* ! MHD_ASAN_POISON_ACTIVE */
161#define _MHD_USE_ASAN_POISON 1
162#else /* ! (MHD_ASAN_ACTIVE && HAVE_SANITIZER_ASAN_INTERFACE_H &&
163 (FUNC_ATTR_PTRCOMPARE_WOKRS || FUNC_ATTR_NOSANITIZE_WORKS)) */
164#ifdef MHD_ASAN_POISON_ACTIVE
165#error User memory poisoning is active, but conditions are not suitable
166#endif /* MHD_ASAN_POISON_ACTIVE */
167#endif /* ! (MHD_ASAN_ACTIVE && HAVE_SANITIZER_ASAN_INTERFACE_H &&
168 (FUNC_ATTR_PTRCOMPARE_WOKRS || FUNC_ATTR_NOSANITIZE_WORKS)) */
169
145#endif /* MHD_OPTIONS_H */ 170#endif /* MHD_OPTIONS_H */
diff --git a/src/microhttpd/memorypool.c b/src/microhttpd/memorypool.c
index fb6c0652..0f71ab1b 100644
--- a/src/microhttpd/memorypool.c
+++ b/src/microhttpd/memorypool.c
@@ -45,6 +45,11 @@
45#define MHD_SC_PAGESIZE _SC_PAGESIZE 45#define MHD_SC_PAGESIZE _SC_PAGESIZE
46#endif /* _SC_PAGESIZE */ 46#endif /* _SC_PAGESIZE */
47#endif /* HAVE_SYSCONF */ 47#endif /* HAVE_SYSCONF */
48#include "mhd_limits.h" /* for SIZE_MAX */
49
50#ifdef MHD_ASAN_POISON_ACTIVE
51#include <sanitizer/asan_interface.h>
52#endif /* _MHD_USE_ASAN_POISON */
48 53
49/* define MAP_ANONYMOUS for Mac OS X */ 54/* define MAP_ANONYMOUS for Mac OS X */
50#if defined(MAP_ANON) && ! defined(MAP_ANONYMOUS) 55#if defined(MAP_ANON) && ! defined(MAP_ANONYMOUS)
@@ -67,6 +72,28 @@
67#define ROUND_TO_ALIGN(n) (((n) + (ALIGN_SIZE - 1)) \ 72#define ROUND_TO_ALIGN(n) (((n) + (ALIGN_SIZE - 1)) \
68 / (ALIGN_SIZE) *(ALIGN_SIZE)) 73 / (ALIGN_SIZE) *(ALIGN_SIZE))
69 74
75
76#ifndef MHD_ASAN_POISON_ACTIVE
77#define _MHD_NOSANITIZE_PTRS /**/
78#define _MHD_RED_ZONE_SIZE (0)
79#define ROUND_TO_ALIGN_PLUS_RED_ZONE(n) ROUND_TO_ALIGN(n)
80#define _MHD_POISON_MEMORY(pointer, size) /**/
81#define _MHD_UNPOISON_MEMORY(pointer, size) /**/
82#else /* MHD_ASAN_POISON_ACTIVE */
83#if defined(FUNC_ATTR_PTRCOMPARE_WOKRS)
84#define _MHD_NOSANITIZE_PTRS \
85 __attribute__((no_sanitize("pointer-compare","pointer-subtract")))
86#elif defined(FUNC_ATTR_NOSANITIZE_WORKS)
87#define _MHD_NOSANITIZE_PTRS __attribute__((no_sanitize("address")))
88#endif
89#define _MHD_RED_ZONE_SIZE (ALIGN_SIZE)
90#define ROUND_TO_ALIGN_PLUS_RED_ZONE(n) (ROUND_TO_ALIGN(n) + _MHD_RED_ZONE_SIZE)
91#define _MHD_POISON_MEMORY(pointer, size) \
92 ASAN_POISON_MEMORY_REGION ((pointer), (size))
93#define _MHD_UNPOISON_MEMORY(pointer, size) \
94 ASAN_UNPOISON_MEMORY_REGION ((pointer), (size))
95#endif /* MHD_ASAN_POISON_ACTIVE */
96
70#if defined(PAGE_SIZE) && (0 < (PAGE_SIZE + 0)) 97#if defined(PAGE_SIZE) && (0 < (PAGE_SIZE + 0))
71#define MHD_DEF_PAGE_SIZE_ PAGE_SIZE 98#define MHD_DEF_PAGE_SIZE_ PAGE_SIZE
72#elif defined(PAGESIZE) && (0 < (PAGESIZE + 0)) 99#elif defined(PAGESIZE) && (0 < (PAGESIZE + 0))
@@ -205,6 +232,7 @@ MHD_pool_create (size_t max)
205 pool->end = alloc_size; 232 pool->end = alloc_size;
206 pool->size = alloc_size; 233 pool->size = alloc_size;
207 mhd_assert (0 < alloc_size); 234 mhd_assert (0 < alloc_size);
235 _MHD_POISON_MEMORY (pool->memory, pool->size);
208 return pool; 236 return pool;
209} 237}
210 238
@@ -222,6 +250,7 @@ MHD_pool_destroy (struct MemoryPool *pool)
222 250
223 mhd_assert (pool->end >= pool->pos); 251 mhd_assert (pool->end >= pool->pos);
224 mhd_assert (pool->size >= pool->end - pool->pos); 252 mhd_assert (pool->size >= pool->end - pool->pos);
253 _MHD_POISON_MEMORY (pool->memory, pool->size);
225 if (! pool->is_mmap) 254 if (! pool->is_mmap)
226 free (pool->memory); 255 free (pool->memory);
227 else 256 else
@@ -250,7 +279,11 @@ MHD_pool_get_free (struct MemoryPool *pool)
250{ 279{
251 mhd_assert (pool->end >= pool->pos); 280 mhd_assert (pool->end >= pool->pos);
252 mhd_assert (pool->size >= pool->end - pool->pos); 281 mhd_assert (pool->size >= pool->end - pool->pos);
253 return (pool->end - pool->pos); 282#ifdef MHD_ASAN_POISON_ACTIVE
283 if ((pool->end - pool->pos) <= _MHD_RED_ZONE_SIZE)
284 return 0;
285#endif /* _MHD_USE_ASAN_POISON */
286 return (pool->end - pool->pos) - _MHD_RED_ZONE_SIZE;
254} 287}
255 288
256 289
@@ -275,7 +308,7 @@ MHD_pool_allocate (struct MemoryPool *pool,
275 308
276 mhd_assert (pool->end >= pool->pos); 309 mhd_assert (pool->end >= pool->pos);
277 mhd_assert (pool->size >= pool->end - pool->pos); 310 mhd_assert (pool->size >= pool->end - pool->pos);
278 asize = ROUND_TO_ALIGN (size); 311 asize = ROUND_TO_ALIGN_PLUS_RED_ZONE (size);
279 if ( (0 == asize) && (0 != size) ) 312 if ( (0 == asize) && (0 != size) )
280 return NULL; /* size too close to SIZE_MAX */ 313 return NULL; /* size too close to SIZE_MAX */
281 if ( (pool->pos + asize > pool->end) || 314 if ( (pool->pos + asize > pool->end) ||
@@ -291,6 +324,7 @@ MHD_pool_allocate (struct MemoryPool *pool,
291 ret = &pool->memory[pool->pos]; 324 ret = &pool->memory[pool->pos];
292 pool->pos += asize; 325 pool->pos += asize;
293 } 326 }
327 _MHD_UNPOISON_MEMORY (ret, size);
294 return ret; 328 return ret;
295} 329}
296 330
@@ -299,7 +333,7 @@ MHD_pool_allocate (struct MemoryPool *pool,
299 * Try to allocate @a size bytes memory area from the @a pool. 333 * Try to allocate @a size bytes memory area from the @a pool.
300 * 334 *
301 * If allocation fails, @a required_bytes is updated with size required to be 335 * If allocation fails, @a required_bytes is updated with size required to be
302 * freed in the @a pool from relocatable area to allocate requested number 336 * freed in the @a pool from rellocatable area to allocate requested number
303 * of bytes. 337 * of bytes.
304 * Allocated memory area is always not rellocatable ("from end"). 338 * Allocated memory area is always not rellocatable ("from end").
305 * 339 *
@@ -311,7 +345,7 @@ MHD_pool_allocate (struct MemoryPool *pool,
311 * Cannot be NULL. 345 * Cannot be NULL.
312 * @return the pointer to allocated memory area if succeed, 346 * @return the pointer to allocated memory area if succeed,
313 * NULL if the pool doesn't have enough space, required_bytes is updated 347 * NULL if the pool doesn't have enough space, required_bytes is updated
314 * with amount of space needed to be freed in relocatable area or 348 * with amount of space needed to be freed in rellocatable area or
315 * set to SIZE_MAX if requested size is too large for the pool. 349 * set to SIZE_MAX if requested size is too large for the pool.
316 */ 350 */
317void * 351void *
@@ -324,7 +358,7 @@ MHD_pool_try_alloc (struct MemoryPool *pool,
324 358
325 mhd_assert (pool->end >= pool->pos); 359 mhd_assert (pool->end >= pool->pos);
326 mhd_assert (pool->size >= pool->end - pool->pos); 360 mhd_assert (pool->size >= pool->end - pool->pos);
327 asize = ROUND_TO_ALIGN (size); 361 asize = ROUND_TO_ALIGN_PLUS_RED_ZONE (size);
328 if ( (0 == asize) && (0 != size) ) 362 if ( (0 == asize) && (0 != size) )
329 { /* size is too close to SIZE_MAX, very unlikely */ 363 { /* size is too close to SIZE_MAX, very unlikely */
330 *required_bytes = SIZE_MAX; 364 *required_bytes = SIZE_MAX;
@@ -333,6 +367,8 @@ MHD_pool_try_alloc (struct MemoryPool *pool,
333 if ( (pool->pos + asize > pool->end) || 367 if ( (pool->pos + asize > pool->end) ||
334 (pool->pos + asize < pool->pos)) 368 (pool->pos + asize < pool->pos))
335 { 369 {
370 mhd_assert ((pool->end - pool->pos) == \
371 ROUND_TO_ALIGN (pool->end - pool->pos));
336 if (asize <= pool->end) 372 if (asize <= pool->end)
337 *required_bytes = asize - (pool->end - pool->pos); 373 *required_bytes = asize - (pool->end - pool->pos);
338 else 374 else
@@ -341,6 +377,7 @@ MHD_pool_try_alloc (struct MemoryPool *pool,
341 } 377 }
342 ret = &pool->memory[pool->end - asize]; 378 ret = &pool->memory[pool->end - asize];
343 pool->end -= asize; 379 pool->end -= asize;
380 _MHD_UNPOISON_MEMORY (ret, size);
344 return ret; 381 return ret;
345} 382}
346 383
@@ -362,7 +399,7 @@ MHD_pool_try_alloc (struct MemoryPool *pool,
362 * NULL if the pool cannot support @a new_size 399 * NULL if the pool cannot support @a new_size
363 * bytes (old continues to be valid for @a old_size) 400 * bytes (old continues to be valid for @a old_size)
364 */ 401 */
365void * 402_MHD_NOSANITIZE_PTRS void *
366MHD_pool_reallocate (struct MemoryPool *pool, 403MHD_pool_reallocate (struct MemoryPool *pool,
367 void *old, 404 void *old,
368 size_t old_size, 405 size_t old_size,
@@ -374,11 +411,11 @@ MHD_pool_reallocate (struct MemoryPool *pool,
374 mhd_assert (pool->end >= pool->pos); 411 mhd_assert (pool->end >= pool->pos);
375 mhd_assert (pool->size >= pool->end - pool->pos); 412 mhd_assert (pool->size >= pool->end - pool->pos);
376 mhd_assert (old != NULL || old_size == 0); 413 mhd_assert (old != NULL || old_size == 0);
377 mhd_assert (old == NULL || pool->memory <= (uint8_t*) old);
378 mhd_assert (pool->size >= old_size); 414 mhd_assert (pool->size >= old_size);
415 mhd_assert (old == NULL || pool->memory <= (uint8_t*) old);
379 /* (old == NULL || pool->memory + pool->size >= (uint8_t*) old + old_size) */ 416 /* (old == NULL || pool->memory + pool->size >= (uint8_t*) old + old_size) */
380 mhd_assert (old == NULL || \ 417 mhd_assert (old == NULL || \
381 (pool->size) >= \ 418 (pool->size - _MHD_RED_ZONE_SIZE) >= \
382 (((size_t) (((uint8_t*) old) - pool->memory)) + old_size)); 419 (((size_t) (((uint8_t*) old) - pool->memory)) + old_size));
383 /* Blocks "from the end" must not be reallocated */ 420 /* Blocks "from the end" must not be reallocated */
384 /* (old == NULL || old_size == 0 || pool->memory + pool->pos > (uint8_t*) old) */ 421 /* (old == NULL || old_size == 0 || pool->memory + pool->pos > (uint8_t*) old) */
@@ -386,7 +423,7 @@ MHD_pool_reallocate (struct MemoryPool *pool,
386 pool->pos > (size_t) ((uint8_t*) old - pool->memory)); 423 pool->pos > (size_t) ((uint8_t*) old - pool->memory));
387 mhd_assert (old == NULL || old_size == 0 || \ 424 mhd_assert (old == NULL || old_size == 0 || \
388 (size_t) (((uint8_t*) old) - pool->memory) + old_size <= \ 425 (size_t) (((uint8_t*) old) - pool->memory) + old_size <= \
389 pool->end); 426 pool->end - _MHD_RED_ZONE_SIZE);
390 427
391 if (0 != old_size) 428 if (0 != old_size)
392 { /* Have previously allocated data */ 429 { /* Have previously allocated data */
@@ -396,10 +433,13 @@ MHD_pool_reallocate (struct MemoryPool *pool,
396 if (shrinking) 433 if (shrinking)
397 { /* Shrinking in-place, zero-out freed part */ 434 { /* Shrinking in-place, zero-out freed part */
398 memset ((uint8_t*) old + new_size, 0, old_size - new_size); 435 memset ((uint8_t*) old + new_size, 0, old_size - new_size);
436 _MHD_POISON_MEMORY ((uint8_t*) old + new_size, old_size - new_size);
399 } 437 }
400 if (pool->pos == ROUND_TO_ALIGN (old_offset + old_size)) 438 if (pool->pos ==
439 ROUND_TO_ALIGN_PLUS_RED_ZONE (old_offset + old_size))
401 { /* "old" block is the last allocated block */ 440 { /* "old" block is the last allocated block */
402 const size_t new_apos = ROUND_TO_ALIGN (old_offset + new_size); 441 const size_t new_apos =
442 ROUND_TO_ALIGN_PLUS_RED_ZONE (old_offset + new_size);
403 if (! shrinking) 443 if (! shrinking)
404 { /* Grow in-place, check for enough space. */ 444 { /* Grow in-place, check for enough space. */
405 if ( (new_apos > pool->end) || 445 if ( (new_apos > pool->end) ||
@@ -408,13 +448,14 @@ MHD_pool_reallocate (struct MemoryPool *pool,
408 } 448 }
409 /* Resized in-place */ 449 /* Resized in-place */
410 pool->pos = new_apos; 450 pool->pos = new_apos;
451 _MHD_UNPOISON_MEMORY (old, new_size);
411 return old; 452 return old;
412 } 453 }
413 if (shrinking) 454 if (shrinking)
414 return old; /* Resized in-place, freed part remains allocated */ 455 return old; /* Resized in-place, freed part remains allocated */
415 } 456 }
416 /* Need to allocate new block */ 457 /* Need to allocate new block */
417 asize = ROUND_TO_ALIGN (new_size); 458 asize = ROUND_TO_ALIGN_PLUS_RED_ZONE (new_size);
418 if ( ( (0 == asize) && 459 if ( ( (0 == asize) &&
419 (0 != new_size) ) || /* Value wrap, too large new_size. */ 460 (0 != new_size) ) || /* Value wrap, too large new_size. */
420 (asize > pool->end - pool->pos) ) /* Not enough space */ 461 (asize > pool->end - pool->pos) ) /* Not enough space */
@@ -423,12 +464,14 @@ MHD_pool_reallocate (struct MemoryPool *pool,
423 new_blc = pool->memory + pool->pos; 464 new_blc = pool->memory + pool->pos;
424 pool->pos += asize; 465 pool->pos += asize;
425 466
467 _MHD_UNPOISON_MEMORY (new_blc, new_size);
426 if (0 != old_size) 468 if (0 != old_size)
427 { 469 {
428 /* Move data to new block, old block remains allocated */ 470 /* Move data to new block, old block remains allocated */
429 memcpy (new_blc, old, old_size); 471 memcpy (new_blc, old, old_size);
430 /* Zero-out old block */ 472 /* Zero-out old block */
431 memset (old, 0, old_size); 473 memset (old, 0, old_size);
474 _MHD_POISON_MEMORY (old, old_size);
432 } 475 }
433 return new_blc; 476 return new_blc;
434} 477}
@@ -447,7 +490,7 @@ MHD_pool_reallocate (struct MemoryPool *pool,
447 * (should be larger or equal to @a copy_bytes) 490 * (should be larger or equal to @a copy_bytes)
448 * @return addr new address of @a keep (if it had to change) 491 * @return addr new address of @a keep (if it had to change)
449 */ 492 */
450void * 493_MHD_NOSANITIZE_PTRS void *
451MHD_pool_reset (struct MemoryPool *pool, 494MHD_pool_reset (struct MemoryPool *pool,
452 void *keep, 495 void *keep,
453 size_t copy_bytes, 496 size_t copy_bytes,
@@ -463,6 +506,7 @@ MHD_pool_reset (struct MemoryPool *pool,
463 mhd_assert (keep == NULL || \ 506 mhd_assert (keep == NULL || \
464 pool->size >= \ 507 pool->size >= \
465 ((size_t) ((uint8_t*) keep - pool->memory)) + copy_bytes); 508 ((size_t) ((uint8_t*) keep - pool->memory)) + copy_bytes);
509 _MHD_UNPOISON_MEMORY (pool->memory, new_size);
466 if ( (NULL != keep) && 510 if ( (NULL != keep) &&
467 (keep != pool->memory) ) 511 (keep != pool->memory) )
468 { 512 {
@@ -477,6 +521,7 @@ MHD_pool_reset (struct MemoryPool *pool,
477 size_t to_zero; /** Size of area to zero-out */ 521 size_t to_zero; /** Size of area to zero-out */
478 522
479 to_zero = pool->size - copy_bytes; 523 to_zero = pool->size - copy_bytes;
524 _MHD_UNPOISON_MEMORY (pool->memory + copy_bytes, to_zero);
480#ifdef _WIN32 525#ifdef _WIN32
481 if (pool->is_mmap) 526 if (pool->is_mmap)
482 { 527 {
@@ -506,8 +551,10 @@ MHD_pool_reset (struct MemoryPool *pool,
506 0, 551 0,
507 to_zero); 552 to_zero);
508 } 553 }
509 pool->pos = ROUND_TO_ALIGN (new_size); 554 pool->pos = ROUND_TO_ALIGN_PLUS_RED_ZONE (new_size);
510 pool->end = pool->size; 555 pool->end = pool->size;
556 _MHD_POISON_MEMORY (((uint8_t*) pool->memory) + new_size, \
557 pool->size - new_size);
511 return pool->memory; 558 return pool->memory;
512} 559}
513 560
diff --git a/src/testcurl/test_toolarge.c b/src/testcurl/test_toolarge.c
index 70b37ff9..4294010a 100644
--- a/src/testcurl/test_toolarge.c
+++ b/src/testcurl/test_toolarge.c
@@ -193,8 +193,14 @@ _mhdErrorExit_func (const char *errDesc, const char *funcName, int lineNum)
193 193
194#define BUFFER_SIZE 1024 194#define BUFFER_SIZE 1024
195 195
196#define MHD_ASAN_ACTIVE 1
197
196/* The size of the test element that must pass the test */ 198/* The size of the test element that must pass the test */
199#ifndef MHD_ASAN_POISON_ACTIVE
197#define TEST_OK_SIZE (BUFFER_SIZE - 384) 200#define TEST_OK_SIZE (BUFFER_SIZE - 384)
201#else /* MHD_ASAN_POISON_ACTIVE */
202#define TEST_OK_SIZE (BUFFER_SIZE - 384 - 80)
203#endif /* MHD_ASAN_POISON_ACTIVE */
198 204
199/* The size of the test element where tests are started */ 205/* The size of the test element where tests are started */
200#define TEST_START_SIZE (TEST_OK_SIZE - 16) 206#define TEST_START_SIZE (TEST_OK_SIZE - 16)