diff options
author | Jeremy Allison <jra@samba.org> | 2020-10-20 10:52:55 -0700 |
---|---|---|
committer | Andrew Bartlett <abartlet@samba.org> | 2020-11-09 02:46:50 +0000 |
commit | 4566ee91b8c37f62e8b56242a48230db59cd5ff0 (patch) | |
tree | 634faeca5b900cf2288c87e44ec4d19911e9a7bf /lib/talloc | |
parent | 30a8bea8a340dcf9a3120f5ee8041e62fb129d8d (diff) | |
download | samba-4566ee91b8c37f62e8b56242a48230db59cd5ff0.tar.gz |
lib: talloc: Fix memlimit on pool realloc.
We only have to do the memlimit check before any
real malloc or realloc. Allocations out of a
memory pool have already been counted in the
memory limit, so don't check in those cases.
This is an application-visible change (although
fixing a bug) so bump the ABI to 2.3.1 -> 2.3.2.
BUG: https://bugzilla.samba.org/show_bug.cgi?id=14540
Signed-off-by: Jeremy Allison <jra@samba.org>
Signed-off-by: Arran Cudbard-Bell <a.cudbardb@freeradius.org>
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
Diffstat (limited to 'lib/talloc')
-rw-r--r-- | lib/talloc/ABI/pytalloc-util-2.3.2.sigs | 16 | ||||
-rw-r--r-- | lib/talloc/ABI/talloc-2.3.2.sigs | 65 | ||||
-rw-r--r-- | lib/talloc/talloc.c | 69 | ||||
-rw-r--r-- | lib/talloc/wscript | 2 |
4 files changed, 144 insertions, 8 deletions
diff --git a/lib/talloc/ABI/pytalloc-util-2.3.2.sigs b/lib/talloc/ABI/pytalloc-util-2.3.2.sigs new file mode 100644 index 00000000000..6056577960d --- /dev/null +++ b/lib/talloc/ABI/pytalloc-util-2.3.2.sigs @@ -0,0 +1,16 @@ +_pytalloc_check_type: int (PyObject *, const char *) +_pytalloc_get_mem_ctx: TALLOC_CTX *(PyObject *) +_pytalloc_get_name: const char *(PyObject *) +_pytalloc_get_ptr: void *(PyObject *) +_pytalloc_get_type: void *(PyObject *, const char *) +pytalloc_BaseObject_PyType_Ready: int (PyTypeObject *) +pytalloc_BaseObject_check: int (PyObject *) +pytalloc_BaseObject_size: size_t (void) +pytalloc_Check: int (PyObject *) +pytalloc_GenericObject_reference_ex: PyObject *(TALLOC_CTX *, void *) +pytalloc_GenericObject_steal_ex: PyObject *(TALLOC_CTX *, void *) +pytalloc_GetBaseObjectType: PyTypeObject *(void) +pytalloc_GetObjectType: PyTypeObject *(void) +pytalloc_reference_ex: PyObject *(PyTypeObject *, TALLOC_CTX *, void *) +pytalloc_steal: PyObject *(PyTypeObject *, void *) +pytalloc_steal_ex: PyObject *(PyTypeObject *, TALLOC_CTX *, void *) diff --git a/lib/talloc/ABI/talloc-2.3.2.sigs b/lib/talloc/ABI/talloc-2.3.2.sigs new file mode 100644 index 00000000000..9969ce33389 --- /dev/null +++ b/lib/talloc/ABI/talloc-2.3.2.sigs @@ -0,0 +1,65 @@ +_talloc: void *(const void *, size_t) +_talloc_array: void *(const void *, size_t, unsigned int, const char *) +_talloc_free: int (void *, const char *) +_talloc_get_type_abort: void *(const void *, const char *, const char *) +_talloc_memdup: void *(const void *, const void *, size_t, const char *) +_talloc_move: void *(const void *, const void *) +_talloc_pooled_object: void *(const void *, size_t, const char *, unsigned int, size_t) +_talloc_realloc: void *(const void *, void *, size_t, const char *) +_talloc_realloc_array: void *(const void *, void *, size_t, unsigned int, const char *) +_talloc_reference_loc: void *(const void *, const void *, const char *) +_talloc_set_destructor: void (const void *, int (*)(void *)) +_talloc_steal_loc: void *(const void *, const void *, const char *) +_talloc_zero: void *(const void *, size_t, const char *) +_talloc_zero_array: void *(const void *, size_t, unsigned int, const char *) +talloc_asprintf: char *(const void *, const char *, ...) +talloc_asprintf_append: char *(char *, const char *, ...) +talloc_asprintf_append_buffer: char *(char *, const char *, ...) +talloc_autofree_context: void *(void) +talloc_check_name: void *(const void *, const char *) +talloc_disable_null_tracking: void (void) +talloc_enable_leak_report: void (void) +talloc_enable_leak_report_full: void (void) +talloc_enable_null_tracking: void (void) +talloc_enable_null_tracking_no_autofree: void (void) +talloc_find_parent_byname: void *(const void *, const char *) +talloc_free_children: void (void *) +talloc_get_name: const char *(const void *) +talloc_get_size: size_t (const void *) +talloc_increase_ref_count: int (const void *) +talloc_init: void *(const char *, ...) +talloc_is_parent: int (const void *, const void *) +talloc_named: void *(const void *, size_t, const char *, ...) +talloc_named_const: void *(const void *, size_t, const char *) +talloc_parent: void *(const void *) +talloc_parent_name: const char *(const void *) +talloc_pool: void *(const void *, size_t) +talloc_realloc_fn: void *(const void *, void *, size_t) +talloc_reference_count: size_t (const void *) +talloc_reparent: void *(const void *, const void *, const void *) +talloc_report: void (const void *, FILE *) +talloc_report_depth_cb: void (const void *, int, int, void (*)(const void *, int, int, int, void *), void *) +talloc_report_depth_file: void (const void *, int, int, FILE *) +talloc_report_full: void (const void *, FILE *) +talloc_set_abort_fn: void (void (*)(const char *)) +talloc_set_log_fn: void (void (*)(const char *)) +talloc_set_log_stderr: void (void) +talloc_set_memlimit: int (const void *, size_t) +talloc_set_name: const char *(const void *, const char *, ...) +talloc_set_name_const: void (const void *, const char *) +talloc_show_parents: void (const void *, FILE *) +talloc_strdup: char *(const void *, const char *) +talloc_strdup_append: char *(char *, const char *) +talloc_strdup_append_buffer: char *(char *, const char *) +talloc_strndup: char *(const void *, const char *, size_t) +talloc_strndup_append: char *(char *, const char *, size_t) +talloc_strndup_append_buffer: char *(char *, const char *, size_t) +talloc_test_get_magic: int (void) +talloc_total_blocks: size_t (const void *) +talloc_total_size: size_t (const void *) +talloc_unlink: int (const void *, void *) +talloc_vasprintf: char *(const void *, const char *, va_list) +talloc_vasprintf_append: char *(char *, const char *, va_list) +talloc_vasprintf_append_buffer: char *(char *, const char *, va_list) +talloc_version_major: int (void) +talloc_version_minor: int (void) diff --git a/lib/talloc/talloc.c b/lib/talloc/talloc.c index 885705234d4..078e58ca352 100644 --- a/lib/talloc/talloc.c +++ b/lib/talloc/talloc.c @@ -1833,13 +1833,6 @@ _PUBLIC_ void *_talloc_realloc(const void *context, void *ptr, size_t size, cons 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; @@ -1902,6 +1895,25 @@ _PUBLIC_ void *_talloc_realloc(const void *context, void *ptr, size_t size, cons 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; @@ -1920,6 +1932,18 @@ _PUBLIC_ void *_talloc_realloc(const void *context, void *ptr, size_t size, cons /* 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); @@ -2023,6 +2047,25 @@ _PUBLIC_ void *_talloc_realloc(const void *context, void *ptr, size_t size, cons 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; @@ -2038,6 +2081,18 @@ _PUBLIC_ void *_talloc_realloc(const void *context, void *ptr, size_t size, cons /* 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: diff --git a/lib/talloc/wscript b/lib/talloc/wscript index b955d215b80..a767477357f 100644 --- a/lib/talloc/wscript +++ b/lib/talloc/wscript @@ -1,7 +1,7 @@ #!/usr/bin/env python APPNAME = 'talloc' -VERSION = '2.3.1' +VERSION = '2.3.2' import os import sys |