The branch, v3-3-test has been updated
       via  076bc9a21e540b25180a8d63e1e0c3eb071c16f7 (commit)
       via  280f3842fefc5cd2f65bfede70f6376d03946599 (commit)
      from  6fb1f994b55f0ce3777370fe80cde1d0964ba8b2 (commit)

http://gitweb.samba.org/?p=samba.git;a=shortlog;h=v3-3-test


- Log -----------------------------------------------------------------
commit 076bc9a21e540b25180a8d63e1e0c3eb071c16f7
Author: Volker Lendecke <[EMAIL PROTECTED]>
Date:   Fri Nov 14 13:42:54 2008 +0100

    Make memcache_add_talloc NULL out the source pointer
    
    This is an orthogonality measure to make clear this pointer now belongs to 
the
    cache.
    (cherry picked from commit e6080c6e87d6fe3995b121a772bf3f6343fa666f)

commit 280f3842fefc5cd2f65bfede70f6376d03946599
Author: Volker Lendecke <[EMAIL PROTECTED]>
Date:   Thu Nov 13 23:50:19 2008 +0100

    Actually finish memcache_add_talloc
    
    This fixes a memleak found by Martin Zielinski <[EMAIL PROTECTED]>. Thanks 
for
    looking closely!
    
    Volker
    (cherry picked from commit a31a84a078100819809e6d40dbc3df207a50a0b2)

-----------------------------------------------------------------------

Summary of changes:
 source/auth/token_util.c      |    6 +++-
 source/lib/memcache.c         |   49 +++++++++++++++++++++++++++++++++++++++-
 source/lib/util_pw.c          |    2 +-
 source/passdb/pdb_interface.c |   14 ++++++------
 source/torture/torture.c      |   33 ++++++++++++++++++++++++++-
 5 files changed, 91 insertions(+), 13 deletions(-)


Changeset truncated at 500 lines:

diff --git a/source/auth/token_util.c b/source/auth/token_util.c
index bb8f222..7aa5391 100644
--- a/source/auth/token_util.c
+++ b/source/auth/token_util.c
@@ -77,7 +77,7 @@ bool nt_token_check_domain_rid( NT_USER_TOKEN *token, uint32 
rid )
 
 NT_USER_TOKEN *get_root_nt_token( void )
 {
-       struct nt_user_token *token = NULL;
+       struct nt_user_token *token, *for_cache;
        DOM_SID u_sid, g_sid;
        struct passwd *pw;
        void *cache_data;
@@ -107,9 +107,11 @@ NT_USER_TOKEN *get_root_nt_token( void )
 
        token->privileges = se_disk_operators;
 
+       for_cache = token;
+
        memcache_add_talloc(
                NULL, SINGLETON_CACHE_TALLOC,
-               data_blob_string_const("root_nt_token"), token);
+               data_blob_string_const("root_nt_token"), &for_cache);
 
        return token;
 }
diff --git a/source/lib/memcache.c b/source/lib/memcache.c
index 74bc804..4cd9a94 100644
--- a/source/lib/memcache.c
+++ b/source/lib/memcache.c
@@ -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
                         */
@@ -306,9 +340,20 @@ 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)
+                        DATA_BLOB key, void *pptr)
 {
-       memcache_add(cache, n, key, data_blob_const(&ptr, sizeof(ptr)));
+       void **ptr = (void **)pptr;
+       void *p;
+
+       if (cache == NULL) {
+               cache = global_cache;
+       }
+       if (cache == NULL) {
+               return;
+       }
+
+       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)
diff --git a/source/lib/util_pw.c b/source/lib/util_pw.c
index f0f3f00..bf09c42 100644
--- a/source/lib/util_pw.c
+++ b/source/lib/util_pw.c
@@ -63,7 +63,7 @@ struct passwd *getpwnam_alloc(TALLOC_CTX *mem_ctx, const char 
*name)
        }
 
        memcache_add_talloc(NULL, GETPWNAM_CACHE, data_blob_string_const(name),
-                           for_cache);
+                           &for_cache);
 
        return tcopy_passwd(mem_ctx, pw);
 }
diff --git a/source/passdb/pdb_interface.c b/source/passdb/pdb_interface.c
index 6fe1058..5a79f09 100644
--- a/source/passdb/pdb_interface.c
+++ b/source/passdb/pdb_interface.c
@@ -207,28 +207,28 @@ static struct pdb_methods *pdb_get_methods(void)
 bool pdb_getsampwnam(struct samu *sam_acct, const char *username) 
 {
        struct pdb_methods *pdb = pdb_get_methods();
-       struct samu *cache_copy;
+       struct samu *for_cache;
        const struct dom_sid *user_sid;
 
        if (!NT_STATUS_IS_OK(pdb->getsampwnam(pdb, sam_acct, username))) {
                return False;
        }
 
-       cache_copy = samu_new(NULL);
-       if (cache_copy == NULL) {
+       for_cache = samu_new(NULL);
+       if (for_cache == NULL) {
                return False;
        }
 
-       if (!pdb_copy_sam_account(cache_copy, sam_acct)) {
-               TALLOC_FREE(cache_copy);
+       if (!pdb_copy_sam_account(for_cache, sam_acct)) {
+               TALLOC_FREE(for_cache);
                return False;
        }
 
-       user_sid = pdb_get_user_sid(cache_copy);
+       user_sid = pdb_get_user_sid(for_cache);
 
        memcache_add_talloc(NULL, PDB_GETPWSID_CACHE,
                            data_blob_const(user_sid, sizeof(*user_sid)),
-                           cache_copy);
+                           &for_cache);
 
        return True;
 }
diff --git a/source/torture/torture.c b/source/torture/torture.c
index 75a5b30..a4b4679 100644
--- a/source/torture/torture.c
+++ b/source/torture/torture.c
@@ -5189,6 +5189,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) {
@@ -5240,7 +5245,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)


-- 
Samba Shared Repository

Reply via email to