summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorIgor Sysoev <igor@sysoev.ru>2018-04-20 19:46:36 +0300
committerIgor Sysoev <igor@sysoev.ru>2018-04-20 19:46:36 +0300
commitb95d5b88826210165a566cbe4cc564488cd28f88 (patch)
tree4c937737008f2521326dafb35da280ded56579b8
parentad36c8ca8da62d3c19398bf04aceb0f113cc253d (diff)
downloadunit-b95d5b88826210165a566cbe4cc564488cd28f88.tar.gz
unit-b95d5b88826210165a566cbe4cc564488cd28f88.tar.bz2
Prevention of freeing non-freeable memory pool block.
-rw-r--r--src/nxt_mp.c43
1 files changed, 26 insertions, 17 deletions
diff --git a/src/nxt_mp.c b/src/nxt_mp.c
index 43c0a2c0..a1ccd058 100644
--- a/src/nxt_mp.c
+++ b/src/nxt_mp.c
@@ -89,6 +89,7 @@ typedef enum {
typedef struct {
NXT_RBTREE_NODE (node);
nxt_mp_block_type_t type:8;
+ uint8_t freeable;
/* Block size must be less than 4G. */
uint32_t size;
@@ -150,7 +151,8 @@ static void *nxt_mp_get_small(nxt_mp_t *mp, nxt_queue_t *pages, size_t size);
static nxt_mp_page_t *nxt_mp_alloc_page(nxt_mp_t *mp);
static nxt_mp_block_t *nxt_mp_alloc_cluster(nxt_mp_t *mp);
#endif
-static void *nxt_mp_alloc_large(nxt_mp_t *mp, size_t alignment, size_t size);
+static void *nxt_mp_alloc_large(nxt_mp_t *mp, size_t alignment, size_t size,
+ nxt_bool_t freeable);
static intptr_t nxt_mp_rbtree_compare(nxt_rbtree_node_t *node1,
nxt_rbtree_node_t *node2);
static nxt_mp_block_t *nxt_mp_find_block(nxt_rbtree_t *tree, u_char *p);
@@ -395,12 +397,12 @@ nxt_mp_alloc(nxt_mp_t *mp, size_t size)
p = nxt_mp_alloc_small(mp, size);
} else {
- p = nxt_mp_alloc_large(mp, NXT_MAX_ALIGNMENT, size);
+ p = nxt_mp_alloc_large(mp, NXT_MAX_ALIGNMENT, size, 1);
}
#else
- p = nxt_mp_alloc_large(mp, NXT_MAX_ALIGNMENT, size);
+ p = nxt_mp_alloc_large(mp, NXT_MAX_ALIGNMENT, size, 1);
#endif
@@ -444,12 +446,12 @@ nxt_mp_align(nxt_mp_t *mp, size_t alignment, size_t size)
p = nxt_mp_alloc_small(mp, aligned_size);
} else {
- p = nxt_mp_alloc_large(mp, alignment, size);
+ p = nxt_mp_alloc_large(mp, alignment, size, 1);
}
#else
- p = nxt_mp_alloc_large(mp, alignment, size);
+ p = nxt_mp_alloc_large(mp, alignment, size, 1);
#endif
@@ -706,7 +708,8 @@ nxt_mp_alloc_cluster(nxt_mp_t *mp)
static void *
-nxt_mp_alloc_large(nxt_mp_t *mp, size_t alignment, size_t size)
+nxt_mp_alloc_large(nxt_mp_t *mp, size_t alignment, size_t size,
+ nxt_bool_t freeable)
{
u_char *p;
size_t aligned_size;
@@ -747,6 +750,7 @@ nxt_mp_alloc_large(nxt_mp_t *mp, size_t alignment, size_t size)
}
block->type = type;
+ block->freeable = freeable;
block->size = size;
block->start = p;
@@ -790,15 +794,20 @@ nxt_mp_free(nxt_mp_t *mp, void *p)
}
} else if (nxt_fast_path(p == block->start)) {
- nxt_rbtree_delete(&mp->blocks, &block->node);
- if (block->type == NXT_MP_DISCRETE_BLOCK) {
- nxt_free(block);
- }
+ if (block->freeable) {
+ nxt_rbtree_delete(&mp->blocks, &block->node);
+
+ if (block->type == NXT_MP_DISCRETE_BLOCK) {
+ nxt_free(block);
+ }
+
+ nxt_free(p);
- nxt_free(p);
+ return;
+ }
- return;
+ err = "freed pointer points to non-freeable block: %p";
} else {
err = "freed pointer points to middle of block: %p";
@@ -859,7 +868,7 @@ nxt_mp_chunk_free(nxt_mp_t *mp, nxt_mp_block_t *cluster, u_char *p)
}
if (nxt_slow_path(page->size == 0xFF)) {
- return "freed pointer points to non-freeble page: %p";
+ return "freed pointer points to non-freeable page: %p";
}
size = page->size << mp->chunk_size_shift;
@@ -963,12 +972,12 @@ nxt_mp_nget(nxt_mp_t *mp, size_t size)
p = nxt_mp_get_small(mp, &mp->nget_pages, size);
} else {
- p = nxt_mp_alloc_large(mp, NXT_MAX_ALIGNMENT, size);
+ p = nxt_mp_alloc_large(mp, NXT_MAX_ALIGNMENT, size, 0);
}
#else
- p = nxt_mp_alloc_large(mp, NXT_MAX_ALIGNMENT, size);
+ p = nxt_mp_alloc_large(mp, NXT_MAX_ALIGNMENT, size, 0);
#endif
@@ -990,12 +999,12 @@ nxt_mp_get(nxt_mp_t *mp, size_t size)
p = nxt_mp_get_small(mp, &mp->get_pages, size);
} else {
- p = nxt_mp_alloc_large(mp, NXT_MAX_ALIGNMENT, size);
+ p = nxt_mp_alloc_large(mp, NXT_MAX_ALIGNMENT, size, 0);
}
#else
- p = nxt_mp_alloc_large(mp, NXT_MAX_ALIGNMENT, size);
+ p = nxt_mp_alloc_large(mp, NXT_MAX_ALIGNMENT, size, 0);
#endif