]> git.ipfire.org Git - thirdparty/samba.git/commitdiff
lib: talloc: Fix memlimit on pool realloc.
authorJeremy Allison <jra@samba.org>
Tue, 20 Oct 2020 17:52:55 +0000 (10:52 -0700)
committerAndrew Bartlett <abartlet@samba.org>
Mon, 9 Nov 2020 02:46:50 +0000 (02:46 +0000)
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>
lib/talloc/ABI/pytalloc-util-2.3.2.sigs [new file with mode: 0644]
lib/talloc/ABI/talloc-2.3.2.sigs [new file with mode: 0644]
lib/talloc/talloc.c
lib/talloc/wscript

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 (file)
index 0000000..6056577
--- /dev/null
@@ -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 (file)
index 0000000..9969ce3
--- /dev/null
@@ -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)
index 885705234d492daeb324a3beaf6b37c6b71c9f04..078e58ca352397e6ec4357d5a2785ce4dab463b7 100644 (file)
@@ -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:
index b955d215b80922d17cf83156e7031ce71cf266eb..a767477357fae79e148db2f8855c351ce6f39f71 100644 (file)
@@ -1,7 +1,7 @@
 #!/usr/bin/env python
 
 APPNAME = 'talloc'
-VERSION = '2.3.1'
+VERSION = '2.3.2'
 
 import os
 import sys