Implemented and used new function MHD_pool_deallocate()

The new function has special handling for user-poison mode.
This commit is contained in:
Evgeny Grin (Karlson2k)
2023-04-05 19:44:49 +03:00
parent 95ad2a9a48
commit edf692a616
5 changed files with 155 additions and 29 deletions
+3
View File
@@ -4304,6 +4304,9 @@ AS_VAR_IF([enable_sanitizers], ["no"], [:],
AS_VAR_IF([ac_cv_header_sanitizer_asan_interface_h],["yes"],
[
CFLAGS="${CFLAGS_ac} ${san_CFLAGS} ${san_FLAGS} ${errattr_CFLAGS} ${user_CFLAGS}"
MHD_CHECK_FUNC([__asan_address_is_poisoned],[[#include <sanitizer/asan_interface.h>]],
[[int a_var=1; i][f(__asan_address_is_poisoned((void*) &a_var)) return 3;]]
)
MHD_CHECK_FUNC([__asan_region_is_poisoned],[[#include <sanitizer/asan_interface.h>]],
[[int a_var=1; i][f(((void*) 0) != __asan_region_is_poisoned((void*) &a_var, sizeof(a_var))) return 3;]]
)
+18 -9
View File
@@ -1597,11 +1597,20 @@ connection_shrink_read_buffer (struct MHD_Connection *connection)
}
mhd_assert (c->read_buffer_offset <= c->read_buffer_size);
new_buf = MHD_pool_reallocate (c->pool, c->read_buffer, c->read_buffer_size,
c->read_buffer_offset);
mhd_assert (c->read_buffer == new_buf);
c->read_buffer = new_buf;
c->read_buffer_size = c->read_buffer_offset;
if (0 == c->read_buffer_offset)
{
MHD_pool_deallocate (c->pool, c->read_buffer, c->read_buffer_size);
c->read_buffer = NULL;
c->read_buffer_size = 0;
}
else
{
new_buf = MHD_pool_reallocate (c->pool, c->read_buffer, c->read_buffer_size,
c->read_buffer_offset);
mhd_assert (c->read_buffer == new_buf);
c->read_buffer = new_buf;
c->read_buffer_size = c->read_buffer_offset;
}
}
@@ -2424,10 +2433,10 @@ transmit_error_response_len (struct MHD_Connection *connection,
{
/* Read buffer is not needed anymore, discard it
* to free some space for error response. */
connection->read_buffer = MHD_pool_reallocate (connection->pool,
connection->read_buffer,
connection->read_buffer_size,
0);
MHD_pool_deallocate (connection->pool,
connection->read_buffer,
connection->read_buffer_size);
connection->read_buffer = NULL;
connection->read_buffer_size = 0;
connection->read_buffer_offset = 0;
}
+103
View File
@@ -576,6 +576,109 @@ MHD_pool_reallocate (struct MemoryPool *pool,
}
/**
* Deallocate a block of memory obtained from the pool.
*
* If the given block is not the most recently
* (re)allocated block, the memory of the this block
* allocation may be not released until the pool is
* destroyed or reset.
*
* @param pool memory pool to use for the operation
* @param block the allocated block, the NULL is tolerated
* @param block_size the size of the allocated block
*/
void
MHD_pool_deallocate (struct MemoryPool *pool,
void *block,
size_t block_size)
{
mhd_assert (pool->end >= pool->pos);
mhd_assert (pool->size >= pool->end - pool->pos);
mhd_assert (block != NULL || block_size == 0);
mhd_assert (pool->size >= block_size);
mhd_assert (pool->pos == ROUND_TO_ALIGN (pool->pos));
if (NULL != block)
{ /* Have previously allocated data */
const size_t block_offset = mp_ptr_diff_ (block, pool->memory);
mhd_assert (mp_ptr_le_ (pool->memory, block));
mhd_assert (block_offset <= pool->size);
mhd_assert ((block_offset != pool->pos) || (block_size == 0));
/* Zero-out deallocated region */
if (0 != block_size)
{
memset (block, 0, block_size);
_MHD_POISON_MEMORY (block, block_size);
}
#if ! defined(MHD_FAVOR_SMALL_CODE) && ! defined(MHD_ASAN_POISON_ACTIVE)
else
return; /* Zero size, no need to do anything */
#endif /* ! MHD_FAVOR_SMALL_CODE && ! MHD_ASAN_POISON_ACTIVE */
if (block_offset <= pool->pos)
{
/* "Normal" block, not allocated "from the end". */
const size_t alg_end =
ROUND_TO_ALIGN_PLUS_RED_ZONE (block_offset + block_size);
mhd_assert (alg_end <= pool->pos);
if (alg_end == pool->pos)
{
/* The last allocated block, return deallocated block to the pool */
size_t alg_start = ROUND_TO_ALIGN (block_offset);
mhd_assert (alg_start >= block_offset);
#if defined(MHD_ASAN_POISON_ACTIVE)
if (alg_start != block_offset)
{
_MHD_POISON_MEMORY (pool->memory + block_offset, \
alg_start - block_offset);
}
else if (0 != alg_start)
{
bool need_red_zone_before;
mhd_assert (_MHD_RED_ZONE_SIZE <= alg_start);
#if defined(HAVE___ASAN_REGION_IS_POISONED)
need_red_zone_before =
(NULL == __asan_region_is_poisoned (pool->memory
+ alg_start
- _MHD_RED_ZONE_SIZE,
_MHD_RED_ZONE_SIZE));
#elif defined(HAVE___ASAN_ADDRESS_IS_POISONED)
need_red_zone_before =
(0 == __asan_address_is_poisoned (pool->memory + alg_start - 1));
#else /* ! HAVE___ASAN_ADDRESS_IS_POISONED */
need_red_zone_before = true; /* Unknown, assume new red zone needed */
#endif /* ! HAVE___ASAN_ADDRESS_IS_POISONED */
if (need_red_zone_before)
{
_MHD_POISON_MEMORY (pool->memory + alg_start, _MHD_RED_ZONE_SIZE);
alg_start += _MHD_RED_ZONE_SIZE;
}
}
#endif /* MHD_ASAN_POISON_ACTIVE */
mhd_assert (alg_start <= pool->pos);
mhd_assert (alg_start == ROUND_TO_ALIGN (alg_start));
pool->pos = alg_start;
}
}
else
{
/* Allocated "from the end" block. */
/* The size and the pointers of such block should not be manipulated by
MHD code (block split is disallowed). */
mhd_assert (block_offset >= pool->end);
mhd_assert (ROUND_TO_ALIGN (block_offset) == block_offset);
if (block_offset == pool->end)
{
/* The last allocated block, return deallocated block to the pool */
const size_t alg_end =
ROUND_TO_ALIGN_PLUS_RED_ZONE (block_offset + block_size);
pool->end = alg_end;
}
}
}
}
/**
* Clear all entries from the memory pool except
* for @a keep of the given @a copy_bytes. The pointer
+18
View File
@@ -147,6 +147,24 @@ size_t
MHD_pool_get_free (struct MemoryPool *pool);
/**
* Deallocate a block of memory obtained from the pool.
*
* If the given block is not the most recently
* (re)allocated block, the memory of the this block
* allocation may be not released until the pool is
* destroyed or reset.
*
* @param pool memory pool to use for the operation
* @param block the allocated block, the NULL is tolerated
* @param block_size the size of the allocated block
*/
void
MHD_pool_deallocate (struct MemoryPool *pool,
void *block,
size_t block_size);
/**
* Clear all entries from the memory pool except
* for @a keep of the given @a copy_bytes. The pointer
+13 -20
View File
@@ -2148,28 +2148,21 @@ MHD_response_execute_upgrade_ (struct MHD_Response *response,
size_t avail;
char *buf;
if (0 != connection->write_buffer_size)
{
mhd_assert (NULL != connection->write_buffer);
/* All data should be sent already */
mhd_assert (connection->write_buffer_send_offset == \
connection->write_buffer_append_offset);
(void) MHD_pool_reallocate (pool, connection->write_buffer,
connection->write_buffer_size, 0);
connection->write_buffer_append_offset = 0;
connection->write_buffer_send_offset = 0;
connection->write_buffer_size = 0;
}
/* All data should be sent already */
mhd_assert (connection->write_buffer_send_offset == \
connection->write_buffer_append_offset);
MHD_pool_deallocate (pool, connection->write_buffer,
connection->write_buffer_size);
connection->write_buffer_append_offset = 0;
connection->write_buffer_send_offset = 0;
connection->write_buffer_size = 0;
connection->write_buffer = NULL;
if (0 != connection->read_buffer_size)
{
mhd_assert (NULL != connection->read_buffer);
(void) MHD_pool_reallocate (pool, connection->read_buffer,
connection->read_buffer_size, 0);
connection->read_buffer_offset = 0;
connection->read_buffer_size = 0;
}
/* Extra read data should be processed already by the application */
MHD_pool_deallocate (pool, connection->read_buffer,
connection->read_buffer_size);
connection->read_buffer_offset = 0;
connection->read_buffer_size = 0;
connection->read_buffer = NULL;
avail = MHD_pool_get_free (pool);