pytalloc: ensure talloc_ctx is directly after PyObject_HEAD
authorAndrew Tridgell <tridge@samba.org>
Tue, 20 Apr 2010 05:33:00 +0000 (15:33 +1000)
committerAndrew Tridgell <tridge@samba.org>
Tue, 20 Apr 2010 05:50:27 +0000 (15:50 +1000)
the talloc python interface for tp_alloc and tp_dealloc relies on a
cast to a py_talloc_Object to find the talloc_ctx (see
py_talloc_dealloc). This means we rely on the talloc_ctx for the
object being directly after the PyObject_HEAD

This fixes the talloc free with references bug in samba_dnsupdate

The actual problem was the tp_alloc() call in
PyCredentialCacheContainer_from_ccache_container() which used a cast
from a py_talloc_Object to a PyCredentialCacheContainerObject. That
case effectively changed the parent/child relationship between the
talloc_ctx and the ccc ptr.

This patch changes all the structures that follow this pattern to put
the TALLOC_CTX directly after the PyObject_HEAD, to ensure that if
anyone else decides to do a dangerous cast like this that it won't
cause the same sort of subtle breakage.

Pair-Programmed-With: Rusty Russell <rusty@samba.org>

source4/auth/credentials/pycredentials.h
source4/lib/ldb/pyldb.h
source4/lib/messaging/pymessaging.c
source4/libnet/py_net.c

index 6d03ca158b03f71f8764c125f3349d4d990ab007..09deb05e58eb59f44c3c8c78c64bbaf6a658ad85 100644 (file)
@@ -26,8 +26,8 @@ PyAPI_DATA(PyTypeObject) PyCredentials;
 PyAPI_DATA(PyTypeObject) PyCredentialCacheContainer;
 typedef struct {
        PyObject_HEAD
-       struct ccache_container *ccc;
        TALLOC_CTX *mem_ctx;
+       struct ccache_container *ccc;
 } PyCredentialCacheContainerObject;
 #define PyCredentials_Check(py_obj) PyObject_TypeCheck(py_obj, &PyCredentials)
 #define PyCredentials_AsCliCredentials(py_obj) py_talloc_get_type(py_obj, struct cli_credentials)
index 289159c5b3f49f4bd50d90fe2279b69ffcf7d4ee..545011e4c9c55f21328704a2f2c464ea1c94a2ff 100644 (file)
@@ -31,8 +31,8 @@
 
 typedef struct {
        PyObject_HEAD
-       struct ldb_context *ldb_ctx;
        TALLOC_CTX *mem_ctx;
+       struct ldb_context *ldb_ctx;
 } PyLdbObject;
 
 #define PyLdb_AsLdbContext(pyobj) ((PyLdbObject *)pyobj)->ldb_ctx
@@ -40,8 +40,8 @@ typedef struct {
 
 typedef struct {
        PyObject_HEAD
-       struct ldb_dn *dn;
        TALLOC_CTX *mem_ctx;
+       struct ldb_dn *dn;
 } PyLdbDnObject;
 
 PyObject *PyLdbDn_FromDn(struct ldb_dn *);
@@ -51,16 +51,16 @@ bool PyObject_AsDn(TALLOC_CTX *mem_ctx, PyObject *object, struct ldb_context *ld
 
 typedef struct {
        PyObject_HEAD
-       struct ldb_message *msg;
        TALLOC_CTX *mem_ctx;
+       struct ldb_message *msg;
 } PyLdbMessageObject;
 #define PyLdbMessage_Check(ob) PyObject_TypeCheck(ob, &PyLdbMessage)
 #define PyLdbMessage_AsMessage(pyobj) ((PyLdbMessageObject *)pyobj)->msg
 
 typedef struct {
        PyObject_HEAD
-       struct ldb_module *mod;
        TALLOC_CTX *mem_ctx;
+       struct ldb_module *mod;
 } PyLdbModuleObject;
 PyObject *PyLdbMessage_FromMessage(struct ldb_message *message);
 PyObject *PyLdbModule_FromModule(struct ldb_module *mod);
@@ -68,8 +68,8 @@ PyObject *PyLdbModule_FromModule(struct ldb_module *mod);
 
 typedef struct {
        PyObject_HEAD   
-       struct ldb_message_element *el;
        TALLOC_CTX *mem_ctx;
+       struct ldb_message_element *el;
 } PyLdbMessageElementObject;
 struct ldb_message_element *PyObject_AsMessageElement(TALLOC_CTX *mem_ctx, PyObject *obj, int flags, const char *name);
 PyObject *PyLdbMessageElement_FromMessageElement(struct ldb_message_element *, TALLOC_CTX *mem_ctx);
@@ -78,8 +78,8 @@ PyObject *PyLdbMessageElement_FromMessageElement(struct ldb_message_element *, T
 
 typedef struct {
        PyObject_HEAD
-       struct ldb_parse_tree *tree;
        TALLOC_CTX *mem_ctx;
+       struct ldb_parse_tree *tree;
 } PyLdbTreeObject;
 PyObject *PyLdbTree_FromTree(struct ldb_parse_tree *);
 #define PyLdbTree_AsTree(pyobj) ((PyLdbTreeObject *)pyobj)->tree
index 35e009385f8b28a30df265882bc599797c722df7..cea3accce055e1a3c455377b93181c94821cc61b 100644 (file)
@@ -303,10 +303,10 @@ PyTypeObject messaging_Type = {
 */
 typedef struct {
        PyObject_HEAD
+       TALLOC_CTX *mem_ctx;
        const char *server_name;
        struct server_id *dest_ids;
        struct messaging_context *msg_ctx;
-       TALLOC_CTX *mem_ctx;
 } irpc_ClientConnectionObject;
 
 /*
@@ -382,10 +382,10 @@ PyObject *py_irpc_connect(PyTypeObject *self, PyObject *args, PyObject *kwargs)
 
 typedef struct {
        PyObject_HEAD
+       TALLOC_CTX *mem_ctx;
        struct irpc_request **reqs;
        int count;
        int current;
-       TALLOC_CTX *mem_ctx;
        py_data_unpack_fn unpack_fn;
 } irpc_ResultObject;
 
index 6bd4c0ca847660297ff35b4cfe1c05564bae2af9..cdf8aebcb3f012ce42fa92b590ca2170c0857e80 100644 (file)
@@ -29,8 +29,8 @@
 
 typedef struct {
        PyObject_HEAD
-       struct libnet_context *libnet_ctx;
        TALLOC_CTX *mem_ctx;
+       struct libnet_context *libnet_ctx;
        struct tevent_context *ev;
 } py_net_Object;