mirror of
https://github.com/samba-team/samba.git
synced 2024-12-23 17:34:34 +03:00
Actually finish memcache_add_talloc
This fixes a memleak found by Martin Zielinski <mz@seh.de>. Thanks for looking closely! Volker (cherry picked from commit a31a84a078100819809e6d40dbc3df207a50a0b2)
This commit is contained in:
parent
5a210cc552
commit
f50ad76750
@ -40,6 +40,24 @@ struct memcache {
|
||||
static void memcache_element_parse(struct memcache_element *e,
|
||||
DATA_BLOB *key, DATA_BLOB *value);
|
||||
|
||||
static bool memcache_is_talloc(enum memcache_number n)
|
||||
{
|
||||
bool result;
|
||||
|
||||
switch (n) {
|
||||
case GETPWNAM_CACHE:
|
||||
case PDB_GETPWSID_CACHE:
|
||||
case SINGLETON_CACHE_TALLOC:
|
||||
result = true;
|
||||
break;
|
||||
default:
|
||||
result = false;
|
||||
break;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static int memcache_destructor(struct memcache *cache) {
|
||||
struct memcache_element *e, *next;
|
||||
|
||||
@ -188,6 +206,16 @@ static void memcache_delete_element(struct memcache *cache,
|
||||
}
|
||||
DLIST_REMOVE(cache->mru, e);
|
||||
|
||||
if (memcache_is_talloc(e->n)) {
|
||||
DATA_BLOB cache_key, cache_value;
|
||||
void *ptr;
|
||||
|
||||
memcache_element_parse(e, &cache_key, &cache_value);
|
||||
SMB_ASSERT(cache_value.length == sizeof(ptr));
|
||||
memcpy(&ptr, cache_value.data, sizeof(ptr));
|
||||
TALLOC_FREE(ptr);
|
||||
}
|
||||
|
||||
cache->size -= memcache_element_size(e->keylength, e->valuelength);
|
||||
|
||||
SAFE_FREE(e);
|
||||
@ -250,6 +278,12 @@ void memcache_add(struct memcache *cache, enum memcache_number n,
|
||||
memcache_element_parse(e, &cache_key, &cache_value);
|
||||
|
||||
if (value.length <= cache_value.length) {
|
||||
if (memcache_is_talloc(e->n)) {
|
||||
void *ptr;
|
||||
SMB_ASSERT(cache_value.length == sizeof(ptr));
|
||||
memcpy(&ptr, cache_value.data, sizeof(ptr));
|
||||
TALLOC_FREE(ptr);
|
||||
}
|
||||
/*
|
||||
* We can reuse the existing record
|
||||
*/
|
||||
@ -308,7 +342,8 @@ void memcache_add(struct memcache *cache, enum memcache_number n,
|
||||
void memcache_add_talloc(struct memcache *cache, enum memcache_number n,
|
||||
DATA_BLOB key, void *ptr)
|
||||
{
|
||||
memcache_add(cache, n, key, data_blob_const(&ptr, sizeof(ptr)));
|
||||
void *p = talloc_move(cache, &ptr);
|
||||
memcache_add(cache, n, key, data_blob_const(&p, sizeof(p)));
|
||||
}
|
||||
|
||||
void memcache_flush(struct memcache *cache, enum memcache_number n)
|
||||
|
@ -5291,6 +5291,11 @@ static bool run_local_memcache(int dummy)
|
||||
DATA_BLOB d1, d2, d3;
|
||||
DATA_BLOB v1, v2, v3;
|
||||
|
||||
TALLOC_CTX *mem_ctx;
|
||||
char *str1, *str2;
|
||||
size_t size1, size2;
|
||||
bool ret = false;
|
||||
|
||||
cache = memcache_init(NULL, 100);
|
||||
|
||||
if (cache == NULL) {
|
||||
@ -5342,7 +5347,33 @@ static bool run_local_memcache(int dummy)
|
||||
}
|
||||
|
||||
TALLOC_FREE(cache);
|
||||
return true;
|
||||
|
||||
cache = memcache_init(NULL, 0);
|
||||
|
||||
mem_ctx = talloc_init("foo");
|
||||
|
||||
str1 = talloc_strdup(mem_ctx, "string1");
|
||||
str2 = talloc_strdup(mem_ctx, "string2");
|
||||
|
||||
memcache_add_talloc(cache, SINGLETON_CACHE_TALLOC,
|
||||
data_blob_string_const("torture"), str1);
|
||||
size1 = talloc_total_size(cache);
|
||||
|
||||
memcache_add_talloc(cache, SINGLETON_CACHE_TALLOC,
|
||||
data_blob_string_const("torture"), str2);
|
||||
size2 = talloc_total_size(cache);
|
||||
|
||||
printf("size1=%d, size2=%d\n", (int)size1, (int)size2);
|
||||
|
||||
if (size2 > size1) {
|
||||
printf("memcache leaks memory!\n");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
ret = true;
|
||||
fail:
|
||||
TALLOC_FREE(cache);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static double create_procs(bool (*fn)(int), bool *result)
|
||||
|
Loading…
Reference in New Issue
Block a user