From 766fb6e2821dc84ccfe290e8906f12001e34043b Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Sat, 11 Jun 2016 18:22:33 +0200 Subject: [PATCH] fixing more leaks --- src/exchange/taler-exchange-aggregator.c | 8 +-- src/exchange/taler-exchange-httpd_db.c | 50 ++++++++++++------- src/exchange/taler-exchange-httpd_responses.c | 3 +- src/exchange/taler-exchange-httpd_wire.c | 23 ++++++++- src/exchangedb/plugin_exchangedb_common.c | 12 +++++ src/exchangedb/plugin_exchangedb_postgres.c | 26 +++++++--- src/exchangedb/test_exchangedb.c | 5 ++ src/pq/test_pq.c | 4 +- src/wire/plugin_wire_test.c | 44 ++++++++-------- 9 files changed, 121 insertions(+), 54 deletions(-) diff --git a/src/exchange/taler-exchange-aggregator.c b/src/exchange/taler-exchange-aggregator.c index e3262962c..d7b216e5f 100644 --- a/src/exchange/taler-exchange-aggregator.c +++ b/src/exchange/taler-exchange-aggregator.c @@ -432,12 +432,11 @@ deposit_cb (void *cls, return GNUNET_SYSERR; } au->row_id = row_id; - au->wire = (json_t *) wire; + au->wire = json_incref ((json_t *) wire); au->execution_time = GNUNET_TIME_absolute_get (); (void) GNUNET_TIME_round_abs (&au->execution_time); TALER_JSON_hash (au->wire, &au->h_wire); - json_incref (au->wire); GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_NONCE, &au->wtid, sizeof (au->wtid)); @@ -774,8 +773,8 @@ run_aggregation (void *cls) GNUNET_free_non_null (au->additional_rows); if (NULL != au->wire) json_decref (au->wire); - au = NULL; GNUNET_free (au); + au = NULL; /* start again */ task = GNUNET_SCHEDULER_add_now (&run_aggregation, NULL); @@ -810,7 +809,10 @@ prepare_cb (void *cls, struct TALER_EXCHANGEDB_Session *session = au->session; if (NULL != au->wire) + { json_decref (au->wire); + au->wire = NULL; + } GNUNET_free_non_null (au->additional_rows); if (NULL == buf) { diff --git a/src/exchange/taler-exchange-httpd_db.c b/src/exchange/taler-exchange-httpd_db.c index 4cd3df490..1ba64b2a2 100644 --- a/src/exchange/taler-exchange-httpd_db.c +++ b/src/exchange/taler-exchange-httpd_db.c @@ -1185,6 +1185,7 @@ check_commitment (struct MHD_Connection *connection, struct TALER_TransferPublicKeyP transfer_pub_check; struct TALER_EXCHANGEDB_RefreshCommitCoin *commit_coins; unsigned int j; + int ret; if (GNUNET_OK != TMH_plugin->get_refresh_commit_link (TMH_plugin->cls, @@ -1271,10 +1272,10 @@ check_commitment (struct MHD_Connection *connection, { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Blind failed (bad denomination key!?)\n"); - GNUNET_free (commit_coins); - return (MHD_YES == TMH_RESPONSE_reply_internal_error (connection, + ret = (MHD_YES == TMH_RESPONSE_reply_internal_error (connection, "Blinding error")) ? GNUNET_NO : GNUNET_SYSERR; + goto cleanup; } if ( (buf_len != commit_coins[j].coin_ev_size) || @@ -1286,20 +1287,25 @@ check_commitment (struct MHD_Connection *connection, "blind envelope does not match for k=%u, old=%d\n", off, (int) j); - GNUNET_free (commit_coins); - return send_melt_commitment_error (connection, - session, - session_hash, - melt, - off, - j, - "envelope"); + GNUNET_free (buf); + ret = send_melt_commitment_error (connection, + session, + session_hash, + melt, + off, + j, + "envelope"); + goto cleanup; } GNUNET_free (buf); } - GNUNET_free (commit_coins); + ret = GNUNET_OK; - return GNUNET_OK; + cleanup: + for (j = 0; j < num_newcoins; j++) + GNUNET_free (commit_coins[j].coin_ev); + GNUNET_free (commit_coins); + return ret; } @@ -1390,6 +1396,7 @@ execute_refresh_reveal_transaction (struct MHD_Connection *connection, { unsigned int j; struct TMH_KS_StateHandle *key_state; + int ret; START_TRANSACTION (session, connection); if (GNUNET_OK != @@ -1416,15 +1423,17 @@ execute_refresh_reveal_transaction (struct MHD_Connection *connection, j); if (NULL == ev_sigs[j].rsa_signature) { - TMH_KS_release (key_state); - return TMH_RESPONSE_reply_internal_db_error (connection); + ret = TMH_RESPONSE_reply_internal_db_error (connection); + goto cleanup; } } - TMH_KS_release (key_state); COMMIT_TRANSACTION (session, connection); - return TMH_RESPONSE_reply_refresh_reveal_success (connection, - refresh_session->num_newcoins, - ev_sigs); + ret = TMH_RESPONSE_reply_refresh_reveal_success (connection, + refresh_session->num_newcoins, + ev_sigs); + cleanup: + TMH_KS_release (key_state); + return ret; } @@ -1526,8 +1535,11 @@ TMH_DB_execute_refresh_reveal (struct MHD_Connection *connection, ev_sigs, commit_coins); for (i=0;i +/** + * Cached JSON for /wire response. + */ +static json_t *wire_methods; + + /** * Handle a "/wire" request. * @@ -43,8 +49,6 @@ TMH_WIRE_handler_wire (struct TMH_RequestHandler *rh, const char *upload_data, size_t *upload_data_size) { - static json_t *wire_methods; - if (NULL == wire_methods) wire_methods = TMH_VALIDATION_get_wire_methods ("exchange-wire-incoming"); @@ -54,4 +58,19 @@ TMH_WIRE_handler_wire (struct TMH_RequestHandler *rh, } +/** + * Initialize libgcrypt. + */ +void __attribute__ ((destructor)) +TEH_wire_cleanup () +{ + if (NULL != wire_methods) + { + json_decref (wire_methods); + wire_methods = NULL; + } +} + + + /* end of taler-exchange-httpd_wire.c */ diff --git a/src/exchangedb/plugin_exchangedb_common.c b/src/exchangedb/plugin_exchangedb_common.c index 3bf9bda32..2c3cafe10 100644 --- a/src/exchangedb/plugin_exchangedb_common.c +++ b/src/exchangedb/plugin_exchangedb_common.c @@ -75,6 +75,10 @@ common_free_link_data_list (void *cls, while (NULL != ldl) { next = ldl->next; + if (NULL != ldl->denom_pub.rsa_public_key) + GNUNET_CRYPTO_rsa_public_key_free (ldl->denom_pub.rsa_public_key); + if (NULL != ldl->ev_sig.rsa_signature) + GNUNET_CRYPTO_rsa_signature_free (ldl->ev_sig.rsa_signature); GNUNET_free (ldl); ldl = next; } @@ -108,9 +112,17 @@ common_free_coin_transaction_list (void *cls, GNUNET_free (list->details.deposit); break; case TALER_EXCHANGEDB_TT_REFRESH_MELT: + if (NULL != list->details.melt->coin.denom_pub.rsa_public_key) + GNUNET_CRYPTO_rsa_public_key_free (list->details.melt->coin.denom_pub.rsa_public_key); + if (NULL != list->details.melt->coin.denom_sig.rsa_signature) + GNUNET_CRYPTO_rsa_signature_free (list->details.melt->coin.denom_sig.rsa_signature); GNUNET_free (list->details.melt); break; case TALER_EXCHANGEDB_TT_REFUND: + if (NULL != list->details.refund->coin.denom_pub.rsa_public_key) + GNUNET_CRYPTO_rsa_public_key_free (list->details.refund->coin.denom_pub.rsa_public_key); + if (NULL != list->details.refund->coin.denom_sig.rsa_signature) + GNUNET_CRYPTO_rsa_signature_free (list->details.refund->coin.denom_sig.rsa_signature); GNUNET_free (list->details.refund); break; } diff --git a/src/exchangedb/plugin_exchangedb_postgres.c b/src/exchangedb/plugin_exchangedb_postgres.c index d12f0c92a..fa06059f5 100644 --- a/src/exchangedb/plugin_exchangedb_postgres.c +++ b/src/exchangedb/plugin_exchangedb_postgres.c @@ -2568,13 +2568,16 @@ get_known_coin (void *cls, } GNUNET_assert (1 == nrows); /* due to primary key */ if (NULL == coin_info) + { + PQclear (result); return GNUNET_YES; + } { struct GNUNET_PQ_ResultSpec rs[] = { GNUNET_PQ_result_spec_rsa_public_key ("denom_pub", - &coin_info->denom_pub.rsa_public_key), + &coin_info->denom_pub.rsa_public_key), GNUNET_PQ_result_spec_rsa_signature ("denom_sig", - &coin_info->denom_sig.rsa_signature), + &coin_info->denom_sig.rsa_signature), GNUNET_PQ_result_spec_end }; @@ -3339,6 +3342,9 @@ postgres_get_melt_commitment (void *cls, session_hash, &rs)) return NULL; + /* we don't care about most of 'rs' */ + GNUNET_CRYPTO_rsa_public_key_free (rs.melt.coin.denom_pub.rsa_public_key); + GNUNET_CRYPTO_rsa_signature_free (rs.melt.coin.denom_sig.rsa_signature); mc = GNUNET_new (struct TALER_EXCHANGEDB_MeltCommitment); mc->num_newcoins = rs.num_newcoins; mc->denom_pubs = GNUNET_new_array (mc->num_newcoins, @@ -3505,6 +3511,7 @@ postgres_get_link_data_list (void *cls, pos->ev_sig.rsa_signature = sig; ldl = pos; } + PQclear (result); return ldl; } @@ -3810,10 +3817,11 @@ postgres_get_coin_transactions (void *cls, tl->next = head; tl->type = TALER_EXCHANGEDB_TT_REFUND; tl->details.refund = refund; - if (GNUNET_SYSERR == get_known_coin (cls, - session, - coin_pub, - &refund->coin)) + if (GNUNET_SYSERR == + get_known_coin (cls, + session, + coin_pub, + &refund->coin)) { GNUNET_break (0); GNUNET_free (refund); @@ -4310,27 +4318,33 @@ postgres_gc (void *cls) if (PGRES_COMMAND_OK != PQresultStatus (result)) { BREAK_DB_ERR (result); + PQclear (result); PQfinish (conn); return GNUNET_SYSERR; } + PQclear (result); result = GNUNET_PQ_exec_prepared (conn, "gc_denominations", params_time); if (PGRES_COMMAND_OK != PQresultStatus (result)) { BREAK_DB_ERR (result); + PQclear (result); PQfinish (conn); return GNUNET_SYSERR; } + PQclear (result); result = GNUNET_PQ_exec_prepared (conn, "gc_reserves", params_time); if (PGRES_COMMAND_OK != PQresultStatus (result)) { BREAK_DB_ERR (result); + PQclear (result); PQfinish (conn); return GNUNET_SYSERR; } + PQclear (result); PQfinish (conn); return GNUNET_OK; } diff --git a/src/exchangedb/test_exchangedb.c b/src/exchangedb/test_exchangedb.c index b03fff313..5d1dba0dc 100644 --- a/src/exchangedb/test_exchangedb.c +++ b/src/exchangedb/test_exchangedb.c @@ -434,7 +434,10 @@ test_refresh_commit_coins (struct TALER_EXCHANGEDB_Session *session, FAILIF (0 != memcmp (a_rlink.coin_priv_enc, b_rlink.coin_priv_enc, sizeof (a_rlink.coin_priv_enc))); + GNUNET_free (ret_commit_coins[cnt].coin_ev); } + GNUNET_free (ret_commit_coins); + ret_commit_coins = NULL; } ret = GNUNET_OK; @@ -781,6 +784,8 @@ test_melting (struct TALER_EXCHANGEDB_Session *session) ret = GNUNET_OK; drop: + for (cnt=0; cnt < MELT_NEW_COINS; cnt++) + GNUNET_CRYPTO_rsa_signature_free (ev_sigs[cnt].rsa_signature); for (cnt=0;cnttask) + GNUNET_SCHEDULER_cancel (pth->task); + json_decref (pth->wire); + GNUNET_free (pth); +} + + /** * Prepare for exeuction of a wire transfer. Calls the * callback with the serialized state. @@ -405,7 +423,8 @@ do_prepare (void *cls) pth->ptc (pth->ptc_cls, NULL, 0); - GNUNET_free (pth); + test_prepare_wire_transfer_cancel (NULL, + pth); return; } len = strlen (wire_enc) + 1; @@ -429,7 +448,8 @@ do_prepare (void *cls) } free (wire_enc); /* not using GNUNET_free(), as this one is allocated by libjansson */ - GNUNET_free (pth); + test_prepare_wire_transfer_cancel (NULL, + pth); } @@ -469,8 +489,7 @@ test_prepare_wire_transfer (void *cls, } pth = GNUNET_new (struct TALER_WIRE_PrepareHandle); pth->tc = tc; - pth->wire = (json_t *) wire; - json_incref (pth->wire); + pth->wire = json_incref ((json_t *) wire); pth->wtid = *wtid; pth->ptc = ptc; pth->ptc_cls = ptc_cls; @@ -481,23 +500,6 @@ test_prepare_wire_transfer (void *cls, } -/** - * Abort preparation of a wire transfer. For example, - * because we are shutting down. - * - * @param cls the @e cls of this struct with the plugin-specific state - * @param pth preparation to cancel - */ -static void -test_prepare_wire_transfer_cancel (void *cls, - struct TALER_WIRE_PrepareHandle *pth) -{ - GNUNET_SCHEDULER_cancel (pth->task); - json_decref (pth->wire); - GNUNET_free (pth); -} - - /** * Called with the result of submitting information about an incoming * transaction to a bank.