Prevention of freeing non-freeable memory pool block.
This commit is contained in:
43
src/nxt_mp.c
43
src/nxt_mp.c
@@ -89,6 +89,7 @@ typedef enum {
|
|||||||
typedef struct {
|
typedef struct {
|
||||||
NXT_RBTREE_NODE (node);
|
NXT_RBTREE_NODE (node);
|
||||||
nxt_mp_block_type_t type:8;
|
nxt_mp_block_type_t type:8;
|
||||||
|
uint8_t freeable;
|
||||||
|
|
||||||
/* Block size must be less than 4G. */
|
/* Block size must be less than 4G. */
|
||||||
uint32_t size;
|
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_page_t *nxt_mp_alloc_page(nxt_mp_t *mp);
|
||||||
static nxt_mp_block_t *nxt_mp_alloc_cluster(nxt_mp_t *mp);
|
static nxt_mp_block_t *nxt_mp_alloc_cluster(nxt_mp_t *mp);
|
||||||
#endif
|
#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,
|
static intptr_t nxt_mp_rbtree_compare(nxt_rbtree_node_t *node1,
|
||||||
nxt_rbtree_node_t *node2);
|
nxt_rbtree_node_t *node2);
|
||||||
static nxt_mp_block_t *nxt_mp_find_block(nxt_rbtree_t *tree, u_char *p);
|
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);
|
p = nxt_mp_alloc_small(mp, size);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
p = nxt_mp_alloc_large(mp, NXT_MAX_ALIGNMENT, size);
|
p = nxt_mp_alloc_large(mp, NXT_MAX_ALIGNMENT, size, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
p = nxt_mp_alloc_large(mp, NXT_MAX_ALIGNMENT, size);
|
p = nxt_mp_alloc_large(mp, NXT_MAX_ALIGNMENT, size, 1);
|
||||||
|
|
||||||
#endif
|
#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);
|
p = nxt_mp_alloc_small(mp, aligned_size);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
p = nxt_mp_alloc_large(mp, alignment, size);
|
p = nxt_mp_alloc_large(mp, alignment, size, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
p = nxt_mp_alloc_large(mp, alignment, size);
|
p = nxt_mp_alloc_large(mp, alignment, size, 1);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -706,7 +708,8 @@ nxt_mp_alloc_cluster(nxt_mp_t *mp)
|
|||||||
|
|
||||||
|
|
||||||
static void *
|
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;
|
u_char *p;
|
||||||
size_t aligned_size;
|
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->type = type;
|
||||||
|
block->freeable = freeable;
|
||||||
block->size = size;
|
block->size = size;
|
||||||
block->start = p;
|
block->start = p;
|
||||||
|
|
||||||
@@ -790,15 +794,20 @@ nxt_mp_free(nxt_mp_t *mp, void *p)
|
|||||||
}
|
}
|
||||||
|
|
||||||
} else if (nxt_fast_path(p == block->start)) {
|
} else if (nxt_fast_path(p == block->start)) {
|
||||||
nxt_rbtree_delete(&mp->blocks, &block->node);
|
|
||||||
|
|
||||||
if (block->type == NXT_MP_DISCRETE_BLOCK) {
|
if (block->freeable) {
|
||||||
nxt_free(block);
|
nxt_rbtree_delete(&mp->blocks, &block->node);
|
||||||
|
|
||||||
|
if (block->type == NXT_MP_DISCRETE_BLOCK) {
|
||||||
|
nxt_free(block);
|
||||||
|
}
|
||||||
|
|
||||||
|
nxt_free(p);
|
||||||
|
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
nxt_free(p);
|
err = "freed pointer points to non-freeable block: %p";
|
||||||
|
|
||||||
return;
|
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
err = "freed pointer points to middle of block: %p";
|
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)) {
|
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;
|
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);
|
p = nxt_mp_get_small(mp, &mp->nget_pages, size);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
p = nxt_mp_alloc_large(mp, NXT_MAX_ALIGNMENT, size);
|
p = nxt_mp_alloc_large(mp, NXT_MAX_ALIGNMENT, size, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
p = nxt_mp_alloc_large(mp, NXT_MAX_ALIGNMENT, size);
|
p = nxt_mp_alloc_large(mp, NXT_MAX_ALIGNMENT, size, 0);
|
||||||
|
|
||||||
#endif
|
#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);
|
p = nxt_mp_get_small(mp, &mp->get_pages, size);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
p = nxt_mp_alloc_large(mp, NXT_MAX_ALIGNMENT, size);
|
p = nxt_mp_alloc_large(mp, NXT_MAX_ALIGNMENT, size, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
p = nxt_mp_alloc_large(mp, NXT_MAX_ALIGNMENT, size);
|
p = nxt_mp_alloc_large(mp, NXT_MAX_ALIGNMENT, size, 0);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user