[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[libmicrohttpd] 04/04: Implemented and used new function MHD_pool_deallo
From: |
gnunet |
Subject: |
[libmicrohttpd] 04/04: Implemented and used new function MHD_pool_deallocate() |
Date: |
Wed, 05 Apr 2023 18:46:39 +0200 |
This is an automated email from the git hooks/post-receive script.
karlson2k pushed a commit to branch master
in repository libmicrohttpd.
commit edf692a61627394c26132e203857afc5237495c3
Author: Evgeny Grin (Karlson2k) <k2k@narod.ru>
AuthorDate: Wed Apr 5 16:48:35 2023 +0300
Implemented and used new function MHD_pool_deallocate()
The new function has special handling for user-poison mode.
---
configure.ac | 3 ++
src/microhttpd/connection.c | 27 ++++++++----
src/microhttpd/memorypool.c | 103 ++++++++++++++++++++++++++++++++++++++++++++
src/microhttpd/memorypool.h | 18 ++++++++
src/microhttpd/response.c | 33 ++++++--------
5 files changed, 155 insertions(+), 29 deletions(-)
diff --git a/configure.ac b/configure.ac
index c31bb2a4..c1115135 100644
--- a/configure.ac
+++ b/configure.ac
@@ -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;]]
)
diff --git a/src/microhttpd/connection.c b/src/microhttpd/connection.c
index f378334c..82b127b9 100644
--- a/src/microhttpd/connection.c
+++ b/src/microhttpd/connection.c
@@ -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;
}
diff --git a/src/microhttpd/memorypool.c b/src/microhttpd/memorypool.c
index e0511830..8d80f888 100644
--- a/src/microhttpd/memorypool.c
+++ b/src/microhttpd/memorypool.c
@@ -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
diff --git a/src/microhttpd/memorypool.h b/src/microhttpd/memorypool.h
index 98f96bda..49bbcbe1 100644
--- a/src/microhttpd/memorypool.h
+++ b/src/microhttpd/memorypool.h
@@ -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
diff --git a/src/microhttpd/response.c b/src/microhttpd/response.c
index 159c8ecb..d125ea24 100644
--- a/src/microhttpd/response.c
+++ b/src/microhttpd/response.c
@@ -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);
--
To stop receiving notification emails like this one, please contact
gnunet@gnunet.org.