mirror of
https://git.gnunet.org/libmicrohttpd.git
synced 2026-09-25 04:09:31 +03:00
Implemented and used new function MHD_pool_deallocate()
The new function has special handling for user-poison mode.
This commit is contained in:
@@ -4304,6 +4304,9 @@ AS_VAR_IF([enable_sanitizers], ["no"], [:],
|
|||||||
AS_VAR_IF([ac_cv_header_sanitizer_asan_interface_h],["yes"],
|
AS_VAR_IF([ac_cv_header_sanitizer_asan_interface_h],["yes"],
|
||||||
[
|
[
|
||||||
CFLAGS="${CFLAGS_ac} ${san_CFLAGS} ${san_FLAGS} ${errattr_CFLAGS} ${user_CFLAGS}"
|
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>]],
|
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;]]
|
[[int a_var=1; i][f(((void*) 0) != __asan_region_is_poisoned((void*) &a_var, sizeof(a_var))) return 3;]]
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -1597,11 +1597,20 @@ connection_shrink_read_buffer (struct MHD_Connection *connection)
|
|||||||
}
|
}
|
||||||
|
|
||||||
mhd_assert (c->read_buffer_offset <= c->read_buffer_size);
|
mhd_assert (c->read_buffer_offset <= c->read_buffer_size);
|
||||||
new_buf = MHD_pool_reallocate (c->pool, c->read_buffer, c->read_buffer_size,
|
if (0 == c->read_buffer_offset)
|
||||||
c->read_buffer_offset);
|
{
|
||||||
mhd_assert (c->read_buffer == new_buf);
|
MHD_pool_deallocate (c->pool, c->read_buffer, c->read_buffer_size);
|
||||||
c->read_buffer = new_buf;
|
c->read_buffer = NULL;
|
||||||
c->read_buffer_size = c->read_buffer_offset;
|
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
|
/* Read buffer is not needed anymore, discard it
|
||||||
* to free some space for error response. */
|
* to free some space for error response. */
|
||||||
connection->read_buffer = MHD_pool_reallocate (connection->pool,
|
MHD_pool_deallocate (connection->pool,
|
||||||
connection->read_buffer,
|
connection->read_buffer,
|
||||||
connection->read_buffer_size,
|
connection->read_buffer_size);
|
||||||
0);
|
connection->read_buffer = NULL;
|
||||||
connection->read_buffer_size = 0;
|
connection->read_buffer_size = 0;
|
||||||
connection->read_buffer_offset = 0;
|
connection->read_buffer_offset = 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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
|
* Clear all entries from the memory pool except
|
||||||
* for @a keep of the given @a copy_bytes. The pointer
|
* for @a keep of the given @a copy_bytes. The pointer
|
||||||
|
|||||||
@@ -147,6 +147,24 @@ size_t
|
|||||||
MHD_pool_get_free (struct MemoryPool *pool);
|
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
|
* Clear all entries from the memory pool except
|
||||||
* for @a keep of the given @a copy_bytes. The pointer
|
* for @a keep of the given @a copy_bytes. The pointer
|
||||||
|
|||||||
+13
-20
@@ -2148,28 +2148,21 @@ MHD_response_execute_upgrade_ (struct MHD_Response *response,
|
|||||||
size_t avail;
|
size_t avail;
|
||||||
char *buf;
|
char *buf;
|
||||||
|
|
||||||
if (0 != connection->write_buffer_size)
|
/* All data should be sent already */
|
||||||
{
|
mhd_assert (connection->write_buffer_send_offset == \
|
||||||
mhd_assert (NULL != connection->write_buffer);
|
connection->write_buffer_append_offset);
|
||||||
/* All data should be sent already */
|
MHD_pool_deallocate (pool, connection->write_buffer,
|
||||||
mhd_assert (connection->write_buffer_send_offset == \
|
connection->write_buffer_size);
|
||||||
connection->write_buffer_append_offset);
|
connection->write_buffer_append_offset = 0;
|
||||||
(void) MHD_pool_reallocate (pool, connection->write_buffer,
|
connection->write_buffer_send_offset = 0;
|
||||||
connection->write_buffer_size, 0);
|
connection->write_buffer_size = 0;
|
||||||
connection->write_buffer_append_offset = 0;
|
|
||||||
connection->write_buffer_send_offset = 0;
|
|
||||||
connection->write_buffer_size = 0;
|
|
||||||
}
|
|
||||||
connection->write_buffer = NULL;
|
connection->write_buffer = NULL;
|
||||||
|
|
||||||
if (0 != connection->read_buffer_size)
|
/* Extra read data should be processed already by the application */
|
||||||
{
|
MHD_pool_deallocate (pool, connection->read_buffer,
|
||||||
mhd_assert (NULL != connection->read_buffer);
|
connection->read_buffer_size);
|
||||||
(void) MHD_pool_reallocate (pool, connection->read_buffer,
|
connection->read_buffer_offset = 0;
|
||||||
connection->read_buffer_size, 0);
|
connection->read_buffer_size = 0;
|
||||||
connection->read_buffer_offset = 0;
|
|
||||||
connection->read_buffer_size = 0;
|
|
||||||
}
|
|
||||||
connection->read_buffer = NULL;
|
connection->read_buffer = NULL;
|
||||||
|
|
||||||
avail = MHD_pool_get_free (pool);
|
avail = MHD_pool_get_free (pool);
|
||||||
|
|||||||
Reference in New Issue
Block a user