The branch, master has been updated
       via  127352c source4/torture: add talloc_stackframe()
       via  06731bc source3/netapi: fix only caller which doesn't set up a 
talloc_stackframe()
       via  d54ebd3 source3/passdb/py_passdb.c: wrap all calls in 
talloc_stackframe()
       via  9927233 source3/passdb/py_passdb.c: don't steal from 
talloc_stackframe().
       via  51ec59d source3/torture/pdbtest: allocate talloc_stackframe()
       via  1f8b574 talloc_stack: abort in developer me if no stackframe on 
talloc_tos()
       via  fe72740 loadparm: make the source3/ lp_ functions take an explicit 
TALLOC_CTX *.
       via  c809eec source3/utils/net_conf.c: fix stackframe leak
       via  aa2e02e source3/winbindd/winbindd_pam.c: fix stackframe leak
       via  f3001e8 source3/lib/smbconf/testsuite.c: fix stackframe leak
       via  15faffc source3/registry/reg_backend_db.c: fix stackframe leak
       via  5716570 source3/winbindd/idmap_tdb_common.c: fix stackframe leak
       via  32c69e6 source3/rpc_server/svcctl/srv_svcctl_reg.c: fix stackframe 
leak
       via  bdc59fb source3/modules/vfs_xattr_tdb.c: fix stackframe leak
       via  a620fc0 lib/util/modules.c: fix stackframe leak.
       via  2314c60 source3/winbindd/winbindd_util.c: fix stackframe leak
       via  7a65910 nt_printing_tdb_migrate(): fix stackframe leak.
       via  dcec7c1 source3/client/client.c: fix stackframe leak.
       via  634a63d smbpasswd: always free frame.
       via  84fb37f talloc_stack: report lazy freeing (panic if DEVELOPER).
       via  f9b51ff talloc_stack: always include the location when creating a 
talloc_stackframe().
       via  311281c talloc_stack: handle more than one talloc_stackframe_pool()
       via  4f33187 talloc: don't allow a talloc_pool inside a talloc_pool.
       via  8893215 talloc: use a struct for pool headers.
      from  d1a5a5b s3-linux-aio: Fix error handling

http://gitweb.samba.org/?p=samba.git;a=shortlog;h=master


- Log -----------------------------------------------------------------
commit 127352c78c0328d59d742f0b4520ebaac6307854
Author: Rusty Russell <ru...@rustcorp.com.au>
Date:   Wed Jul 18 15:07:28 2012 +0930

    source4/torture: add talloc_stackframe()
    
    We need a stackframe to call lp_load().
    
    Signed-off-by: Rusty Russell <ru...@rustcorp.com.au>
    
    Autobuild-User(master): Rusty Russell <ru...@rustcorp.com.au>
    Autobuild-Date(master): Wed Jul 18 09:31:07 CEST 2012 on sn-devel-104

commit 06731bc28f5bff963f75451a0d7dd7445e94407c
Author: Rusty Russell <ru...@rustcorp.com.au>
Date:   Wed Jul 18 15:07:28 2012 +0930

    source3/netapi: fix only caller which doesn't set up a talloc_stackframe()
    
    libnetapi_free() needs a stackframe too; looked like Andrew and Günther
    missed this in a37de9a95974c138d264d9cb0c7829bb426bb2d6.
    
    Signed-off-by: Rusty Russell <ru...@rustcorp.com.au>

commit d54ebd36cc95ae13844bd00d5bbb2e3ff1a06285
Author: Rusty Russell <ru...@rustcorp.com.au>
Date:   Wed Jul 18 15:07:28 2012 +0930

    source3/passdb/py_passdb.c: wrap all calls in talloc_stackframe()
    
    dbwrap needs it.  Some calls were already wrapped, but they checked the
    talloc_stackframe() return unnecessarily: it can never be NULL.
    
    This is the coccinelle patch I used:
    
    // Add in a stackframe to every function: be sure to free it on (every) 
return
    @rule0@
    identifier func;
    @@
    func(...) {
    +TALLOC_CTX *frame = talloc_stackframe();
    <...
    +talloc_free(frame);
    return ...;
    ...>
    }
    
    // Get rid of tframe allocation/frees, replace usage with frame.
    @rule1@
    identifier func;
    identifier oldframe;
    @@
    func(...) {
    ...
    -TALLOC_CTX *oldframe;
    ...
    -if ((oldframe = talloc_stackframe()) == NULL) {
    -   ...
    -}
    <...
    -talloc_free(oldframe);
    ...>
    }
    
    // Get rid of tframe (variant 2)
    @rule2@
    identifier func;
    identifier oldframe;
    @@
    func(...) {
    ...
    -TALLOC_CTX *oldframe;
    ...
    -oldframe = talloc_stackframe();
    -if (oldframe == NULL) {
    -   ...
    -}
    <...
    -talloc_free(oldframe);
    ...>
    }
    
    // Change tframe to frame
    @rule3@
    identifier func;
    @@
    func(...) {
    <...
    -tframe
    +frame
    ...>
    }
    
    Signed-off-by: Rusty Russell <ru...@rustcorp.com.au>

commit 99272331c60afa900852d996196b434ecd897287
Author: Rusty Russell <ru...@rustcorp.com.au>
Date:   Wed Jul 18 15:07:28 2012 +0930

    source3/passdb/py_passdb.c: don't steal from talloc_stackframe().
    
    If you want a stack-style allocation, use talloc_stackframe().  If you
    don't, don't use it.  In particular, talloc_stackframe() here is actually
    inside a pool, and stealing from pools is a bad idea.
    
    Signed-off-by: Rusty Russell <ru...@rustcorp.com.au>

