return NULL;
}
- if (tc->limit && (size > tc->size)) {
- if (!talloc_memlimit_check(tc->limit, (size - tc->size))) {
- errno = ENOMEM;
- return NULL;
- }
- }
-
/* handle realloc inside a talloc_pool */
if (unlikely(tc->flags & TALLOC_FLAG_POOLMEM)) {
pool_hdr = tc->pool;
if (pool_hdr) {
new_ptr = tc_alloc_pool(tc, size + TC_HDR_SIZE, 0);
if (new_ptr == NULL) {
+ /*
+ * Couldn't allocate from pool (pool size
+ * counts as already allocated for memlimit
+ * purposes). We must check memory limit
+ * before any real malloc.
+ */
+ if (tc->limit) {
+ /*
+ * Note we're doing an extra malloc,
+ * on top of the pool size, so account
+ * for size only, not the difference
+ * between old and new size.
+ */
+ if (!talloc_memlimit_check(tc->limit, size)) {
+ _talloc_chunk_set_not_free(tc);
+ errno = ENOMEM;
+ return NULL;
+ }
+ }
new_ptr = malloc(TC_HDR_SIZE+size);
malloced = true;
new_size = size;
/* We're doing malloc then free here, so record the difference. */
old_size = tc->size;
new_size = size;
+ /*
+ * We must check memory limit
+ * before any real malloc.
+ */
+ if (tc->limit && (size > old_size)) {
+ if (!talloc_memlimit_check(tc->limit,
+ (size - old_size))) {
+ _talloc_chunk_set_not_free(tc);
+ errno = ENOMEM;
+ return NULL;
+ }
+ }
new_ptr = malloc(size + TC_HDR_SIZE);
if (new_ptr) {
memcpy(new_ptr, tc, MIN(tc->size, size) + TC_HDR_SIZE);
new_ptr = tc_alloc_pool(tc, size + TC_HDR_SIZE, 0);
if (new_ptr == NULL) {
+ /*
+ * Couldn't allocate from pool (pool size
+ * counts as already allocated for memlimit
+ * purposes). We must check memory limit
+ * before any real malloc.
+ */
+ if (tc->limit) {
+ /*
+ * Note we're doing an extra malloc,
+ * on top of the pool size, so account
+ * for size only, not the difference
+ * between old and new size.
+ */
+ if (!talloc_memlimit_check(tc->limit, size)) {
+ _talloc_chunk_set_not_free(tc);
+ errno = ENOMEM;
+ return NULL;
+ }
+ }
new_ptr = malloc(TC_HDR_SIZE+size);
malloced = true;
new_size = size;
/* We're doing realloc here, so record the difference. */
old_size = tc->size;
new_size = size;
+ /*
+ * We must check memory limit
+ * before any real realloc.
+ */
+ if (tc->limit && (size > old_size)) {
+ if (!talloc_memlimit_check(tc->limit,
+ (size - old_size))) {
+ _talloc_chunk_set_not_free(tc);
+ errno = ENOMEM;
+ return NULL;
+ }
+ }
new_ptr = realloc(tc, size + TC_HDR_SIZE);
}
got_new_ptr: