commit 9c3c03f71ce0967207455e886f0eb20f845766bf
parent b39514da3cea55b72c6b3c7ede0859811c53e260
Author: Christian Grothoff <christian@grothoff.org>
Date: Fri, 9 May 2025 17:27:06 +0200
-fix misc. memory leaks
Diffstat:
9 files changed, 85 insertions(+), 43 deletions(-)
diff --git a/src/exchange/taler-exchange-httpd_melt_v27.c b/src/exchange/taler-exchange-httpd_melt_v27.c
@@ -208,7 +208,7 @@ struct MeltContext
* Array @e withdraw.num_r_pubs of indices into @e denoms_h
* of CS denominations.
*/
- uint32_t *cs_indices;
+ uint32_t *cs_indices;
/**
* Total (over all coins) amount (excluding fee) committed for the refresh
@@ -366,6 +366,7 @@ clean_melt_rc (struct TEH_RequestContext *rc)
{
free_refresh (&mc->request.refresh_idem);
}
+ GNUNET_free (mc->request.cs_indices);
GNUNET_free (mc);
}
@@ -1670,7 +1671,6 @@ TEH_handler_melt_v27 (
const json_t *root,
const char *const args[0])
{
-
struct MeltContext *mc = rc->rh_ctx;
(void) args;
diff --git a/src/exchange/taler-exchange-httpd_withdraw.c b/src/exchange/taler-exchange-httpd_withdraw.c
@@ -370,6 +370,8 @@ withdraw_is_idempotent (
enum GNUNET_DB_QueryStatus qs;
uint8_t max_retries = 3;
+ /* We should at most be called once */
+ GNUNET_assert (! wc->request.is_idempotent);
while (0 < max_retries--)
{
qs = TEH_plugin->get_withdraw (
@@ -1159,9 +1161,11 @@ static void
free_db_withdraw_data (struct TALER_EXCHANGEDB_Withdraw *wd)
{
if (NULL != wd->denom_sigs)
+ {
for (unsigned int i = 0; i<wd->num_coins; i++)
TALER_blinded_denom_sig_free (&wd->denom_sigs[i]);
- GNUNET_free (wd->denom_sigs);
+ GNUNET_free (wd->denom_sigs);
+ }
GNUNET_free (wd->denom_serials);
GNUNET_free (wd->cs_r_values);
}
diff --git a/src/exchangedb/pg_get_withdraw.c b/src/exchangedb/pg_get_withdraw.c
@@ -113,7 +113,6 @@ TEH_PG_get_withdraw (
",denom_serials"
" FROM withdraw"
" WHERE planchets_h=$1;");
-
ret = GNUNET_PQ_eval_prepared_singleton_select (pg->conn,
"get_withdraw",
params,
@@ -131,18 +130,21 @@ TEH_PG_get_withdraw (
no_max_age ? "true" : "false",
no_noreveal_index ? "true" : "false",
no_selected_h ? "true" : "false");
+ GNUNET_PQ_cleanup_result (rs);
return GNUNET_DB_STATUS_HARD_ERROR;
}
if (no_blinding_seed != no_cs_r_values)
{
GNUNET_break (0);
+ GNUNET_PQ_cleanup_result (rs);
return GNUNET_DB_STATUS_HARD_ERROR;
}
if (no_cs_r_choices != no_cs_r_values)
{
GNUNET_break (0);
+ GNUNET_PQ_cleanup_result (rs);
return GNUNET_DB_STATUS_HARD_ERROR;
}
@@ -154,6 +156,7 @@ TEH_PG_get_withdraw (
"num_coins=%ld, num_sigs=%ld\n",
wd->num_coins,
num_sigs);
+ GNUNET_PQ_cleanup_result (rs);
return GNUNET_DB_STATUS_HARD_ERROR;
}
@@ -164,6 +167,5 @@ TEH_PG_get_withdraw (
wd->num_cs_r_values = 0;
wd->cs_r_choices = 0;
}
-
return ret;
}
diff --git a/src/include/taler_exchange_service.h b/src/include/taler_exchange_service.h
@@ -3384,11 +3384,18 @@ struct TALER_EXCHANGE_RevealMeltResponse
};
+/**
+ * Function called with the result of a reveal-melt operation.
+ *
+ * @param cls closure
+ * @param awr exchange response details
+ */
typedef void
(*TALER_EXCHANGE_RevealMeltCallback)(
void *cls,
const struct TALER_EXCHANGE_RevealMeltResponse *awr);
+
/**
* The tuple of #TALER_CNC_KAPPA - 1 signatures, that are disclosed
* during the /reveal-melt step. From these signatures, signed with
@@ -3397,6 +3404,9 @@ typedef void
*/
struct TALER_RevealPrivateRefreshNonceSignaturesP
{
+ /**
+ * Array of disclosed signatures.
+ */
struct TALER_PrivateRefreshNonceSignatureP tuple[TALER_CNC_KAPPA - 1];
};
@@ -3469,7 +3479,9 @@ struct TALER_EXCHANGE_RevealMeltInput
*/
const struct TALER_RefreshMasterSecretP *rms;
- /* The input data from the prior call to /melt */
+ /**
+ * The input data from the prior call to /melt
+ */
const struct TALER_EXCHANGE_MeltInput *melt_input;
/**
diff --git a/src/lib/exchange_api_reveal_melt.c b/src/lib/exchange_api_reveal_melt.c
@@ -183,7 +183,12 @@ reveal_melt_ok (
mrh->callback = NULL;
/* Free resources */
for (size_t i = 0; i < mrh->num_expected_coins; i++)
+ {
+ struct TALER_EXCHANGE_RevealedCoinInfo *rci = &coins[i];
+
+ TALER_denom_sig_free (&rci->sig);
TALER_blinded_denom_sig_free (&blind_sigs[i]);
+ }
}
return GNUNET_OK;
@@ -321,7 +326,8 @@ perform_protocol (
json_t *j_age = GNUNET_JSON_PACK (
TALER_JSON_pack_age_commitment (
"age_commitment",
- &mrh->reveal_input->melt_input->melt_age_commitment_proof->commitment));
+ &mrh->reveal_input->melt_input->melt_age_commitment_proof->commitment)
+ );
GNUNET_assert (NULL != j_age);
GNUNET_assert (0 ==
json_object_update_new (j_request_body,
@@ -390,9 +396,8 @@ TALER_EXCHANGE_reveal_melt (
reveal_melt_input->blinding_seed,
reveal_melt_input->blinding_values,
&mrh->md);
-
- perform_protocol (curl_ctx, mrh);
-
+ perform_protocol (curl_ctx,
+ mrh);
return mrh;
}
@@ -407,9 +412,7 @@ TALER_EXCHANGE_reveal_melt_cancel (
mrh->job = NULL;
}
TALER_curl_easy_post_finished (&mrh->post_ctx);
-
- if (NULL != mrh->request_url)
- GNUNET_free (mrh->request_url);
-
+ TALER_EXCHANGE_free_melt_data_v27 (&mrh->md);
+ GNUNET_free (mrh->request_url);
GNUNET_free (mrh);
}
diff --git a/src/lib/exchange_api_withdraw.c b/src/lib/exchange_api_withdraw.c
@@ -19,7 +19,11 @@
* @brief Implementation of /withdraw requests
* @author Özgür Kesim
*/
-
+/**
+ * We want the "dangerous" exports here as these are OUR exports
+ * and we want to check that the prototypes match.
+ */
+#define TALER_TESTING_EXPORTS_DANGEROUS 1
#include "platform.h"
#include <gnunet/gnunet_common.h>
#include <jansson.h>
@@ -968,8 +972,6 @@ copy_results (
struct TALER_EXCHANGE_WithdrawResponse resp = {
.hr = wbr->hr,
};
- struct TALER_EXCHANGE_WithdrawCoinPrivateDetails
- details[GNUNET_NZL (wh->num_coins)];
wh->withdraw_blinded_handle = NULL;
@@ -982,17 +984,18 @@ copy_results (
{
case MHD_HTTP_OK:
{
+ struct TALER_EXCHANGE_WithdrawCoinPrivateDetails
+ details[GNUNET_NZL (wh->num_coins)];
+ bool ok = true;
GNUNET_assert (wh->num_coins == wbr->details.ok.num_sigs);
-
- resp.details.ok.num_sigs = wbr->details.ok.num_sigs;
- resp.details.ok.coin_details = details;
- resp.details.ok.planchets_h = wbr->details.ok.planchets_h;
memset (details,
0,
sizeof(details));
-
- for (size_t n = 0; n< wh->num_coins; n++)
+ resp.details.ok.num_sigs = wbr->details.ok.num_sigs;
+ resp.details.ok.coin_details = details;
+ resp.details.ok.planchets_h = wbr->details.ok.planchets_h;
+ for (size_t n = 0; n<wh->num_coins; n++)
{
const struct TALER_BlindedDenominationSignature *bsig =
&wbr->details.ok.blinded_denom_sigs[n];
@@ -1019,13 +1022,26 @@ copy_results (
resp.hr.http_status = 0;
resp.hr.ec = TALER_EC_EXCHANGE_WITHDRAW_UNBLIND_FAILURE;
GNUNET_break_op (0);
+ ok = false;
break;
}
coin->denom_sig = fresh_coin.sig;
}
+ if (ok)
+ {
+ wh->callback (
+ wh->callback_cls,
+ &resp);
+ wh->callback = NULL;
+ }
+ for (size_t n = 0; n<wh->num_coins; n++)
+ {
+ struct TALER_EXCHANGE_WithdrawCoinPrivateDetails *coin = &details[n];
+
+ TALER_denom_sig_free (&coin->denom_sig);
+ }
break;
}
-
case MHD_HTTP_CREATED:
resp.details.created = wbr->details.created;
break;
@@ -1039,12 +1055,13 @@ copy_results (
/* nothing to do here, .hr.ec and .hr.hint are all set already from previous response */
break;
}
-
- wh->callback (
- wh->callback_cls,
- &resp);
-
- wh->callback = NULL;
+ if (NULL != wh->callback)
+ {
+ wh->callback (
+ wh->callback_cls,
+ &resp);
+ wh->callback = NULL;
+ }
TALER_EXCHANGE_withdraw_cancel (wh);
}
@@ -1199,11 +1216,7 @@ blinding_prepare_done (
const struct TALER_EXCHANGE_BlindingPrepareResponse *bpr)
{
struct BlindingPrepareClosure *bpcls = cls;
- struct TALER_EXCHANGE_WithdrawHandle *wh;
-
- GNUNET_assert (NULL != bpcls);
- wh = bpcls->withdraw_handle;
- GNUNET_assert (NULL != wh);
+ struct TALER_EXCHANGE_WithdrawHandle *wh = bpcls->withdraw_handle;
wh->blinding_prepare_handle = NULL;
switch (bpr->hr.http_status)
@@ -1212,9 +1225,9 @@ blinding_prepare_done (
{
bool success = false;
size_t num = bpr->details.ok.num_blinding_values;
+
GNUNET_assert (0 != num);
GNUNET_assert (num == bpcls->num_nonces);
-
for (size_t i = 0; i < bpcls->num_prepare_coins; i++)
{
struct TALER_PlanchetDetail *planchet = bpcls->coins[i].planchet;
@@ -1266,14 +1279,11 @@ blinding_prepare_done (
success = true;
}
- GNUNET_free (bpcls->coins);
- GNUNET_free (bpcls->nonces);
-
/* /blinding-prepare is done, we can now perform the
* actual withdraw operation */
if (success)
call_withdraw_blinded (wh);
- return;
+ goto cleanup;
}
default:
{
@@ -1291,6 +1301,10 @@ blinding_prepare_done (
}
}
TALER_EXCHANGE_withdraw_cancel (wh);
+cleanup:
+ GNUNET_free (bpcls->coins);
+ GNUNET_free (bpcls->nonces);
+ GNUNET_free (bpcls);
}
diff --git a/src/testing/testing_api_cmd_coin_history.c b/src/testing/testing_api_cmd_coin_history.c
@@ -237,6 +237,10 @@ analyze_command (void *cls,
struct TALER_TESTING_Command *cur;
struct TALER_TESTING_Command *bcmd;
+ GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+ "Checking `%s' for history of coin `%s'\n",
+ cmd->label,
+ TALER_B2S (coin_pub));
cur = TALER_TESTING_cmd_batch_get_current (cmd);
if (GNUNET_OK !=
TALER_TESTING_get_trait_batch_cmds (cmd,
@@ -282,15 +286,15 @@ analyze_command (void *cls,
j);
break; /* command does nothing for coins */
}
-
if (0 !=
GNUNET_memcmp (rp,
coin_pub))
{
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Command `%s#%u' is about another coin\n",
+ "Command `%s#%u' is about another coin %s\n",
cmd->label,
- j);
+ j,
+ TALER_B2S (rp));
continue; /* command affects some _other_ coin */
}
if (GNUNET_OK !=
diff --git a/src/testing/testing_api_cmd_get_auditor.c b/src/testing/testing_api_cmd_get_auditor.c
@@ -133,6 +133,7 @@ get_auditor_priv_file (
GNUNET_break (GNUNET_OK ==
GNUNET_CONFIGURATION_load (acfg,
dfn));
+ GNUNET_free (dfn);
if (GNUNET_OK !=
GNUNET_CONFIGURATION_get_value_filename (acfg,
"auditor",
diff --git a/src/testing/testing_api_cmd_get_exchange.c b/src/testing/testing_api_cmd_get_exchange.c
@@ -99,6 +99,8 @@ cert_cb (void *cls,
struct TALER_TESTING_Interpreter *is = ges->is;
ges->exchange = NULL;
+ if (NULL != ges->keys)
+ TALER_EXCHANGE_keys_decref (ges->keys);
ges->keys = keys;
switch (hr->http_status)
{