commit 51ec59db10306fd90211c237fd672acf3ab3304a
Author: Rusty Russell <ru...@rustcorp.com.au>
Date:   Wed Jul 18 15:07:28 2012 +0930

    source3/torture/pdbtest: allocate talloc_stackframe()
    
    Avoid talloc_tos() without a stackframe.
    
    Signed-off-by: Rusty Russell <ru...@rustcorp.com.au>

commit 1f8b574adb10397ca4b9dc4a55281d3afaaeabfc
Author: Rusty Russell <ru...@rustcorp.com.au>
Date:   Wed Jul 18 15:07:27 2012 +0930

    talloc_stack: abort in developer me if no stackframe on talloc_tos()
    
    Don't tolerate leaks in developer mode.
    
    Signed-off-by: Rusty Russell <ru...@rustcorp.com.au>

commit fe72740e8221575921c22030d6d4fcb19201b03b
Author: Rusty Russell <ru...@rustcorp.com.au>
Date:   Wed Jul 18 15:07:23 2012 +0930

    loadparm: make the source3/ lp_ functions take an explicit TALLOC_CTX *.
    
    They use talloc_tos() internally: hoist that up to the callers, some
    of whom don't want to us talloc_tos().
    
    A simple patch, but hits a lot of files.
    
    Signed-off-by: Rusty Russell <ru...@rustcorp.com.au>

commit c809eec53fb1d2a36909e4934dff349f91e3359e
Author: Rusty Russell <ru...@rustcorp.com.au>
Date:   Wed Jul 18 05:09:31 2012 +0930

    source3/utils/net_conf.c: fix stackframe leak
    
    net_conf_wrap_function() doesn't free its stackframe.
    
    Signed-off-by: Rusty Russell <ru...@rustcorp.com.au>

commit aa2e02e6846c4fa8199ebafbe6b9e050df8af16b
Author: Rusty Russell <ru...@rustcorp.com.au>
Date:   Wed Jul 18 05:08:31 2012 +0930

    source3/winbindd/winbindd_pam.c: fix stackframe leak
    
    check_info3_in_group() doesn't always free its stackframe.
    
    Signed-off-by: Rusty Russell <ru...@rustcorp.com.au>

commit f3001e808c3b1ea35358f41154360709642cf282
Author: Rusty Russell <ru...@rustcorp.com.au>
Date:   Wed Jul 18 05:07:31 2012 +0930

    source3/lib/smbconf/testsuite.c: fix stackframe leak
    
    Signed-off-by: Rusty Russell <ru...@rustcorp.com.au>

commit 15faffc53752f27c550c305435a1d7e1ea58514f
Author: Rusty Russell <ru...@rustcorp.com.au>
Date:   Wed Jul 18 05:06:31 2012 +0930

    source3/registry/reg_backend_db.c: fix stackframe leak
    
    regdb_store_values_internal() doesn't always free its stackframe.
    
    Signed-off-by: Rusty Russell <ru...@rustcorp.com.au>

commit 5716570cbc1db1bf0d60441622f79ac934443232
Author: Rusty Russell <ru...@rustcorp.com.au>
Date:   Wed Jul 18 05:05:31 2012 +0930

    source3/winbindd/idmap_tdb_common.c: fix stackframe leak
    
    idmap_tdb_common_sid_to_unixid() doesn't always free its stackframe.
    
    Signed-off-by: Rusty Russell <ru...@rustcorp.com.au>

commit 32c69e6e2a089812610599ee9e0e832d2ffe195a
Author: Rusty Russell <ru...@rustcorp.com.au>
Date:   Wed Jul 18 05:04:31 2012 +0930

    source3/rpc_server/svcctl/srv_svcctl_reg.c: fix stackframe leak
    
    svcctl_init_winreg() doesn't free its stackframe.
    
    Signed-off-by: Rusty Russell <ru...@rustcorp.com.au>

commit bdc59fb538345d9571554dfef79469fa2c325c90
Author: Rusty Russell <ru...@rustcorp.com.au>
Date:   Wed Jul 18 05:03:31 2012 +0930

    source3/modules/vfs_xattr_tdb.c: fix stackframe leak
    
    xattr_tdb_getxattr() doesn't free its stackframe.
    
    Signed-off-by: Rusty Russell <ru...@rustcorp.com.au>

commit a620fc0372a8c493c8d4800acc42cc630acebcb4
Author: Rusty Russell <ru...@rustcorp.com.au>
Date:   Wed Jul 18 05:02:31 2012 +0930

    lib/util/modules.c: fix stackframe leak.
    
    do_smb_load_module() doesn't free its stackframe on success.
    
    Signed-off-by: Rusty Russell <ru...@rustcorp.com.au>

commit 2314c606297218b8e16bb42b181c1ea175cf710a
Author: Rusty Russell <ru...@rustcorp.com.au>
Date:   Wed Jul 18 05:01:31 2012 +0930

    source3/winbindd/winbindd_util.c: fix stackframe leak
    
    winbindd_can_contact_domain() doesn't always free its stackframe.
    
    Signed-off-by: Rusty Russell <ru...@rustcorp.com.au>

commit 7a6591037b22773c03a7592230f33832b0775237
Author: Rusty Russell <ru...@rustcorp.com.au>
Date:   Wed Jul 18 05:00:31 2012 +0930

    nt_printing_tdb_migrate(): fix stackframe leak.
    
    Signed-off-by: Rusty Russell <ru...@rustcorp.com.au>

