From: Swen Schillig Date: Mon, 30 Mar 2020 10:54:00 +0000 (+0200) Subject: dbwrap: fix possible memleak and false result check. X-Git-Tag: ldb-2.2.0~1127 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=130c26b43ffbb577438006e4e4acfb0e88199c64;p=thirdparty%2Fsamba.git dbwrap: fix possible memleak and false result check. 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 Reviewed-by: Volker Lendecke Reviewed-by: Martin Schwenke Autobuild-User(master): Martin Schwenke Autobuild-Date(master): Thu Apr 2 11:26:32 UTC 2020 on sn-devel-184 --- diff --git a/source3/lib/dbwrap/dbwrap_ctdb.c b/source3/lib/dbwrap/dbwrap_ctdb.c index 188021ab202..4441ffa0285 100644 --- a/source3/lib/dbwrap/dbwrap_ctdb.c +++ b/source3/lib/dbwrap/dbwrap_ctdb.c @@ -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));