gnunet-svn
[Top][All Lists]
Advanced

[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.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]