diff options
author | Evgeny Grin (Karlson2k) <k2k@narod.ru> | 2021-10-10 21:16:25 +0300 |
---|---|---|
committer | Evgeny Grin (Karlson2k) <k2k@narod.ru> | 2021-10-10 21:16:25 +0300 |
commit | 50c9e5efea6913cf97b4b1afd8c57f886f552d32 (patch) | |
tree | ae6e689a7f9a61b1cfd5ee88bf3299837af37ee9 | |
parent | fe8a9c6181424520383dd7ff7e30a082158e4b04 (diff) | |
download | libmicrohttpd-50c9e5efea6913cf97b4b1afd8c57f886f552d32.tar.gz libmicrohttpd-50c9e5efea6913cf97b4b1afd8c57f886f552d32.zip |
Added custom memory poisoning for MemoryPool
-rw-r--r-- | configure.ac | 111 | ||||
-rw-r--r-- | src/include/mhd_options.h | 27 | ||||
-rw-r--r-- | src/microhttpd/memorypool.c | 75 | ||||
-rw-r--r-- | src/testcurl/test_toolarge.c | 6 |
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"))) | ||
2710 | int 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"))) | ||
2756 | int 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 | */ |
317 | void * | 351 | void * |
@@ -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 | */ |
365 | void * | 402 | _MHD_NOSANITIZE_PTRS void * |
366 | MHD_pool_reallocate (struct MemoryPool *pool, | 403 | MHD_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 | */ |
450 | void * | 493 | _MHD_NOSANITIZE_PTRS void * |
451 | MHD_pool_reset (struct MemoryPool *pool, | 494 | MHD_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) |