diff options
author | Evgeny Grin (Karlson2k) <k2k@narod.ru> | 2022-11-24 11:59:38 +0300 |
---|---|---|
committer | Evgeny Grin (Karlson2k) <k2k@narod.ru> | 2022-11-26 20:02:17 +0300 |
commit | 3444792f14d96a58648add92b8f3b70e4babf772 (patch) | |
tree | a49de37a14d040cc2073e0caaf16f834cf277ac8 | |
parent | 49c675a0e98daecef2d89f7f187b3c899648684a (diff) | |
download | libmicrohttpd-3444792f14d96a58648add92b8f3b70e4babf772.tar.gz libmicrohttpd-3444792f14d96a58648add92b8f3b70e4babf772.zip |
Refactored user-poison: minimized scope of non-sanitized code
-rw-r--r-- | configure.ac | 246 | ||||
-rw-r--r-- | src/include/mhd_options.h | 7 | ||||
-rw-r--r-- | src/microhttpd/memorypool.c | 120 |
3 files changed, 308 insertions, 65 deletions
diff --git a/configure.ac b/configure.ac index cf261ead..b032badc 100644 --- a/configure.ac +++ b/configure.ac | |||
@@ -3995,39 +3995,167 @@ AS_VAR_IF([enable_sanitizers], ["no"], [:], | |||
3995 | AS_VAR_IF([enable_san_upoison], ["no"], [:], | 3995 | AS_VAR_IF([enable_san_upoison], ["no"], [:], |
3996 | [ | 3996 | [ |
3997 | AC_CHECK_HEADERS([sanitizer/asan_interface.h], [], [], [AC_INCLUDES_DEFAULT]) | 3997 | AC_CHECK_HEADERS([sanitizer/asan_interface.h], [], [], [AC_INCLUDES_DEFAULT]) |
3998 | AS_IF([test "x${mhd_cv_cc_sanitizer_pointer_compare}" = "xyes" && test "x${ac_cv_header_sanitizer_asan_interface_h}" = "xyes"], | 3998 | AS_VAR_IF([ac_cv_header_sanitizer_asan_interface_h],["yes"], |
3999 | [ | 3999 | [ |
4000 | AC_CACHE_CHECK([whether '__attribute__((no_sanitize("pointer-compare","pointer-subtract")))' works], [mhd_cv_func_attribute_nosanitize_ptr], | 4000 | AC_CACHE_CHECK([whether special function attribute is needed for user-poison], [mhd_cv_func_u_p_attribute_needed], |
4001 | [ | 4001 | [ |
4002 | ASAN_OPTIONS="exitcode=88:detect_invalid_pointer_pairs=3:halt_on_error=1" | 4002 | ASAN_OPTIONS="exitcode=88:detect_invalid_pointer_pairs=3:halt_on_error=1" |
4003 | export ASAN_OPTIONS | 4003 | export ASAN_OPTIONS |
4004 | CFLAGS="${CFLAGS_ac} ${san_CFLAGS} ${san_FLAGS} ${errattr_CFLAGS} ${user_CFLAGS}" | 4004 | CFLAGS="${CFLAGS_ac} ${san_CFLAGS} ${san_FLAGS} ${errattr_CFLAGS} ${user_CFLAGS}" |
4005 | AC_RUN_IFELSE( | 4005 | AC_RUN_IFELSE( |
4006 | [ | 4006 | [ |
4007 | AC_LANG_PROGRAM( | 4007 | AC_LANG_SOURCE( |
4008 | [[ | 4008 | [[ |
4009 | #include <stdint.h> | ||
4009 | #include <stdlib.h> | 4010 | #include <stdlib.h> |
4011 | #include <sanitizer/asan_interface.h> | ||
4010 | 4012 | ||
4011 | __attribute__((no_sanitize("pointer-compare","pointer-subtract"))) | 4013 | static const size_t first_pos = 0; |
4012 | int ptr_process(void *ptr1, void *ptr2) | 4014 | static const size_t mid_pos = 64; |
4015 | static const size_t last_pos = 128; | ||
4016 | static const size_t zone_size = 16; | ||
4017 | static const size_t buf_size = 128 + 16; | ||
4018 | |||
4019 | static int ptr_compare(void *ptr1, uint8_t *ptr2) | ||
4013 | { | 4020 | { |
4014 | if ((char*)ptr1 <= (char*)ptr2) | 4021 | if ((((uintptr_t) (uint8_t *)ptr1) >= ((uintptr_t)ptr2))) |
4015 | return (int) ((char*)ptr2 - (char*)ptr1); | 4022 | return ((char *) ptr1)[0] < ((char *) ptr2)[0]; |
4016 | return (int) ((char*)ptr1 - (char*)ptr2); | 4023 | return ((char *) ptr1)[0] > ((char *) ptr2)[0]; |
4017 | } | 4024 | } |
4018 | ]], | 4025 | |
4026 | static int ptr_subtract(void *ptr1, uint8_t *ptr2) | ||
4027 | { | ||
4028 | return ((size_t)(((uintptr_t)(uint8_t*)ptr1) - ((uintptr_t)ptr2))) <= last_pos; | ||
4029 | } | ||
4030 | |||
4031 | int main(int argc, char *argv[]) | ||
4032 | { | ||
4033 | char *buf = (char*) malloc (buf_size); | ||
4034 | char *a; | ||
4035 | char *b; | ||
4036 | int ret; | ||
4037 | |||
4038 | (void) argv; | ||
4039 | if (NULL == buf) | ||
4040 | return 10; | ||
4041 | ASAN_POISON_MEMORY_REGION (buf + first_pos + zone_size, mid_pos - first_pos - zone_size); | ||
4042 | ASAN_POISON_MEMORY_REGION (buf + mid_pos + zone_size, last_pos - mid_pos - zone_size); | ||
4043 | |||
4044 | if (0 < argc) | ||
4045 | a = buf + last_pos; | ||
4046 | else | ||
4047 | a = buf + first_pos; | ||
4048 | b = buf + mid_pos; | ||
4049 | |||
4050 | *a = '0'; | ||
4051 | *b = '9'; | ||
4052 | |||
4053 | if (ptr_compare((void *)a, (uint8_t*) b)) | ||
4054 | { | ||
4055 | if (ptr_subtract((void *)a, (uint8_t*) b)) | ||
4056 | ret = 0; | ||
4057 | else | ||
4058 | ret = 10; | ||
4059 | } | ||
4060 | else | ||
4061 | ret = 5; | ||
4062 | ASAN_UNPOISON_MEMORY_REGION (buf, buf_size); | ||
4063 | free (buf); | ||
4064 | |||
4065 | return ret; | ||
4066 | } | ||
4067 | ]] | ||
4068 | ) | ||
4069 | ], | ||
4070 | [mhd_cv_func_u_p_attribute_needed="no"], [mhd_cv_func_u_p_attribute_needed="yes"], | ||
4071 | [ | ||
4072 | # Cross-compiling with sanitizers?? | ||
4073 | mhd_cv_func_up_attribute_needed='assuming no' | ||
4074 | ] | ||
4075 | ) | ||
4076 | AS_UNSET([ASAN_OPTIONS]) | ||
4077 | ] | ||
4078 | ) | ||
4079 | ] | ||
4080 | ) | ||
4081 | AS_VAR_IF([mhd_cv_func_u_p_attribute_needed],["yes"],[:], | ||
4082 | [ | ||
4083 | AC_DEFINE([FUNC_PTRCOMPARE_CAST_WORKAROUND_WORKS],[1],[Define to '1' if cast to 'uintptr_t' works for safely processing user-poisoned pointer]) | ||
4084 | ] | ||
4085 | ) | ||
4086 | AS_IF([test "x${mhd_cv_func_u_p_attribute_needed}" = "xyes" && test "x${ac_cv_header_sanitizer_asan_interface_h}" = "xyes"], | ||
4087 | [ | ||
4088 | AC_CACHE_CHECK([whether '__attribute__((no_sanitize("pointer-compare")))' and '__attribute__((no_sanitize("pointer-subtract")))' work], | ||
4089 | [mhd_cv_func_attribute_nosanitize_ptr], | ||
4090 | [ | ||
4091 | ASAN_OPTIONS="exitcode=88:detect_invalid_pointer_pairs=3:halt_on_error=1" | ||
4092 | export ASAN_OPTIONS | ||
4093 | CFLAGS="${CFLAGS_ac} ${san_CFLAGS} ${san_FLAGS} ${errattr_CFLAGS} ${user_CFLAGS}" | ||
4094 | AC_RUN_IFELSE( | ||
4095 | [ | ||
4096 | AC_LANG_SOURCE( | ||
4019 | [[ | 4097 | [[ |
4020 | int *a = (int*) malloc (sizeof(int)*4); | 4098 | #include <stdint.h> |
4021 | int *b = (int*) malloc (sizeof(long)*6); | 4099 | #include <stdlib.h> |
4022 | int c = ptr_process(a, b); | 4100 | #include <sanitizer/asan_interface.h> |
4023 | if (c) | 4101 | |
4102 | static const size_t first_pos = 0; | ||
4103 | static const size_t mid_pos = 64; | ||
4104 | static const size_t last_pos = 128; | ||
4105 | static const size_t zone_size = 16; | ||
4106 | static const size_t buf_size = 128 + 16; | ||
4107 | |||
4108 | __attribute__((no_sanitize("pointer-compare"))) | ||
4109 | static int ptr_compare(void *ptr1, uint8_t *ptr2) | ||
4110 | { | ||
4111 | if ((((const uint8_t*)ptr1) >= ((const uint8_t*)ptr2))) | ||
4112 | return ((char *) ptr1)[0] < ((char *) ptr2)[0]; | ||
4113 | return ((char *) ptr1)[0] > ((char *) ptr2)[0]; | ||
4114 | } | ||
4115 | |||
4116 | __attribute__((no_sanitize("pointer-subtract"))) | ||
4117 | static int ptr_subtract(void *ptr1, uint8_t *ptr2) | ||
4118 | { | ||
4119 | return ((size_t)(((const uint8_t*)ptr1) - \ | ||
4120 | ((const uint8_t*)ptr2))) <= last_pos; | ||
4121 | } | ||
4122 | |||
4123 | int main(int argc, char *argv[]) | ||
4124 | { | ||
4125 | char *buf = (char*) malloc (buf_size); | ||
4126 | char *a; | ||
4127 | char *b; | ||
4128 | int ret; | ||
4129 | |||
4130 | (void) argv; | ||
4131 | if (NULL == buf) | ||
4132 | return 10; | ||
4133 | ASAN_POISON_MEMORY_REGION (buf + first_pos + zone_size, mid_pos - first_pos - zone_size); | ||
4134 | ASAN_POISON_MEMORY_REGION (buf + mid_pos + zone_size, last_pos - mid_pos - zone_size); | ||
4135 | |||
4136 | if (0 < argc) | ||
4137 | a = buf + last_pos; | ||
4138 | else | ||
4139 | a = buf + first_pos; | ||
4140 | b = buf + mid_pos; | ||
4141 | |||
4142 | *a = '0'; | ||
4143 | *b = '9'; | ||
4144 | |||
4145 | if (ptr_compare((void *)a, (uint8_t*) b)) | ||
4024 | { | 4146 | { |
4025 | free (b); | 4147 | if (ptr_subtract((void *)a, (uint8_t*) b)) |
4026 | free (a); | 4148 | ret = 0; |
4027 | return 0; | 4149 | else |
4150 | ret = 10; | ||
4028 | } | 4151 | } |
4029 | free (a); | 4152 | else |
4030 | free (b); | 4153 | ret = 5; |
4154 | ASAN_UNPOISON_MEMORY_REGION (buf, buf_size); | ||
4155 | free (buf); | ||
4156 | |||
4157 | return ret; | ||
4158 | } | ||
4031 | ]] | 4159 | ]] |
4032 | ) | 4160 | ) |
4033 | ], | 4161 | ], |
@@ -4041,7 +4169,10 @@ int ptr_process(void *ptr1, void *ptr2) | |||
4041 | ] | 4169 | ] |
4042 | ) | 4170 | ) |
4043 | AS_VAR_IF([mhd_cv_func_attribute_nosanitize_ptr], ["yes"], | 4171 | AS_VAR_IF([mhd_cv_func_attribute_nosanitize_ptr], ["yes"], |
4044 | [AC_DEFINE([FUNC_ATTR_PTRCOMPARE_WORKS],[1],[Define to '1' if '__attribute__((no_sanitize("pointer-compare","pointer-subtract")))' works])], | 4172 | [ |
4173 | AC_DEFINE([FUNC_ATTR_PTRCOMPARE_WORKS],[1],[Define to '1' if '__attribute__((no_sanitize("pointer-compare")))' works]) | ||
4174 | AC_DEFINE([FUNC_ATTR_PTRSUBTRACT_WORKS],[1],[Define to '1' if '__attribute__((no_sanitize("pointer-subtract")))' works]) | ||
4175 | ], | ||
4045 | [ | 4176 | [ |
4046 | AC_CACHE_CHECK([whether '__attribute__((no_sanitize("address")))' works for pointers compare], [mhd_cv_func_attribute_nosanitize_addr], | 4177 | AC_CACHE_CHECK([whether '__attribute__((no_sanitize("address")))' works for pointers compare], [mhd_cv_func_attribute_nosanitize_addr], |
4047 | [ | 4178 | [ |
@@ -4050,30 +4181,69 @@ int ptr_process(void *ptr1, void *ptr2) | |||
4050 | CFLAGS="${CFLAGS_ac} ${san_CFLAGS} ${san_FLAGS} ${errattr_CFLAGS} ${user_CFLAGS}" | 4181 | CFLAGS="${CFLAGS_ac} ${san_CFLAGS} ${san_FLAGS} ${errattr_CFLAGS} ${user_CFLAGS}" |
4051 | AC_RUN_IFELSE( | 4182 | AC_RUN_IFELSE( |
4052 | [ | 4183 | [ |
4053 | AC_LANG_PROGRAM( | 4184 | AC_LANG_SOURCE( |
4054 | [[ | 4185 | [[ |
4186 | #include <stdint.h> | ||
4055 | #include <stdlib.h> | 4187 | #include <stdlib.h> |
4188 | #include <sanitizer/asan_interface.h> | ||
4189 | |||
4190 | static const size_t first_pos = 0; | ||
4191 | static const size_t mid_pos = 64; | ||
4192 | static const size_t last_pos = 128; | ||
4193 | static const size_t zone_size = 16; | ||
4194 | static const size_t buf_size = 128 + 16; | ||
4056 | 4195 | ||
4057 | __attribute__((no_sanitize("address"))) | 4196 | __attribute__((no_sanitize("address"))) |
4058 | int ptr_process(void *ptr1, void *ptr2) | 4197 | static int ptr_compare(void *ptr1, uint8_t *ptr2) |
4059 | { | 4198 | { |
4060 | if ((char*)ptr1 <= (char*)ptr2) | 4199 | if ((((const uint8_t*)ptr1) >= ((const uint8_t*)ptr2))) |
4061 | return (int) ((char*)ptr2 - (char*)ptr1); | 4200 | return ((char *) ptr1)[0] < ((char *) ptr2)[0]; |
4062 | return (int) ((char*)ptr1 - (char*)ptr2); | 4201 | return ((char *) ptr1)[0] > ((char *) ptr2)[0]; |
4063 | } | 4202 | } |
4064 | ]], | 4203 | |
4065 | [[ | 4204 | __attribute__((no_sanitize("address"))) |
4066 | int *a = (int*) malloc (sizeof(int)*4); | 4205 | static int ptr_subtract(void *ptr1, uint8_t *ptr2) |
4067 | int *b = (int*) malloc (sizeof(long)*6); | 4206 | { |
4068 | int c = ptr_process(a, b); | 4207 | return ((size_t)(((const uint8_t*)ptr1) - \ |
4069 | if (c) | 4208 | ((const uint8_t*)ptr2))) <= last_pos; |
4209 | } | ||
4210 | |||
4211 | int main(int argc, char *argv[]) | ||
4212 | { | ||
4213 | char *buf = (char*) malloc (buf_size); | ||
4214 | char *a; | ||
4215 | char *b; | ||
4216 | int ret; | ||
4217 | |||
4218 | (void) argv; | ||
4219 | if (NULL == buf) | ||
4220 | return 10; | ||
4221 | ASAN_POISON_MEMORY_REGION (buf + first_pos + zone_size, mid_pos - first_pos - zone_size); | ||
4222 | ASAN_POISON_MEMORY_REGION (buf + mid_pos + zone_size, last_pos - mid_pos - zone_size); | ||
4223 | |||
4224 | if (0 < argc) | ||
4225 | a = buf + last_pos; | ||
4226 | else | ||
4227 | a = buf + first_pos; | ||
4228 | b = buf + mid_pos; | ||
4229 | |||
4230 | *a = '0'; | ||
4231 | *b = '9'; | ||
4232 | |||
4233 | if (ptr_compare((void *)a, (uint8_t*) b)) | ||
4070 | { | 4234 | { |
4071 | free (b); | 4235 | if (ptr_subtract((void *)a, (uint8_t*) b)) |
4072 | free (a); | 4236 | ret = 0; |
4073 | return 0; | 4237 | else |
4238 | ret = 10; | ||
4074 | } | 4239 | } |
4075 | free (a); | 4240 | else |
4076 | free (b); | 4241 | ret = 5; |
4242 | ASAN_UNPOISON_MEMORY_REGION (buf, buf_size); | ||
4243 | free (buf); | ||
4244 | |||
4245 | return ret; | ||
4246 | } | ||
4077 | ]] | 4247 | ]] |
4078 | ) | 4248 | ) |
4079 | ], | 4249 | ], |
@@ -4263,9 +4433,9 @@ int main(void) | |||
4263 | AS_VAR_IF([enable_san_upoison], ["no"], [:], | 4433 | AS_VAR_IF([enable_san_upoison], ["no"], [:], |
4264 | [ | 4434 | [ |
4265 | AC_MSG_CHECKING([whether to enable user memory poisoning]) | 4435 | AC_MSG_CHECKING([whether to enable user memory poisoning]) |
4266 | AS_IF([test "x${mhd_cv_cc_sanitizer_address}" = "xyes" && test "x${mhd_cv_cc_sanitizer_pointer_compare}" = "xyes" && \ | 4436 | AS_IF([test "x${mhd_cv_cc_sanitizer_address}" = "xyes" && test "x${ac_cv_header_sanitizer_asan_interface_h}" = "xyes" && \ |
4267 | test "x${ac_cv_header_sanitizer_asan_interface_h}" = "xyes" && \ | 4437 | (test "x${mhd_cv_func_u_p_attribute_needed}" != "xyes" || test "x${mhd_cv_func_attribute_nosanitize_ptr}" = "xyes" || \ |
4268 | (test "x${mhd_cv_func_attribute_nosanitize_ptr}" = "xyes" || test "x${mhd_cv_func_attribute_nosanitize_addr}" = "xyes")], | 4438 | test "x${mhd_cv_func_attribute_nosanitize_addr}" = "xyes")], |
4269 | [ | 4439 | [ |
4270 | AC_DEFINE([MHD_ASAN_POISON_ACTIVE], [1], [Define to '1' if user memory poison is used]) | 4440 | AC_DEFINE([MHD_ASAN_POISON_ACTIVE], [1], [Define to '1' if user memory poison is used]) |
4271 | enabled_sanitizers="${enabled_sanitizers}${enabled_sanitizers:+, }user-poison" | 4441 | enabled_sanitizers="${enabled_sanitizers}${enabled_sanitizers:+, }user-poison" |
diff --git a/src/include/mhd_options.h b/src/include/mhd_options.h index 85ad6555..5a5b7fee 100644 --- a/src/include/mhd_options.h +++ b/src/include/mhd_options.h | |||
@@ -156,9 +156,12 @@ | |||
156 | #endif /* MHD_ASAN_ACTIVE */ | 156 | #endif /* MHD_ASAN_ACTIVE */ |
157 | 157 | ||
158 | #if defined(MHD_ASAN_ACTIVE) && defined(HAVE_SANITIZER_ASAN_INTERFACE_H) && \ | 158 | #if defined(MHD_ASAN_ACTIVE) && defined(HAVE_SANITIZER_ASAN_INTERFACE_H) && \ |
159 | (defined(FUNC_ATTR_PTRCOMPARE_WORKS) || defined(FUNC_ATTR_NOSANITIZE_WORKS)) | 159 | (defined(FUNC_PTRCOMPARE_CAST_WORKAROUND_WORKS) || \ |
160 | (defined(FUNC_ATTR_PTRCOMPARE_WORKS) && \ | ||
161 | defined(FUNC_ATTR_PTRSUBTRACT_WORKS)) || \ | ||
162 | defined(FUNC_ATTR_NOSANITIZE_WORKS)) | ||
160 | #ifndef MHD_ASAN_POISON_ACTIVE | 163 | #ifndef MHD_ASAN_POISON_ACTIVE |
161 | /* Manual ASAN poisoning could be used */ | 164 | /* User ASAN poisoning could be used */ |
162 | #warning User memory poisoning is not active | 165 | #warning User memory poisoning is not active |
163 | #endif /* ! MHD_ASAN_POISON_ACTIVE */ | 166 | #endif /* ! MHD_ASAN_POISON_ACTIVE */ |
164 | #else /* ! (MHD_ASAN_ACTIVE && HAVE_SANITIZER_ASAN_INTERFACE_H && | 167 | #else /* ! (MHD_ASAN_ACTIVE && HAVE_SANITIZER_ASAN_INTERFACE_H && |
diff --git a/src/microhttpd/memorypool.c b/src/microhttpd/memorypool.c index 5d656b47..92ec6edc 100644 --- a/src/microhttpd/memorypool.c +++ b/src/microhttpd/memorypool.c | |||
@@ -102,19 +102,92 @@ | |||
102 | #define ROUND_TO_ALIGN_PLUS_RED_ZONE(n) ROUND_TO_ALIGN(n) | 102 | #define ROUND_TO_ALIGN_PLUS_RED_ZONE(n) ROUND_TO_ALIGN(n) |
103 | #define _MHD_POISON_MEMORY(pointer, size) (void)0 | 103 | #define _MHD_POISON_MEMORY(pointer, size) (void)0 |
104 | #define _MHD_UNPOISON_MEMORY(pointer, size) (void)0 | 104 | #define _MHD_UNPOISON_MEMORY(pointer, size) (void)0 |
105 | /** | ||
106 | * Boolean 'true' if the first pointer is less or equal the second pointer | ||
107 | */ | ||
108 | #define mp_ptr_le_(p1,p2) \ | ||
109 | (((const uint8_t*)p1) <= ((const uint8_t*)p2)) | ||
110 | /** | ||
111 | * The difference in bytes between positions of the first and | ||
112 | * the second pointers | ||
113 | */ | ||
114 | #define mp_ptr_diff_(p1,p2) \ | ||
115 | ((size_t)(((const uint8_t*)p1) - ((const uint8_t*)p2))) | ||
105 | #else /* MHD_ASAN_POISON_ACTIVE */ | 116 | #else /* MHD_ASAN_POISON_ACTIVE */ |
106 | #if defined(FUNC_ATTR_PTRCOMPARE_WORKS) | ||
107 | #define _MHD_NOSANITIZE_PTRS \ | ||
108 | __attribute__((no_sanitize("pointer-compare","pointer-subtract"))) | ||
109 | #elif defined(FUNC_ATTR_NOSANITIZE_WORKS) | ||
110 | #define _MHD_NOSANITIZE_PTRS __attribute__((no_sanitize("address"))) | ||
111 | #endif | ||
112 | #define _MHD_RED_ZONE_SIZE (ALIGN_SIZE) | 117 | #define _MHD_RED_ZONE_SIZE (ALIGN_SIZE) |
113 | #define ROUND_TO_ALIGN_PLUS_RED_ZONE(n) (ROUND_TO_ALIGN(n) + _MHD_RED_ZONE_SIZE) | 118 | #define ROUND_TO_ALIGN_PLUS_RED_ZONE(n) (ROUND_TO_ALIGN(n) + _MHD_RED_ZONE_SIZE) |
114 | #define _MHD_POISON_MEMORY(pointer, size) \ | 119 | #define _MHD_POISON_MEMORY(pointer, size) \ |
115 | ASAN_POISON_MEMORY_REGION ((pointer), (size)) | 120 | ASAN_POISON_MEMORY_REGION ((pointer), (size)) |
116 | #define _MHD_UNPOISON_MEMORY(pointer, size) \ | 121 | #define _MHD_UNPOISON_MEMORY(pointer, size) \ |
117 | ASAN_UNPOISON_MEMORY_REGION ((pointer), (size)) | 122 | ASAN_UNPOISON_MEMORY_REGION ((pointer), (size)) |
123 | #if defined(FUNC_PTRCOMPARE_CAST_WORKAROUND_WORKS) | ||
124 | /** | ||
125 | * Boolean 'true' if the first pointer is less or equal the second pointer | ||
126 | */ | ||
127 | #define mp_ptr_le_(p1,p2) \ | ||
128 | (((uintptr_t)((const void*)(p1))) <= ((uintptr_t)((const void*)(p1)))) | ||
129 | /** | ||
130 | * The difference in bytes between positions of the first and | ||
131 | * the second pointers | ||
132 | */ | ||
133 | #define mp_ptr_diff_(p1,p2) \ | ||
134 | ((size_t)(((uintptr_t)((const uint8_t*)p1)) - \ | ||
135 | ((uintptr_t)((const uint8_t*)p2)))) | ||
136 | #elif defined(FUNC_ATTR_PTRCOMPARE_WORKS) && \ | ||
137 | defined(FUNC_ATTR_PTRSUBTRACT_WORKS) | ||
138 | #ifdef _DEBUG | ||
139 | /** | ||
140 | * Boolean 'true' if the first pointer is less or equal the second pointer | ||
141 | */ | ||
142 | __attribute__((no_sanitize ("pointer-compare"))) static bool | ||
143 | mp_ptr_le_ (const void *p1, const void *p2) | ||
144 | { | ||
145 | return (((const uint8_t *) p1) <= ((const uint8_t *) p2)); | ||
146 | } | ||
147 | |||
148 | |||
149 | #endif /* _DEBUG */ | ||
150 | |||
151 | |||
152 | /** | ||
153 | * The difference in bytes between positions of the first and | ||
154 | * the second pointers | ||
155 | */ | ||
156 | __attribute__((no_sanitize ("pointer-subtract"))) static size_t | ||
157 | mp_ptr_diff_ (const void *p1, const void *p2) | ||
158 | { | ||
159 | return (size_t) (((const uint8_t *) p1) - ((const uint8_t *) p2)); | ||
160 | } | ||
161 | |||
162 | |||
163 | #elif defined(FUNC_ATTR_NOSANITIZE_WORKS) | ||
164 | #ifdef _DEBUG | ||
165 | /** | ||
166 | * Boolean 'true' if the first pointer is less or equal the second pointer | ||
167 | */ | ||
168 | __attribute__((no_sanitize ("address"))) static bool | ||
169 | mp_ptr_le_ (const void *p1, const void *p2) | ||
170 | { | ||
171 | return (((const uint8_t *) p1) <= ((const uint8_t *) p2)); | ||
172 | } | ||
173 | |||
174 | |||
175 | #endif /* _DEBUG */ | ||
176 | |||
177 | /** | ||
178 | * The difference in bytes between positions of the first and | ||
179 | * the second pointers | ||
180 | */ | ||
181 | __attribute__((no_sanitize ("address"))) static size_t | ||
182 | mp_ptr_diff_ (const void *p1, const void *p2) | ||
183 | { | ||
184 | return (size_t) (((const uint8_t *) p1) - ((const uint8_t *) p2)); | ||
185 | } | ||
186 | |||
187 | |||
188 | #else /* ! FUNC_ATTR_NOSANITIZE_WORKS */ | ||
189 | #error User-poisoning cannot be used | ||
190 | #endif /* ! FUNC_ATTR_NOSANITIZE_WORKS */ | ||
118 | #endif /* MHD_ASAN_POISON_ACTIVE */ | 191 | #endif /* MHD_ASAN_POISON_ACTIVE */ |
119 | 192 | ||
120 | /** | 193 | /** |
@@ -419,7 +492,7 @@ MHD_pool_try_alloc (struct MemoryPool *pool, | |||
419 | * NULL if the pool cannot support @a new_size | 492 | * NULL if the pool cannot support @a new_size |
420 | * bytes (old continues to be valid for @a old_size) | 493 | * bytes (old continues to be valid for @a old_size) |
421 | */ | 494 | */ |
422 | _MHD_NOSANITIZE_PTRS void * | 495 | void * |
423 | MHD_pool_reallocate (struct MemoryPool *pool, | 496 | MHD_pool_reallocate (struct MemoryPool *pool, |
424 | void *old, | 497 | void *old, |
425 | size_t old_size, | 498 | size_t old_size, |
@@ -432,23 +505,21 @@ MHD_pool_reallocate (struct MemoryPool *pool, | |||
432 | mhd_assert (pool->size >= pool->end - pool->pos); | 505 | mhd_assert (pool->size >= pool->end - pool->pos); |
433 | mhd_assert (old != NULL || old_size == 0); | 506 | mhd_assert (old != NULL || old_size == 0); |
434 | mhd_assert (pool->size >= old_size); | 507 | mhd_assert (pool->size >= old_size); |
435 | mhd_assert (old == NULL || pool->memory <= (uint8_t *) old); | ||
436 | /* (old == NULL || pool->memory + pool->size >= (uint8_t*) old + old_size) */ | ||
437 | mhd_assert (old == NULL || \ | ||
438 | (pool->size - _MHD_RED_ZONE_SIZE) >= \ | ||
439 | (((size_t) (((uint8_t *) old) - pool->memory)) + old_size)); | ||
440 | /* Blocks "from the end" must not be reallocated */ | ||
441 | /* (old == NULL || old_size == 0 || pool->memory + pool->pos > (uint8_t*) old) */ | ||
442 | mhd_assert (old == NULL || old_size == 0 || \ | ||
443 | pool->pos > (size_t) ((uint8_t *) old - pool->memory)); | ||
444 | mhd_assert (old == NULL || old_size == 0 || \ | ||
445 | (size_t) (((uint8_t *) old) - pool->memory) + old_size <= \ | ||
446 | pool->end - _MHD_RED_ZONE_SIZE); | ||
447 | 508 | ||
448 | if (NULL != old) | 509 | if (NULL != old) |
449 | { /* Have previously allocated data */ | 510 | { /* Have previously allocated data */ |
450 | const size_t old_offset = (size_t) (((uint8_t *) old) - pool->memory); | 511 | const size_t old_offset = mp_ptr_diff_ (old, pool->memory); |
451 | const bool shrinking = (old_size > new_size); | 512 | const bool shrinking = (old_size > new_size); |
513 | |||
514 | mhd_assert (mp_ptr_le_ (pool->memory, old)); | ||
515 | /* (pool->memory + pool->size >= (uint8_t*) old + old_size) */ | ||
516 | mhd_assert ((pool->size - _MHD_RED_ZONE_SIZE) >= (old_offset + old_size)); | ||
517 | /* Blocks "from the end" must not be reallocated */ | ||
518 | /* (old_size == 0 || pool->memory + pool->pos > (uint8_t*) old) */ | ||
519 | mhd_assert ((old_size == 0) || \ | ||
520 | (pool->pos > old_offset)); | ||
521 | mhd_assert ((old_size == 0) || \ | ||
522 | ((pool->end - _MHD_RED_ZONE_SIZE) >= (old_offset + old_size))); | ||
452 | /* Try resizing in-place */ | 523 | /* Try resizing in-place */ |
453 | if (shrinking) | 524 | if (shrinking) |
454 | { /* Shrinking in-place, zero-out freed part */ | 525 | { /* Shrinking in-place, zero-out freed part */ |
@@ -510,7 +581,7 @@ MHD_pool_reallocate (struct MemoryPool *pool, | |||
510 | * (should be larger or equal to @a copy_bytes) | 581 | * (should be larger or equal to @a copy_bytes) |
511 | * @return addr new address of @a keep (if it had to change) | 582 | * @return addr new address of @a keep (if it had to change) |
512 | */ | 583 | */ |
513 | _MHD_NOSANITIZE_PTRS void * | 584 | void * |
514 | MHD_pool_reset (struct MemoryPool *pool, | 585 | MHD_pool_reset (struct MemoryPool *pool, |
515 | void *keep, | 586 | void *keep, |
516 | size_t copy_bytes, | 587 | size_t copy_bytes, |
@@ -521,11 +592,10 @@ MHD_pool_reset (struct MemoryPool *pool, | |||
521 | mhd_assert (copy_bytes <= new_size); | 592 | mhd_assert (copy_bytes <= new_size); |
522 | mhd_assert (copy_bytes <= pool->size); | 593 | mhd_assert (copy_bytes <= pool->size); |
523 | mhd_assert (keep != NULL || copy_bytes == 0); | 594 | mhd_assert (keep != NULL || copy_bytes == 0); |
524 | mhd_assert (keep == NULL || pool->memory <= (uint8_t *) keep); | 595 | mhd_assert (keep == NULL || mp_ptr_le_ (pool->memory, keep)); |
525 | /* (keep == NULL || pool->memory + pool->size >= (uint8_t*) keep + copy_bytes) */ | 596 | /* (keep == NULL || pool->memory + pool->size >= (uint8_t*) keep + copy_bytes) */ |
526 | mhd_assert (keep == NULL || \ | 597 | mhd_assert ((keep == NULL) || \ |
527 | pool->size >= \ | 598 | (pool->size >= mp_ptr_diff_ (keep, pool->memory) + copy_bytes)); |
528 | ((size_t) ((uint8_t *) keep - pool->memory)) + copy_bytes); | ||
529 | _MHD_UNPOISON_MEMORY (pool->memory, new_size); | 599 | _MHD_UNPOISON_MEMORY (pool->memory, new_size); |
530 | if ( (NULL != keep) && | 600 | if ( (NULL != keep) && |
531 | (keep != pool->memory) ) | 601 | (keep != pool->memory) ) |