summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/talloc/talloc.c32
1 files changed, 22 insertions, 10 deletions
diff --git a/lib/talloc/talloc.c b/lib/talloc/talloc.c
index 74db284aa0..21d675d3a2 100644
--- a/lib/talloc/talloc.c
+++ b/lib/talloc/talloc.c
@@ -510,7 +510,7 @@ static void tc_invalidate_pool(union talloc_pool_chunk *pool_tc)
*/
static struct talloc_chunk *talloc_alloc_pool(struct talloc_chunk *parent,
- size_t size)
+ size_t size, size_t prefix_len)
{
union talloc_pool_chunk *pool_ctx = NULL;
size_t space_left;
@@ -537,13 +537,14 @@ static struct talloc_chunk *talloc_alloc_pool(struct talloc_chunk *parent,
/*
* Align size to 16 bytes
*/
- chunk_size = TC_ALIGN16(size);
+ chunk_size = TC_ALIGN16(size + prefix_len);
if (space_left < chunk_size) {
return NULL;
}
- result = (struct talloc_chunk *)pool_ctx->hdr.next;
+ result = (struct talloc_chunk *)
+ ((char *)pool_ctx->hdr.next + prefix_len);
#if defined(DEVELOPER) && defined(VALGRIND_MAKE_MEM_UNDEFINED)
VALGRIND_MAKE_MEM_UNDEFINED(result, size);
@@ -562,10 +563,12 @@ static struct talloc_chunk *talloc_alloc_pool(struct talloc_chunk *parent,
/*
Allocate a bit of memory as a child of an existing pointer
*/
-static inline void *__talloc(const void *context, size_t size)
+static inline void *__talloc_with_prefix(const void *context, size_t size,
+ size_t prefix_len)
{
struct talloc_chunk *tc = NULL;
struct talloc_memlimit *limit = NULL;
+ size_t total_len = TC_HDR_SIZE + size + prefix_len;
if (unlikely(context == NULL)) {
context = null_context;
@@ -575,6 +578,10 @@ static inline void *__talloc(const void *context, size_t size)
return NULL;
}
+ if (unlikely(total_len < TC_HDR_SIZE)) {
+ return NULL;
+ }
+
if (context != NULL) {
struct talloc_chunk *ptc = talloc_chunk_from_ptr(context);
@@ -582,24 +589,24 @@ static inline void *__talloc(const void *context, size_t size)
limit = ptc->limit;
}
- tc = talloc_alloc_pool(ptc, TC_HDR_SIZE+size);
+ tc = talloc_alloc_pool(ptc, TC_HDR_SIZE+size, prefix_len);
}
if (tc == NULL) {
/*
* Only do the memlimit check/update on actual allocation.
*/
- if (!talloc_memlimit_check(limit, TC_HDR_SIZE + size)) {
+ if (!talloc_memlimit_check(limit, total_len)) {
errno = ENOMEM;
return NULL;
}
- tc = (struct talloc_chunk *)malloc(TC_HDR_SIZE+size);
+ tc = (struct talloc_chunk *)malloc(total_len);
if (unlikely(tc == NULL)) return NULL;
tc->flags = TALLOC_MAGIC;
tc->pool = NULL;
- talloc_memlimit_grow(limit, TC_HDR_SIZE + size);
+ talloc_memlimit_grow(limit, total_len);
}
tc->limit = limit;
@@ -629,6 +636,11 @@ static inline void *__talloc(const void *context, size_t size)
return TC_PTR_FROM_CHUNK(tc);
}
+static inline void *__talloc(const void *context, size_t size)
+{
+ return __talloc_with_prefix(context, size, 0);
+}
+
/*
* Create a talloc pool
*/
@@ -1558,7 +1570,7 @@ _PUBLIC_ void *_talloc_realloc(const void *context, void *ptr, size_t size, cons
#if ALWAYS_REALLOC
if (pool_tc) {
- new_ptr = talloc_alloc_pool(tc, size + TC_HDR_SIZE);
+ new_ptr = talloc_alloc_pool(tc, size + TC_HDR_SIZE, 0);
pool_tc->hdr.object_count--;
if (new_ptr == NULL) {
@@ -1673,7 +1685,7 @@ _PUBLIC_ void *_talloc_realloc(const void *context, void *ptr, size_t size, cons
}
}
- new_ptr = talloc_alloc_pool(tc, size + TC_HDR_SIZE);
+ new_ptr = talloc_alloc_pool(tc, size + TC_HDR_SIZE, 0);
if (new_ptr == NULL) {
new_ptr = malloc(TC_HDR_SIZE+size);