commit dcec7c1f71937ad301be95050fb0e69aede7648c
Author: Rusty Russell <ru...@rustcorp.com.au>
Date:   Wed Jul 18 04:59:31 2012 +0930

    source3/client/client.c: fix stackframe leak.
    
    do_message_op() doesn't free its stackframe in various paths.
    
    Signed-off-by: Rusty Russell <ru...@rustcorp.com.au>

commit 634a63d934db6f01fd8c2584af9ab05e05762a0d
Author: Rusty Russell <ru...@rustcorp.com.au>
Date:   Wed Jul 18 04:58:31 2012 +0930

    smbpasswd: always free frame.
    
    We're about to exit, so it doesn't really matter, but might as well
    unify the paths.
    
    Signed-off-by: Rusty Russell <ru...@rustcorp.com.au>

commit 84fb37fe372bc22e0a3ceca8030bff459225044a
Author: Rusty Russell <ru...@rustcorp.com.au>
Date:   Wed Jul 18 04:57:31 2012 +0930

    talloc_stack: report lazy freeing (panic if DEVELOPER).
    
    talloc_stackframe() stacks, so if you forget to free one, the outer
    one will free it.  However, it's not a good idea to rely too heavily
    on this behaviour: it can lead to delays in the release of memory or
    destructors.
    
    I had an elaborate hack to make sure every talloc_stackframe() was
    freed in the exact same function it was allocated, however all bugs it
    caught were simply lazy freeing, so this patch just checks for that.
    
    This doesn't check for stackframes we don't free up on exit: that would
    be nice, but uncovers some uncomfortable (but probably harmless) cases.
    
    Signed-off-by: Rusty Russell <ru...@rustcorp.com.au>

commit f9b51ff33e10aa126de848072e98b0bf36a7dbc7
Author: Rusty Russell <ru...@rustcorp.com.au>
Date:   Wed Jul 18 04:56:31 2012 +0930

    talloc_stack: always include the location when creating a 
talloc_stackframe().
    
    Much better for debugging.
    
    Signed-off-by: Rusty Russell <ru...@rustcorp.com.au>

commit 311281c2c550b71ec4d8b2fc7329a1dfe5af82b0
Author: Rusty Russell <ru...@rustcorp.com.au>
Date:   Wed Jul 18 04:55:31 2012 +0930

    talloc_stack: handle more than one talloc_stackframe_pool()
    
    The only reason we make one stackframe parent of the next is so we use
    our parent's pool.  That doesn't make sense if we're a new pool, and
    wouldn't work anyway.
    
    Signed-off-by: Rusty Russell <ru...@rustcorp.com.au>

commit 4f331872bc783445c709e5fe4846b8687e274953
Author: Rusty Russell <ru...@rustcorp.com.au>
Date:   Wed Jul 18 04:54:31 2012 +0930

    talloc: don't allow a talloc_pool inside a talloc_pool.
    
    We explicitly call free() on a pool which falls to zero, assuming it's
    not inside another pool (we crash).  Check on creation and explicitly
    document this case.
    
    Signed-off-by: Rusty Russell <ru...@rustcorp.com.au>

commit 8893215aaf714154c190c66bf7d1ce568118ec39
Author: Rusty Russell <ru...@rustcorp.com.au>
Date:   Wed Jul 18 04:53:31 2012 +0930

    talloc: use a struct for pool headers.
    
    This neatens the code a bit (we should do a similar thing for all the
    TALLOC_CHUNK macros).
    
    Two subtler changes:
    (1) As a result of the struct, we actually pack object_count into the
        talloc header on 32-bit platforms (since the header is 40 bytes, but
        needs to be 16-byte aligned).
    (2) I avoid VALGRIND_MAKE_MEM_UNDEFINED on memmove when we resize the
        only entry in a pool; that's done later anyway.
    
    With -O2 on my 11.04 Ubuntu 32-bit x86 laptop, the talloc_pool speed as
    measured by testsuite.c actually increases 10%.
    
    Signed-off-by: Rusty Russell <ru...@rustcorp.com.au>

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

