aboutsummaryrefslogtreecommitdiff
path: root/src/microhttpd
diff options
context:
space:
mode:
authorEvgeny Grin (Karlson2k) <k2k@narod.ru>2023-04-05 16:48:35 +0300
committerEvgeny Grin (Karlson2k) <k2k@narod.ru>2023-04-05 19:44:49 +0300
commitedf692a61627394c26132e203857afc5237495c3 (patch)
tree0d06ed9cad5859d2051553da6f492a8e15fc50f9 /src/microhttpd
parent95ad2a9a480435e86dfa1bbd7a6798150320d3bd (diff)
downloadlibmicrohttpd-edf692a61627394c26132e203857afc5237495c3.tar.gz
libmicrohttpd-edf692a61627394c26132e203857afc5237495c3.zip
Implemented and used new function MHD_pool_deallocate()
The new function has special handling for user-poison mode.
Diffstat (limited to 'src/microhttpd')
-rw-r--r--src/microhttpd/connection.c27
-rw-r--r--src/microhttpd/memorypool.c103
-rw-r--r--src/microhttpd/memorypool.h18
-rw-r--r--src/microhttpd/response.c33
4 files changed, 152 insertions, 29 deletions
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)
1597 } 1597 }
1598 1598
1599 mhd_assert (c->read_buffer_offset <= c->read_buffer_size); 1599 mhd_assert (c->read_buffer_offset <= c->read_buffer_size);
1600 new_buf = MHD_pool_reallocate (c->pool, c->read_buffer, c->read_buffer_size, 1600 if (0 == c->read_buffer_offset)
1601 c->read_buffer_offset); 1601 {
1602 mhd_assert (c->read_buffer == new_buf); 1602 MHD_pool_deallocate (c->pool, c->read_buffer, c->read_buffer_size);
1603 c->read_buffer = new_buf; 1603 c->read_buffer = NULL;
1604 c->read_buffer_size = c->read_buffer_offset; 1604 c->read_buffer_size = 0;
1605 }
1606 else
1607 {
1608 new_buf = MHD_pool_reallocate (c->pool, c->read_buffer, c->read_buffer_size,
1609 c->read_buffer_offset);
1610 mhd_assert (c->read_buffer == new_buf);
1611 c->read_buffer = new_buf;
1612 c->read_buffer_size = c->read_buffer_offset;
1613 }
1605} 1614}
1606 1615
1607 1616
@@ -2424,10 +2433,10 @@ transmit_error_response_len (struct MHD_Connection *connection,
2424 { 2433 {
2425 /* Read buffer is not needed anymore, discard it 2434 /* Read buffer is not needed anymore, discard it
2426 * to free some space for error response. */ 2435 * to free some space for error response. */
2427 connection->read_buffer = MHD_pool_reallocate (connection->pool, 2436 MHD_pool_deallocate (connection->pool,
2428 connection->read_buffer, 2437 connection->read_buffer,
2429 connection->read_buffer_size, 2438 connection->read_buffer_size);
2430 0); 2439 connection->read_buffer = NULL;
2431 connection->read_buffer_size = 0; 2440 connection->read_buffer_size = 0;
2432 connection->read_buffer_offset = 0; 2441 connection->read_buffer_offset = 0;
2433 } 2442 }
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
@@ -577,6 +577,109 @@ MHD_pool_reallocate (struct MemoryPool *pool,
577 577
578 578
579/** 579/**
580 * Deallocate a block of memory obtained from the pool.
581 *
582 * If the given block is not the most recently
583 * (re)allocated block, the memory of the this block
584 * allocation may be not released until the pool is
585 * destroyed or reset.
586 *
587 * @param pool memory pool to use for the operation
588 * @param block the allocated block, the NULL is tolerated
589 * @param block_size the size of the allocated block
590 */
591void
592MHD_pool_deallocate (struct MemoryPool *pool,
593 void *block,
594 size_t block_size)
595{
596 mhd_assert (pool->end >= pool->pos);
597 mhd_assert (pool->size >= pool->end - pool->pos);
598 mhd_assert (block != NULL || block_size == 0);
599 mhd_assert (pool->size >= block_size);
600 mhd_assert (pool->pos == ROUND_TO_ALIGN (pool->pos));
601
602 if (NULL != block)
603 { /* Have previously allocated data */
604 const size_t block_offset = mp_ptr_diff_ (block, pool->memory);
605 mhd_assert (mp_ptr_le_ (pool->memory, block));
606 mhd_assert (block_offset <= pool->size);
607 mhd_assert ((block_offset != pool->pos) || (block_size == 0));
608 /* Zero-out deallocated region */
609 if (0 != block_size)
610 {
611 memset (block, 0, block_size);
612 _MHD_POISON_MEMORY (block, block_size);
613 }
614#if ! defined(MHD_FAVOR_SMALL_CODE) && ! defined(MHD_ASAN_POISON_ACTIVE)
615 else
616 return; /* Zero size, no need to do anything */
617#endif /* ! MHD_FAVOR_SMALL_CODE && ! MHD_ASAN_POISON_ACTIVE */
618 if (block_offset <= pool->pos)
619 {
620 /* "Normal" block, not allocated "from the end". */
621 const size_t alg_end =
622 ROUND_TO_ALIGN_PLUS_RED_ZONE (block_offset + block_size);
623 mhd_assert (alg_end <= pool->pos);
624 if (alg_end == pool->pos)
625 {
626 /* The last allocated block, return deallocated block to the pool */
627 size_t alg_start = ROUND_TO_ALIGN (block_offset);
628 mhd_assert (alg_start >= block_offset);
629#if defined(MHD_ASAN_POISON_ACTIVE)
630 if (alg_start != block_offset)
631 {
632 _MHD_POISON_MEMORY (pool->memory + block_offset, \
633 alg_start - block_offset);
634 }
635 else if (0 != alg_start)
636 {
637 bool need_red_zone_before;
638 mhd_assert (_MHD_RED_ZONE_SIZE <= alg_start);
639#if defined(HAVE___ASAN_REGION_IS_POISONED)
640 need_red_zone_before =
641 (NULL == __asan_region_is_poisoned (pool->memory
642 + alg_start
643 - _MHD_RED_ZONE_SIZE,
644 _MHD_RED_ZONE_SIZE));
645#elif defined(HAVE___ASAN_ADDRESS_IS_POISONED)
646 need_red_zone_before =
647 (0 == __asan_address_is_poisoned (pool->memory + alg_start - 1));
648#else /* ! HAVE___ASAN_ADDRESS_IS_POISONED */
649 need_red_zone_before = true; /* Unknown, assume new red zone needed */
650#endif /* ! HAVE___ASAN_ADDRESS_IS_POISONED */
651 if (need_red_zone_before)
652 {
653 _MHD_POISON_MEMORY (pool->memory + alg_start, _MHD_RED_ZONE_SIZE);
654 alg_start += _MHD_RED_ZONE_SIZE;
655 }
656 }
657#endif /* MHD_ASAN_POISON_ACTIVE */
658 mhd_assert (alg_start <= pool->pos);
659 mhd_assert (alg_start == ROUND_TO_ALIGN (alg_start));
660 pool->pos = alg_start;
661 }
662 }
663 else
664 {
665 /* Allocated "from the end" block. */
666 /* The size and the pointers of such block should not be manipulated by
667 MHD code (block split is disallowed). */
668 mhd_assert (block_offset >= pool->end);
669 mhd_assert (ROUND_TO_ALIGN (block_offset) == block_offset);
670 if (block_offset == pool->end)
671 {
672 /* The last allocated block, return deallocated block to the pool */
673 const size_t alg_end =
674 ROUND_TO_ALIGN_PLUS_RED_ZONE (block_offset + block_size);
675 pool->end = alg_end;
676 }
677 }
678 }
679}
680
681
682/**
580 * Clear all entries from the memory pool except 683 * Clear all entries from the memory pool except
581 * for @a keep of the given @a copy_bytes. The pointer 684 * for @a keep of the given @a copy_bytes. The pointer
582 * returned should be a buffer of @a new_size where 685 * returned should be a buffer of @a new_size where
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
@@ -148,6 +148,24 @@ MHD_pool_get_free (struct MemoryPool *pool);
148 148
149 149
150/** 150/**
151 * Deallocate a block of memory obtained from the pool.
152 *
153 * If the given block is not the most recently
154 * (re)allocated block, the memory of the this block
155 * allocation may be not released until the pool is
156 * destroyed or reset.
157 *
158 * @param pool memory pool to use for the operation
159 * @param block the allocated block, the NULL is tolerated
160 * @param block_size the size of the allocated block
161 */
162void
163MHD_pool_deallocate (struct MemoryPool *pool,
164 void *block,
165 size_t block_size);
166
167
168/**
151 * Clear all entries from the memory pool except 169 * Clear all entries from the memory pool except
152 * for @a keep of the given @a copy_bytes. The pointer 170 * for @a keep of the given @a copy_bytes. The pointer
153 * returned should be a buffer of @a new_size where 171 * returned should be a buffer of @a new_size where
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,
2148 size_t avail; 2148 size_t avail;
2149 char *buf; 2149 char *buf;
2150 2150
2151 if (0 != connection->write_buffer_size) 2151 /* All data should be sent already */
2152 { 2152 mhd_assert (connection->write_buffer_send_offset == \
2153 mhd_assert (NULL != connection->write_buffer); 2153 connection->write_buffer_append_offset);
2154 /* All data should be sent already */ 2154 MHD_pool_deallocate (pool, connection->write_buffer,
2155 mhd_assert (connection->write_buffer_send_offset == \ 2155 connection->write_buffer_size);
2156 connection->write_buffer_append_offset); 2156 connection->write_buffer_append_offset = 0;
2157 (void) MHD_pool_reallocate (pool, connection->write_buffer, 2157 connection->write_buffer_send_offset = 0;
2158 connection->write_buffer_size, 0); 2158 connection->write_buffer_size = 0;
2159 connection->write_buffer_append_offset = 0;
2160 connection->write_buffer_send_offset = 0;
2161 connection->write_buffer_size = 0;
2162 }
2163 connection->write_buffer = NULL; 2159 connection->write_buffer = NULL;
2164 2160
2165 if (0 != connection->read_buffer_size) 2161 /* Extra read data should be processed already by the application */
2166 { 2162 MHD_pool_deallocate (pool, connection->read_buffer,
2167 mhd_assert (NULL != connection->read_buffer); 2163 connection->read_buffer_size);
2168 (void) MHD_pool_reallocate (pool, connection->read_buffer, 2164 connection->read_buffer_offset = 0;
2169 connection->read_buffer_size, 0); 2165 connection->read_buffer_size = 0;
2170 connection->read_buffer_offset = 0;
2171 connection->read_buffer_size = 0;
2172 }
2173 connection->read_buffer = NULL; 2166 connection->read_buffer = NULL;
2174 2167
2175 avail = MHD_pool_get_free (pool); 2168 avail = MHD_pool_get_free (pool);