1
0
mirror of https://github.com/samba-team/samba.git synced 2024-12-22 13:34:15 +03:00

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>
This commit is contained in:
Jeremy Allison 2020-10-20 10:52:55 -07:00 committed by Andrew Bartlett
parent 30a8bea8a3
commit 4566ee91b8
4 changed files with 144 additions and 8 deletions

View File

@ -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 *)

View File

@ -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)

View 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:

View File

@ -1,7 +1,7 @@
#!/usr/bin/env python
APPNAME = 'talloc'
VERSION = '2.3.1'
VERSION = '2.3.2'
import os
import sys