Summary of changes:
 lib/talloc/talloc.c                             |  201 +++---
 lib/talloc/talloc.h                             |    3 +-
 lib/talloc/testsuite.c                          |    2 +-
 lib/util/debug_s3.c                             |    2 +-
 lib/util/modules.c                              |    3 +-
 lib/util/talloc_stack.c                         |   51 +-
 lib/util/talloc_stack.h                         |    9 +-
 source3/auth/auth_util.c                        |    8 +-
 source3/auth/pampass.c                          |    2 +-
 source3/auth/user_util.c                        |    4 +-
 source3/client/client.c                         |   22 +-
 source3/groupdb/mapping.c                       |   20 +-
 source3/include/proto.h                         |  162 ++--
 source3/lib/netapi/netapi.c                     |    4 +
 source3/lib/netapi/serverinfo.c                 |    4 +-
 source3/lib/smbconf/testsuite.c                 |    1 +
 source3/lib/smbldap.c                           |    3 +-
 source3/lib/sysquotas.c                         |    4 +-
 source3/lib/util.c                              |    4 +-
 source3/libnet/libnet_dssync_passdb.c           |    4 +-
 source3/libnet/libnet_samsync_ldif.c            |   40 +-
 source3/libnet/libnet_samsync_passdb.c          |    4 +-
 source3/modules/vfs_default.c                   |    2 +-
 source3/modules/vfs_dfs_samba4.c                |    2 +-
 source3/modules/vfs_expand_msdfs.c              |    2 +-
 source3/modules/vfs_fileid.c                    |    2 +-
 source3/modules/vfs_full_audit.c                |    4 +-
 source3/modules/vfs_recycle.c                   |    2 +-
 source3/modules/vfs_xattr_tdb.c                 |    4 +-
 source3/nmbd/nmbd.c                             |    4 +-
 source3/nmbd/nmbd_sendannounce.c                |    7 +-
 source3/nmbd/nmbd_serverlistdb.c                |    2 +-
 source3/nmbd/nmbd_winsserver.c                  |    2 +-
 source3/nmbd/nmbd_workgroupdb.c                 |    2 +-
 source3/param/loadparm.c                        |  115 ++--
 source3/param/service.c                         |    4 +-
 source3/passdb/pdb_interface.c                  |    8 +-
 source3/passdb/pdb_ipa.c                        |    8 +-
 source3/passdb/pdb_ldap.c                       |   54 +-
 source3/passdb/pdb_ldap_util.c                  |    6 +-
 source3/passdb/pdb_smbpasswd.c                  |    5 +-
 source3/passdb/pdb_tdb.c                        |    2 +-
 source3/passdb/py_passdb.c                      | 1025 +++++++++++------------
 source3/passdb/secrets.c                        |    2 +-
 source3/printing/load.c                         |    2 +-
 source3/printing/notify.c                       |   16 +-
 source3/printing/nt_printing.c                  |   10 +-
 source3/printing/nt_printing_ads.c              |    2 +-
 source3/printing/nt_printing_migrate_internal.c |    1 +
 source3/printing/nt_printing_os2.c              |    2 +-
 source3/printing/print_cups.c                   |   28 +-
 source3/printing/print_generic.c                |   26 +-
 source3/printing/print_iprint.c                 |   24 +-
 source3/printing/printing.c                     |   38 +-
 source3/printing/printspoolss.c                 |    5 +-
 source3/printing/spoolssd.c                     |   12 +-
 source3/registry/reg_backend_db.c               |    6 +-
 source3/rpc_server/epmd.c                       |    5 +-
 source3/rpc_server/lsasd.c                      |    6 +-
 source3/rpc_server/samr/srv_samr_chgpasswd.c    |   10 +-
 source3/rpc_server/samr/srv_samr_nt.c           |   14 +-
 source3/rpc_server/spoolss/srv_spoolss_nt.c     |   40 +-
 source3/rpc_server/srvsvc/srv_srvsvc_nt.c       |   97 ++--
 source3/rpc_server/svcctl/srv_svcctl_reg.c      |    1 +
 source3/rpc_server/winreg/srv_winreg_nt.c       |   10 +-
 source3/smbd/close.c                            |   10 +-
 source3/smbd/conn_idle.c                        |    3 +-
 source3/smbd/connection.c                       |    7 +-
 source3/smbd/dfree.c                            |    2 +-
 source3/smbd/dosmode.c                          |    2 +-
 source3/smbd/fake_file.c                        |    4 +-
 source3/smbd/lanman.c                           |   25 +-
 source3/smbd/mangle.c                           |    2 +-
 source3/smbd/message.c                          |   12 +-
 source3/smbd/msdfs.c                            |   41 +-
 source3/smbd/nttrans.c                          |    4 +-
 source3/smbd/open.c                             |    2 +-
 source3/smbd/password.c                         |    2 +-
 source3/smbd/perfcount.c                        |    2 +-
 source3/smbd/process.c                          |   11 +-
 source3/smbd/reply.c                            |   16 +-
 source3/smbd/server.c                           |    2 +-
 source3/smbd/server_reload.c                    |    8 +-
 source3/smbd/service.c                          |  102 ++--
 source3/smbd/share_access.c                     |   19 +-
 source3/smbd/smb2_find.c                        |    4 +-
 source3/smbd/smb2_tcon.c                        |    7 +-
 source3/smbd/trans2.c                           |   40 +-
 source3/smbd/uid.c                              |   15 +-
 source3/torture/cmd_vfs.c                       |    2 +-
 source3/torture/pdbtest.c                       |    4 +-
 source3/utils/net_conf.c                        |    2 +
 source3/utils/net_idmap.c                       |    3 +-
 source3/utils/net_sam.c                         |   15 +-
 source3/utils/net_usershare.c                   |    8 +-
 source3/utils/smbpasswd.c                       |   12 +-
 source3/utils/testparm.c                        |   44 +-
 source3/web/swat.c                              |    6 +-
 source3/winbindd/idmap_ldap.c                   |    2 +-
 source3/winbindd/idmap_tdb_common.c             |    1 +
 source3/winbindd/winbindd.c                     |    8 +-
 source3/winbindd/winbindd_dual.c                |    4 +-
 source3/winbindd/winbindd_pam.c                 |    1 +
 source3/winbindd/winbindd_util.c                |    6 +-
 source4/torture/libnetapi/libnetapi.c           |    3 +
 105 files changed, 1331 insertions(+), 1308 deletions(-)


Changeset truncated at 500 lines:

diff --git a/lib/talloc/talloc.c b/lib/talloc/talloc.c
index e5fd0d2..18ee548 100644
--- a/lib/talloc/talloc.c
+++ b/lib/talloc/talloc.c
@@ -437,49 +437,50 @@ _PUBLIC_ const char *talloc_parent_name(const void *ptr)
   memory footprint of each talloc chunk by those 16 bytes.
 */
 
-#define TALLOC_POOL_HDR_SIZE 16
+union talloc_pool_chunk {
+       /* This lets object_count nestle into 16-byte padding of talloc_chunk,
+        * on 32-bit platforms. */
+       struct tc_pool_hdr {
+               struct talloc_chunk c;
+               unsigned int object_count;
+       } hdr;
+       /* This makes it always 16 byte aligned. */
+       char pad[TC_ALIGN16(sizeof(struct tc_pool_hdr))];
+};
 
