]> git.ipfire.org Git - thirdparty/samba.git/commitdiff
dbwrap: fix possible memleak and false result check.
authorSwen Schillig <swen@linux.ibm.com>
Mon, 30 Mar 2020 10:54:00 +0000 (12:54 +0200)
committerMartin Schwenke <martins@samba.org>
Thu, 2 Apr 2020 11:26:32 +0000 (11:26 +0000)
A cstatus != 0 or a data.dsize != sizeof(uint32_t)
does not guarantee to have no received data referenced by data.dptr.
Therefore, make sure data.dptr is free'd.
Reusing the same data structure as data input and data output parameter
can lead to wrong results, especially when the output parameters value
is used to detect errors. Create the additional local variable outdata
to prevent this issue.

Signed-off-by: Swen Schillig <swen@linux.ibm.com>
Reviewed-by: Volker Lendecke <vl@samba.org>
Reviewed-by: Martin Schwenke <martin@meltin.net>
Autobuild-User(master): Martin Schwenke <martins@samba.org>
Autobuild-Date(master): Thu Apr  2 11:26:32 UTC 2020 on sn-devel-184

source3/lib/dbwrap/dbwrap_ctdb.c

index 188021ab202b7eeae0713a9ac979632a2363dc3c..4441ffa02855c1cdc22d5e49eb6e7978ffe6d6f2 100644 (file)
@@ -1825,6 +1825,7 @@ struct db_context *db_open_ctdb(TALLOC_CTX *mem_ctx,
        char *db_path;
        struct loadparm_context *lp_ctx;
        TDB_DATA data;
+       TDB_DATA outdata = {0};
        bool persistent = (tdb_flags & TDB_CLEAR_IF_FIRST) == 0;
        int32_t cstatus;
        int ret;
@@ -1897,7 +1898,7 @@ struct db_context *db_open_ctdb(TALLOC_CTX *mem_ctx,
 
        ret = ctdbd_control_local(messaging_ctdb_connection(),
                                  CTDB_CONTROL_DB_OPEN_FLAGS,
-                                 0, 0, data, NULL, &data, &cstatus);
+                                 0, 0, data, NULL, &outdata, &cstatus);
        if (ret != 0) {
                DBG_ERR(" ctdb control for db_open_flags "
                         "failed: %s\n", strerror(ret));
@@ -1905,13 +1906,15 @@ struct db_context *db_open_ctdb(TALLOC_CTX *mem_ctx,
                return NULL;
        }
 
-       if (cstatus != 0 || data.dsize != sizeof(int)) {
+       if (cstatus != 0 || outdata.dsize != sizeof(int)) {
                DBG_ERR("ctdb_control for db_open_flags failed\n");
+               TALLOC_FREE(outdata.dptr);
                TALLOC_FREE(result);
                return NULL;
        }
 
-       tdb_flags = *(int *)data.dptr;
+       tdb_flags = *(int *)outdata.dptr;
+       TALLOC_FREE(outdata.dptr);
 
        if (!result->persistent) {
                ret = ctdb_async_ctx_init(NULL, messaging_tevent_context(msg_ctx));