exchange

Base system with REST service to issue digital coins, run by the payment service provider
Log | Files | Refs | Submodules | README | LICENSE

commit bbe66ad4cf81749cba522d72e0490751a05d97dd
parent 37000db5b0d03f1165b40c6d46f3f4ebe1fd4f2f
Author: Christian Grothoff <christian@grothoff.org>
Date:   Fri,  9 May 2025 20:00:11 +0200

misc leak fixes

Diffstat:
Msrc/exchange/taler-exchange-httpd_melt_v27.c | 5+++--
Msrc/exchangedb/pg_get_refresh.c | 27+++++++++++----------------
Msrc/exchangedb/pg_get_reserve_history.c | 15+++++++++++++--
Msrc/exchangedb/pg_get_withdraw.c | 56++++++++++++++++++++++++++++++++++++++++++--------------
Msrc/exchangedb/pg_lookup_records_by_table.c | 6++----
Msrc/exchangedb/pg_select_withdrawals_above_serial_id.c | 11++++++-----
Msrc/pq/pq_result_helper.c | 15+++++++--------
7 files changed, 84 insertions(+), 51 deletions(-)

diff --git a/src/exchange/taler-exchange-httpd_melt_v27.c b/src/exchange/taler-exchange-httpd_melt_v27.c @@ -332,9 +332,11 @@ static void free_refresh (struct TALER_EXCHANGEDB_Refresh_v27 *re) { if (NULL != re->denom_sigs) + { for (size_t i = 0; i<re->num_coins; i++) TALER_blinded_denom_sig_free (&re->denom_sigs[i]); - GNUNET_free (re->denom_sigs); + GNUNET_free (re->denom_sigs); + } GNUNET_free (re->cs_r_values); GNUNET_free (re->denom_serials); GNUNET_free (re->denom_pub_hashes); @@ -836,7 +838,6 @@ static void phase_check_coin_signature ( struct MeltContext *mc) { - /* We can now compute the commitment */ { struct TALER_KappaHashBlindedPlanchetsP k_bps_h = {0}; diff --git a/src/exchangedb/pg_get_refresh.c b/src/exchangedb/pg_get_refresh.c @@ -32,17 +32,16 @@ TEH_PG_get_refresh (void *cls, struct TALER_EXCHANGEDB_Refresh_v27 *refresh) { struct PostgresClosure *pg = cls; - bool no_cs_r_values; - bool no_cs_r_choices; - size_t num_denom_sigs; - struct TALER_BlindedDenominationSignature *denom_sigs; - struct GNUNET_CRYPTO_CSPublicRPairP *cs_r_values; - uint64_t *denom_serials; - struct GNUNET_PQ_QueryParam params[] = { GNUNET_PQ_query_param_auto_from_type (rc), GNUNET_PQ_query_param_end }; + bool no_cs_r_values; + bool no_cs_r_choices; + size_t num_denom_sigs; + struct TALER_BlindedDenominationSignature *denom_sigs = NULL; + struct GNUNET_CRYPTO_CSPublicRPairP *cs_r_values = NULL; + uint64_t *denom_serials = NULL; struct GNUNET_PQ_ResultSpec rs[] = { TALER_PQ_RESULT_SPEC_AMOUNT ("amount_with_fee", &refresh->amount_with_fee), @@ -91,9 +90,6 @@ TEH_PG_get_refresh (void *cls, memset (&refresh->coin.denom_sig, 0, sizeof (refresh->coin.denom_sig)); - - /* Used in #postgres_get_refresh() to fetch - high-level information about a refresh operation */ PREPARE (pg, "get_refresh", "SELECT" @@ -123,11 +119,14 @@ TEH_PG_get_refresh (void *cls, if (0 > qs) { GNUNET_break (0); + GNUNET_PQ_cleanup_result (rs); return qs; } - if (qs == GNUNET_DB_STATUS_SUCCESS_NO_RESULTS) + if (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS == qs) + { + GNUNET_PQ_cleanup_result (rs); return qs; - + } if (refresh->num_coins != num_denom_sigs) { GNUNET_break (0); @@ -160,9 +159,7 @@ TEH_PG_get_refresh (void *cls, memset (&refresh->coin.h_age_commitment, 0, sizeof(refresh->coin.h_age_commitment)); - refresh->rc = *rc; - /* move the result arrays */ refresh->denom_sigs = denom_sigs; refresh->denom_serials = denom_serials; @@ -170,8 +167,6 @@ TEH_PG_get_refresh (void *cls, denom_sigs = NULL; denom_serials = NULL; cs_r_values = NULL; - GNUNET_PQ_cleanup_result (rs); - return qs; } diff --git a/src/exchangedb/pg_get_reserve_history.c b/src/exchangedb/pg_get_reserve_history.c @@ -192,6 +192,8 @@ add_withdraw (void *cls, bool no_selected_h; size_t num_denom_hs; size_t num_denom_serials; + uint64_t *my_denom_serials = NULL; + struct TALER_DenominationHashP *my_denom_pub_hashes = NULL; struct GNUNET_PQ_ResultSpec rs[] = { GNUNET_PQ_result_spec_auto_from_type ("planchets_h", &wd->planchets_h), @@ -218,11 +220,11 @@ add_withdraw (void *cls, TALER_PQ_result_spec_array_denom_hash (pg->conn, "denom_pub_hashes", &num_denom_hs, - &wd->denom_pub_hashes), + &my_denom_pub_hashes), GNUNET_PQ_result_spec_array_uint64 (pg->conn, "denom_serials", &num_denom_serials, - &wd->denom_serials), + &my_denom_serials), GNUNET_PQ_result_spec_end }; @@ -234,6 +236,7 @@ add_withdraw (void *cls, GNUNET_break (0); GNUNET_free (wd); rhc->failed = true; + GNUNET_PQ_cleanup_result (rs); return; } @@ -242,6 +245,7 @@ add_withdraw (void *cls, GNUNET_break (0); GNUNET_free (wd); rhc->failed = true; + GNUNET_PQ_cleanup_result (rs); return; } @@ -251,11 +255,18 @@ add_withdraw (void *cls, GNUNET_break (0); GNUNET_free (wd); rhc->failed = true; + GNUNET_PQ_cleanup_result (rs); return; } wd->age_proof_required = ! no_max_age; wd->num_coins = num_denom_serials; wd->reserve_pub = *rhc->reserve_pub; + wd->denom_serials = my_denom_serials; + wd->denom_pub_hashes = my_denom_pub_hashes; + /* prevent cleanup from destroying our actual result */ + my_denom_serials = NULL; + my_denom_pub_hashes = NULL; + GNUNET_PQ_cleanup_result (rs); } tail = append_rh (rhc); diff --git a/src/exchangedb/pg_get_withdraw.c b/src/exchangedb/pg_get_withdraw.c @@ -1,6 +1,6 @@ /* This file is part of TALER - Copyright (C) 2023 Taler Systems SA + Copyright (C) 2023, 2025 Taler Systems SA TALER is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -34,17 +34,23 @@ TEH_PG_get_withdraw ( { enum GNUNET_DB_QueryStatus ret; struct PostgresClosure *pg = cls; - size_t num_sigs; + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_auto_from_type (wch), + GNUNET_PQ_query_param_end + }; + struct TALER_BlindedDenominationSignature *my_denom_sigs = NULL; + uint64_t *my_denom_serials = NULL; + struct GNUNET_CRYPTO_CSPublicRPairP *my_cs_r_values = NULL; + size_t num_sigs = 0; + size_t num_coins = 0; + size_t num_cs_r_values = 0; bool no_noreveal_index; bool no_max_age; bool no_selected_h; bool no_blinding_seed; bool no_cs_r_values; bool no_cs_r_choices; - struct GNUNET_PQ_QueryParam params[] = { - GNUNET_PQ_query_param_auto_from_type (wch), - GNUNET_PQ_query_param_end - }; + struct GNUNET_PQ_ResultSpec rs[] = { GNUNET_PQ_result_spec_auto_from_type ("planchets_h", &wd->planchets_h), @@ -75,8 +81,8 @@ TEH_PG_get_withdraw ( TALER_PQ_result_spec_array_cs_r_pub ( pg->conn, "cs_r_values", - &wd->num_cs_r_values, - &wd->cs_r_values), + &num_cs_r_values, + &my_cs_r_values), &no_cs_r_values), GNUNET_PQ_result_spec_allow_null ( GNUNET_PQ_result_spec_uint64 ("cs_r_choices", @@ -86,12 +92,12 @@ TEH_PG_get_withdraw ( pg->conn, "denom_sigs", &num_sigs, - &wd->denom_sigs), + &my_denom_sigs), GNUNET_PQ_result_spec_array_uint64 ( pg->conn, "denom_serials", - &wd->num_coins, - &wd->denom_serials), + &num_coins, + &my_denom_serials), GNUNET_PQ_result_spec_end }; @@ -117,8 +123,17 @@ TEH_PG_get_withdraw ( "get_withdraw", params, rs); - if (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT != ret) + if (0 > ret) + { + GNUNET_break (0); + GNUNET_PQ_cleanup_result (rs); + return ret; + } + if (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS == ret) + { + GNUNET_PQ_cleanup_result (rs); return ret; + } if ((no_max_age != no_noreveal_index) || (no_max_age != no_selected_h)) @@ -145,13 +160,13 @@ TEH_PG_get_withdraw ( GNUNET_PQ_cleanup_result (rs); return GNUNET_DB_STATUS_HARD_ERROR; } - if (wd->num_coins != num_sigs) + if (num_coins != num_sigs) { GNUNET_break (0); GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "got inconsistent number of entries in withdraw from DB: " "num_coins=%ld, num_sigs=%ld\n", - wd->num_coins, + num_coins, num_sigs); GNUNET_PQ_cleanup_result (rs); return GNUNET_DB_STATUS_HARD_ERROR; @@ -163,5 +178,18 @@ TEH_PG_get_withdraw ( wd->num_cs_r_values = 0; wd->cs_r_choices = 0; } + wd->denom_sigs = my_denom_sigs; + wd->num_coins = num_coins; + wd->denom_serials = my_denom_serials; + wd->cs_r_values = my_cs_r_values; + wd->num_cs_r_values = num_cs_r_values; + /* ensure cleanup_result does not trash data we care about */ + my_denom_sigs = NULL; + my_denom_serials = NULL; + my_cs_r_values = NULL; + num_sigs = 0; + num_coins = 0; + num_cs_r_values = 0; + GNUNET_PQ_cleanup_result (rs); return ret; } diff --git a/src/exchangedb/pg_lookup_records_by_table.c b/src/exchangedb/pg_lookup_records_by_table.c @@ -1000,6 +1000,7 @@ lrbt_cb_table_refresh (void *cls, { GNUNET_break (0); ctx->error = true; + GNUNET_PQ_cleanup_result (rs); return; } ctx->cb (ctx->cb_cls, @@ -2644,9 +2645,9 @@ lrbt_cb_table_withdraw (void *cls, { GNUNET_break (0); ctx->error = true; + GNUNET_PQ_cleanup_result (rs); return; } - if ((num_h_coin_evs != td.details.withdraw.num_coins) || (num_h_coin_evs != num_sigs)) { @@ -2655,7 +2656,6 @@ lrbt_cb_table_withdraw (void *cls, GNUNET_PQ_cleanup_result (rs); return; } - if (no_max_age != no_noreveal_index) { GNUNET_break (0); @@ -2663,7 +2663,6 @@ lrbt_cb_table_withdraw (void *cls, GNUNET_PQ_cleanup_result (rs); return; } - if (no_cs_r_pubs != td.details.withdraw.no_blinding_seed) { GNUNET_break (0); @@ -2671,7 +2670,6 @@ lrbt_cb_table_withdraw (void *cls, GNUNET_PQ_cleanup_result (rs); return; } - td.details.withdraw.age_proof_required = ! no_max_age; ctx->cb (ctx->cb_cls, &td); diff --git a/src/exchangedb/pg_select_withdrawals_above_serial_id.c b/src/exchangedb/pg_select_withdrawals_above_serial_id.c @@ -73,9 +73,9 @@ withdraw_serial_helper_cb (void *cls, for (unsigned int i = 0; i<num_results; i++) { size_t num_evs; - struct TALER_BlindedCoinHashP *h_blind_evs; + struct TALER_BlindedCoinHashP *h_blind_evs = NULL; size_t num_denom_serials; - uint64_t *denom_serials; + uint64_t *denom_serials = NULL; struct TALER_ReservePublicKeyP reserve_pub; struct TALER_ReserveSignatureP reserve_sig; struct GNUNET_TIME_Timestamp execution_date; @@ -132,20 +132,21 @@ withdraw_serial_helper_cb (void *cls, { GNUNET_break (0); rosc->status = GNUNET_SYSERR; + GNUNET_PQ_cleanup_result (rs); return; } - if (num_denom_serials != num_evs) { GNUNET_break (0); rosc->status = GNUNET_SYSERR; + GNUNET_PQ_cleanup_result (rs); return; } - if (no_max_age != no_noreveal_index) { GNUNET_break (0); rosc->status = GNUNET_SYSERR; + GNUNET_PQ_cleanup_result (rs); return; } @@ -154,9 +155,9 @@ withdraw_serial_helper_cb (void *cls, { GNUNET_break (0); rosc->status = GNUNET_SYSERR; + GNUNET_PQ_cleanup_result (rs); return; } - ret = rosc->cb (rosc->cb_cls, rowid, num_evs, diff --git a/src/pq/pq_result_helper.c b/src/pq/pq_result_helper.c @@ -1453,8 +1453,7 @@ array_cleanup (void *cls, for (size_t i = 0; i < *info->num; i++) GNUNET_free (denom_sigs[i].blinded_sig); } - - GNUNET_free (cls); + GNUNET_free (info); GNUNET_free (*dst); *dst = NULL; } @@ -1478,7 +1477,7 @@ TALER_PQ_result_spec_array_blinded_denom_sig ( { struct GNUNET_PQ_ResultSpec res = { .conv = extract_array_generic, - .cleaner = array_cleanup, + .cleaner = &array_cleanup, .dst = (void *) denom_sigs, .fname = name, .cls = info @@ -1507,7 +1506,7 @@ TALER_PQ_result_spec_array_blinded_coin_hash ( { struct GNUNET_PQ_ResultSpec res = { .conv = extract_array_generic, - .cleaner = array_cleanup, + .cleaner = &array_cleanup, .dst = (void *) h_coin_evs, .fname = name, .cls = info @@ -1536,7 +1535,7 @@ TALER_PQ_result_spec_array_denom_hash ( { struct GNUNET_PQ_ResultSpec res = { .conv = extract_array_generic, - .cleaner = array_cleanup, + .cleaner = &array_cleanup, .dst = (void *) denom_hs, .fname = name, .cls = info @@ -1575,7 +1574,7 @@ TALER_PQ_result_spec_array_amount ( { struct GNUNET_PQ_ResultSpec res = { .conv = extract_array_generic, - .cleaner = array_cleanup, + .cleaner = &array_cleanup, .dst = (void *) amounts, .fname = name, .cls = info, @@ -1605,7 +1604,7 @@ TALER_PQ_result_spec_array_hash_code ( { struct GNUNET_PQ_ResultSpec res = { .conv = extract_array_generic, - .cleaner = array_cleanup, + .cleaner = &array_cleanup, .dst = (void *) hashes, .fname = name, .cls = info, @@ -1634,7 +1633,7 @@ TALER_PQ_result_spec_array_cs_r_pub ( { struct GNUNET_PQ_ResultSpec res = { .conv = extract_array_generic, - .cleaner = array_cleanup, + .cleaner = &array_cleanup, .dst = (void *) cs_r_pubs, .fname = name, .cls = info