-#define TC_POOL_SPACE_LEFT(_pool_tc) \
-       PTR_DIFF(TC_HDR_SIZE + (_pool_tc)->size + (char *)(_pool_tc), \
-                (_pool_tc)->pool)
+static void *tc_pool_end(union talloc_pool_chunk *pool_tc)
+{
+       return (char *)pool_tc + TC_HDR_SIZE + pool_tc->hdr.c.size;
+}
 
-#define TC_POOL_FIRST_CHUNK(_pool_tc) \
-       ((void *)(TC_HDR_SIZE + TALLOC_POOL_HDR_SIZE + (char *)(_pool_tc)))
+static size_t tc_pool_space_left(union talloc_pool_chunk *pool_tc)
+{
+       return (char *)tc_pool_end(pool_tc) - (char *)pool_tc->hdr.c.pool;
+}
 
-#define TC_POOLMEM_CHUNK_SIZE(_tc) \
-       TC_ALIGN16(TC_HDR_SIZE + (_tc)->size)
+static void *tc_pool_first_chunk(union talloc_pool_chunk *pool_tc)
+{
+       return pool_tc + 1;
+}
 
-#define TC_POOLMEM_NEXT_CHUNK(_tc) \
-       ((void *)(TC_POOLMEM_CHUNK_SIZE(tc) + (char*)(_tc)))
+/* If tc is inside a pool, this gives the next neighbour. */
+static void *tc_next_chunk(struct talloc_chunk *tc)
+{
+       return (char *)tc + TC_ALIGN16(TC_HDR_SIZE + tc->size);
+}
 
 /* Mark the whole remaining pool as not accessable */
-#define TC_INVALIDATE_FILL_POOL(_pool_tc) do { \
-       if (unlikely(talloc_fill.enabled)) { \
-               size_t _flen = TC_POOL_SPACE_LEFT(_pool_tc); \
-               char *_fptr = (char *)(_pool_tc)->pool; \
-               memset(_fptr, talloc_fill.fill_value, _flen); \
-       } \
-} while(0)
+static void tc_invalidate_pool(union talloc_pool_chunk *pool_tc)
+{
+       size_t flen = tc_pool_space_left(pool_tc);
+
+       if (unlikely(talloc_fill.enabled)) {
+               memset(pool_tc->hdr.c.pool, talloc_fill.fill_value, flen);
+       }
 
 #if defined(DEVELOPER) && defined(VALGRIND_MAKE_MEM_NOACCESS)
-/* Mark the whole remaining pool as not accessable */
-#define TC_INVALIDATE_VALGRIND_POOL(_pool_tc) do { \
-       size_t _flen = TC_POOL_SPACE_LEFT(_pool_tc); \
-       char *_fptr = (char *)(_pool_tc)->pool; \
-       VALGRIND_MAKE_MEM_NOACCESS(_fptr, _flen); \
-} while(0)
-#else
-#define TC_INVALIDATE_VALGRIND_POOL(_pool_tc) do { } while (0)
+       VALGRIND_MAKE_MEM_NOACCESS(pool_tc->hdr.c.pool, flen);
 #endif
-
-#define TC_INVALIDATE_POOL(_pool_tc) do { \
-       TC_INVALIDATE_FILL_POOL(_pool_tc); \
-       TC_INVALIDATE_VALGRIND_POOL(_pool_tc); \
-} while (0)
-
-static unsigned int *talloc_pool_objectcount(struct talloc_chunk *tc)
-{
-       return (unsigned int *)((char *)tc + TC_HDR_SIZE);
 }
 
 /*
@@ -489,7 +490,7 @@ static unsigned int *talloc_pool_objectcount(struct 
talloc_chunk *tc)
 static struct talloc_chunk *talloc_alloc_pool(struct talloc_chunk *parent,
                                              size_t size)
 {
-       struct talloc_chunk *pool_ctx = NULL;
+       union talloc_pool_chunk *pool_ctx = NULL;
        size_t space_left;
        struct talloc_chunk *result;
        size_t chunk_size;
@@ -499,17 +500,17 @@ static struct talloc_chunk *talloc_alloc_pool(struct 
talloc_chunk *parent,
        }
 
        if (parent->flags & TALLOC_FLAG_POOL) {
-               pool_ctx = parent;
+               pool_ctx = (union talloc_pool_chunk *)parent;
        }
        else if (parent->flags & TALLOC_FLAG_POOLMEM) {
-               pool_ctx = (struct talloc_chunk *)parent->pool;
+               pool_ctx = (union talloc_pool_chunk *)parent->pool;
        }
 
        if (pool_ctx == NULL) {
                return NULL;
        }
 
-       space_left = TC_POOL_SPACE_LEFT(pool_ctx);
+       space_left = tc_pool_space_left(pool_ctx);
 
        /*
         * Align size to 16 bytes
@@ -520,18 +521,18 @@ static struct talloc_chunk *talloc_alloc_pool(struct 
talloc_chunk *parent,
                return NULL;
        }
 
-       result = (struct talloc_chunk *)pool_ctx->pool;
+       result = (struct talloc_chunk *)pool_ctx->hdr.c.pool;
 
 #if defined(DEVELOPER) && defined(VALGRIND_MAKE_MEM_UNDEFINED)
        VALGRIND_MAKE_MEM_UNDEFINED(result, size);
 #endif
 
-       pool_ctx->pool = (void *)((char *)result + chunk_size);
+       pool_ctx->hdr.c.pool = (void *)((char *)result + chunk_size);
 
        result->flags = TALLOC_MAGIC | TALLOC_FLAG_POOLMEM;
        result->pool = pool_ctx;
 
-       *talloc_pool_objectcount(pool_ctx) += 1;
+       pool_ctx->hdr.object_count++;
 
        return result;
 }
@@ -595,21 +596,27 @@ static inline void *__talloc(const void *context, size_t 
size)
 
 _PUBLIC_ void *talloc_pool(const void *context, size_t size)
 {
-       void *result = __talloc(context, size + TALLOC_POOL_HDR_SIZE);
-       struct talloc_chunk *tc;
+       union talloc_pool_chunk *pool_tc;
+       void *result = __talloc(context, sizeof(*pool_tc) - TC_HDR_SIZE + size);
 
        if (unlikely(result == NULL)) {
                return NULL;
        }
 
-       tc = talloc_chunk_from_ptr(result);
-
-       tc->flags |= TALLOC_FLAG_POOL;
-       tc->pool = TC_POOL_FIRST_CHUNK(tc);
+       pool_tc = (union talloc_pool_chunk *)talloc_chunk_from_ptr(result);
+       if (unlikely(pool_tc->hdr.c.flags & TALLOC_FLAG_POOLMEM)) {
+               /* We don't handle this correctly, so fail. */
+               talloc_log("talloc: cannot allocate pool off another pool %s\n",
+                          talloc_get_name(context));
+               talloc_free(result);
+               return NULL;
+       }
+       pool_tc->hdr.c.flags |= TALLOC_FLAG_POOL;
+       pool_tc->hdr.c.pool = tc_pool_first_chunk(pool_tc);
 
