diff options
Diffstat (limited to 'src/microhttpd/memorypool.c')
-rw-r--r-- | src/microhttpd/memorypool.c | 120 |
1 files changed, 95 insertions, 25 deletions
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) ) |