-       *talloc_pool_objectcount(tc) = 1;
+       pool_tc->hdr.object_count = 1;
 
-       TC_INVALIDATE_POOL(tc);
+       tc_invalidate_pool(pool_tc);
 
        return result;
 }
@@ -712,12 +719,11 @@ static void *_talloc_steal_internal(const void *new_ctx, 
const void *ptr);
 static inline void _talloc_free_poolmem(struct talloc_chunk *tc,
                                        const char *location)
 {
-       struct talloc_chunk *pool;
+       union talloc_pool_chunk *pool;
        void *next_tc;
-       unsigned int *pool_object_count;
 
-       pool = (struct talloc_chunk *)tc->pool;
-       next_tc = TC_POOLMEM_NEXT_CHUNK(tc);
+       pool = (union talloc_pool_chunk *)tc->pool;
+       next_tc = tc_next_chunk(tc);
 
        tc->flags |= TALLOC_FLAG_FREE;
 
@@ -729,16 +735,15 @@ static inline void _talloc_free_poolmem(struct 
talloc_chunk *tc,
 
        TC_INVALIDATE_FULL_CHUNK(tc);
 
-       pool_object_count = talloc_pool_objectcount(pool);
-
-       if (unlikely(*pool_object_count == 0)) {
+       if (unlikely(pool->hdr.object_count == 0)) {
                talloc_abort("Pool object count zero!");
                return;
        }
 
-       *pool_object_count -= 1;
+       pool->hdr.object_count--;
 
-       if (unlikely(*pool_object_count == 1 && !(pool->flags & 
TALLOC_FLAG_FREE))) {
+       if (unlikely(pool->hdr.object_count == 1
+                    && !(pool->hdr.c.flags & TALLOC_FLAG_FREE))) {
                /*
                 * if there is just one object left in the pool
                 * and pool->flags does not have TALLOC_FLAG_FREE,
@@ -746,25 +751,25 @@ static inline void _talloc_free_poolmem(struct 
talloc_chunk *tc,
                 * the rest is available for new objects
                 * again.
                 */
-               pool->pool = TC_POOL_FIRST_CHUNK(pool);
-               TC_INVALIDATE_POOL(pool);
-       } else if (unlikely(*pool_object_count == 0)) {
+               pool->hdr.c.pool = tc_pool_first_chunk(pool);
+               tc_invalidate_pool(pool);
+       } else if (unlikely(pool->hdr.object_count == 0)) {
                /*
                 * we mark the freed memory with where we called the free
                 * from. This means on a double free error we can report where
                 * the first free came from
                 */
-               pool->name = location;
+               pool->hdr.c.name = location;
 
-               TC_INVALIDATE_FULL_CHUNK(pool);
+               TC_INVALIDATE_FULL_CHUNK(&pool->hdr.c);
                free(pool);
-       } else if (pool->pool == next_tc) {
+       } else if (pool->hdr.c.pool == next_tc) {
                /*
                 * if pool->pool still points to end of
                 * 'tc' (which is stored in the 'next_tc' variable),
                 * we can reclaim the memory of 'tc'.
                 */
-               pool->pool = tc;
+               pool->hdr.c.pool = tc;
        }
 }
 
@@ -854,18 +859,15 @@ static inline int _talloc_free_internal(void *ptr, const 
char *location)
        tc->name = location;
 
        if (tc->flags & TALLOC_FLAG_POOL) {
-               unsigned int *pool_object_count;
-
-               pool_object_count = talloc_pool_objectcount(tc);
+               union talloc_pool_chunk *pool = (union talloc_pool_chunk *)tc;
 
-               if (unlikely(*pool_object_count == 0)) {
+               if (unlikely(pool->hdr.object_count == 0)) {
                        talloc_abort("Pool object count zero!");
                        return 0;
                }
 
-               *pool_object_count -= 1;
-
-               if (unlikely(*pool_object_count == 0)) {
+               pool->hdr.object_count--;
+               if (unlikely(pool->hdr.object_count == 0)) {
                        TC_INVALIDATE_FULL_CHUNK(tc);
                        free(tc);
                }
@@ -1380,7 +1382,7 @@ _PUBLIC_ void *_talloc_realloc(const void *context, void 
*ptr, size_t size, cons
        struct talloc_chunk *tc;
        void *new_ptr;
        bool malloced = false;
-       struct talloc_chunk *pool_tc = NULL;
+       union talloc_pool_chunk *pool_tc = NULL;
 
        /* size zero is equivalent to free() */
        if (unlikely(size == 0)) {
@@ -1409,20 +1411,21 @@ _PUBLIC_ void *_talloc_realloc(const void *context, 
void *ptr, size_t size, cons
                return NULL;
        }
 
-       /* don't let anybody try to realloc a talloc_pool */
+       /* handle realloc inside a talloc_pool */
        if (unlikely(tc->flags & TALLOC_FLAG_POOLMEM)) {
-               pool_tc = (struct talloc_chunk *)tc->pool;
+               pool_tc = (union talloc_pool_chunk *)tc->pool;
        }
 
 #if (ALWAYS_REALLOC == 0)
        /* don't shrink if we have less than 1k to gain */
        if (size < tc->size) {
                if (pool_tc) {
-                       void *next_tc = TC_POOLMEM_NEXT_CHUNK(tc);
+                       void *next_tc = tc_next_chunk(tc);
                        TC_INVALIDATE_SHRINK_CHUNK(tc, size);
                        tc->size = size;
-                       if (next_tc == pool_tc->pool) {
-                               pool_tc->pool = TC_POOLMEM_NEXT_CHUNK(tc);
+                       if (next_tc == pool_tc->hdr.c.pool) {
+                               /* note: tc->size has changed, so this works */
+                               pool_tc->hdr.c.pool = tc_next_chunk(tc);
                        }
                        return ptr;
                } else if ((tc->size - size) < 1024) {
@@ -1455,7 +1458,7 @@ _PUBLIC_ void *_talloc_realloc(const void *context, void 
*ptr, size_t size, cons
 #if ALWAYS_REALLOC
        if (pool_tc) {
                new_ptr = talloc_alloc_pool(tc, size + TC_HDR_SIZE);
-               *talloc_pool_objectcount(pool_tc) -= 1;
+               pool_tc->hdr.object_count--;
 
                if (new_ptr == NULL) {
                        new_ptr = malloc(TC_HDR_SIZE+size);
@@ -1475,14 +1478,14 @@ _PUBLIC_ void *_talloc_realloc(const void *context, 
void *ptr, size_t size, cons
        }
 #else
        if (pool_tc) {
-               void *next_tc = TC_POOLMEM_NEXT_CHUNK(tc);
-               size_t old_chunk_size = TC_POOLMEM_CHUNK_SIZE(tc);
+               void *next_tc = tc_next_chunk(tc);
+               size_t old_chunk_size = TC_ALIGN16(TC_HDR_SIZE + tc->size);
                size_t new_chunk_size = TC_ALIGN16(TC_HDR_SIZE + size);
                size_t space_needed;
                size_t space_left;
-               unsigned int chunk_count = *talloc_pool_objectcount(pool_tc);
+               unsigned int chunk_count = pool_tc->hdr.object_count;
 
-               if (!(pool_tc->flags & TALLOC_FLAG_FREE)) {
+               if (!(pool_tc->hdr.c.flags & TALLOC_FLAG_FREE)) {
                        chunk_count -= 1;
                }
 
@@ -1491,27 +1494,15 @@ _PUBLIC_ void *_talloc_realloc(const void *context, 
void *ptr, size_t size, cons
                         * optimize for the case where 'tc' is the only
                         * chunk in the pool.
                         */
+                       char *start = tc_pool_first_chunk(pool_tc);
                        space_needed = new_chunk_size;
-                       space_left = pool_tc->size - TALLOC_POOL_HDR_SIZE;
+                       space_left = (char *)tc_pool_end(pool_tc) - start;
 
                        if (space_left >= space_needed) {
                                size_t old_used = TC_HDR_SIZE + tc->size;
                                size_t new_used = TC_HDR_SIZE + size;
-                               pool_tc->pool = TC_POOL_FIRST_CHUNK(pool_tc);
-#if defined(DEVELOPER) && defined(VALGRIND_MAKE_MEM_UNDEFINED)
-                               /*
-                                * we need to prepare the memmove into
-                                * the unaccessable area.
-                                */
-                               {
-                                       size_t diff = PTR_DIFF(tc, 
pool_tc->pool);
-                                       size_t flen = MIN(diff, old_used);
-                                       char *fptr = (char *)pool_tc->pool;
-                                       VALGRIND_MAKE_MEM_UNDEFINED(fptr, flen);
-                               }
-#endif
-                               memmove(pool_tc->pool, tc, old_used);
-                               new_ptr = pool_tc->pool;
+                               new_ptr = start;
+                               memmove(new_ptr, tc, old_used);
 
                                tc = (struct talloc_chunk *)new_ptr;
                                TC_UNDEFINE_GROW_CHUNK(tc, size);
@@ -1521,11 +1512,11 @@ _PUBLIC_ void *_talloc_realloc(const void *context, 
void *ptr, size_t size, cons
                                 * because we want to invalidate the padding
                                 * too.
                                 */
-                               pool_tc->pool = new_used + (char *)new_ptr;
-                               TC_INVALIDATE_POOL(pool_tc);
+                               pool_tc->hdr.c.pool = new_used + (char 
*)new_ptr;
+                               tc_invalidate_pool(pool_tc);
 
                                /* now the aligned pointer */
-                               pool_tc->pool = new_chunk_size + (char 
*)new_ptr;
+                               pool_tc->hdr.c.pool = new_chunk_size + (char 
*)new_ptr;
                                goto got_new_ptr;
                        }
 
@@ -1539,19 +1530,19 @@ _PUBLIC_ void *_talloc_realloc(const void *context, 
void *ptr, size_t size, cons
                        return ptr;
                }
 
-               if (next_tc == pool_tc->pool) {
+               if (next_tc == pool_tc->hdr.c.pool) {
                        /*
                         * optimize for the case where 'tc' is the last
                         * chunk in the pool.
                         */
                        space_needed = new_chunk_size - old_chunk_size;
-                       space_left = TC_POOL_SPACE_LEFT(pool_tc);
+                       space_left = tc_pool_space_left(pool_tc);
 
                        if (space_left >= space_needed) {
                                TC_UNDEFINE_GROW_CHUNK(tc, size);
                                tc->flags &= ~TALLOC_FLAG_FREE;
                                tc->size = size;
-                               pool_tc->pool = TC_POOLMEM_NEXT_CHUNK(tc);
+                               pool_tc->hdr.c.pool = tc_next_chunk(tc);
                                return ptr;
                        }
                }
diff --git a/lib/talloc/talloc.h b/lib/talloc/talloc.h
index 05e6292..e48dc09 100644
--- a/lib/talloc/talloc.h
+++ b/lib/talloc/talloc.h
@@ -839,7 +839,8 @@ void *talloc_find_parent_bytype(const void *ptr, #type);
  * talloc pool to a talloc parent outside the pool, the whole pool memory is
  * not free(3)'ed until that moved chunk is also talloc_free()ed.
  *
- * @param[in]  context  The talloc context to hang the result off.
+ * @param[in]  context  The talloc context to hang the result off (must not
+ *                     be another pool).
  *
  * @param[in]  size     Size of the talloc pool.
  *
diff --git a/lib/talloc/testsuite.c b/lib/talloc/testsuite.c
index 7191703..eaab9d7 100644
--- a/lib/talloc/testsuite.c
+++ b/lib/talloc/testsuite.c
@@ -848,7 +848,7 @@ static bool test_speed(void)
                        p1 = talloc_size(ctx, loop % 100);
                        p2 = talloc_strdup(p1, "foo bar");
                        p3 = talloc_size(p1, 300);
-                       talloc_free_children(ctx);
+                       talloc_free(p1);
                }
                count += 3 * loop;
        } while (timeval_elapsed(&tv) < 5.0);
diff --git a/lib/util/debug_s3.c b/lib/util/debug_s3.c
index cfb6755..ccf577f 100644
--- a/lib/util/debug_s3.c
+++ b/lib/util/debug_s3.c
@@ -30,7 +30,7 @@ bool reopen_logs(void)
 {
        if (lp_loaded()) {
                struct debug_settings settings;
-               debug_set_logfile(lp_logfile());
+               debug_set_logfile(lp_logfile(talloc_tos()));
 
                ZERO_STRUCT(settings);
                settings.max_log_size = lp_max_log_size();
diff --git a/lib/util/modules.c b/lib/util/modules.c
index 93fd79b..23298da 100644
--- a/lib/util/modules.c
+++ b/lib/util/modules.c
@@ -192,6 +192,7 @@ static NTSTATUS do_smb_load_module(const char *subsystem,
        }
 
        if (!init) {
+               TALLOC_FREE(ctx);
                return NT_STATUS_UNSUCCESSFUL;
        }
 
@@ -203,7 +204,7 @@ static NTSTATUS do_smb_load_module(const char *subsystem,
                          module_name, get_friendly_nt_error_msg(status)));
                dlclose(handle);
        }
-
+       TALLOC_FREE(ctx);
        return status;
 }
 
diff --git a/lib/util/talloc_stack.c b/lib/util/talloc_stack.c
index 16e9d74..9c72c80 100644
--- a/lib/util/talloc_stack.c
+++ b/lib/util/talloc_stack.c
@@ -96,6 +96,17 @@ static int talloc_pop(TALLOC_CTX *frame)
                (struct talloc_stackframe *)SMB_THREAD_GET_TLS(global_ts);
        int i;
 
+       /* Catch lazy frame-freeing. */
+       if (ts->talloc_stack[ts->talloc_stacksize-1] != frame) {
+               DEBUG(0, ("Freed frame %s, expected %s.\n",
+                         talloc_get_name(frame),
+                         talloc_get_name(ts->talloc_stack
+                                         [ts->talloc_stacksize-1])));
+#ifdef DEVELOPER
+               smb_panic("Frame not freed in order.");
+#endif
+       }
+
        for (i=ts->talloc_stacksize-1; i>0; i--) {
                if (frame == ts->talloc_stack[i]) {
                        break;
@@ -115,9 +126,10 @@ static int talloc_pop(TALLOC_CTX *frame)
  * not explicitly freed.
  */
 
-static TALLOC_CTX *talloc_stackframe_internal(size_t poolsize)
+static TALLOC_CTX *talloc_stackframe_internal(const char *location,
+                                             size_t poolsize)
 {
-       TALLOC_CTX **tmp, *top, *parent;
+       TALLOC_CTX **tmp, *top;
        struct talloc_stackframe *ts =
                (struct talloc_stackframe *)SMB_THREAD_GET_TLS(global_ts);
 


-- 
Samba Shared Repository

Reply via email to