commit 7bf11f3ad51fdbf0f3046c2306dee9e16069c3be
parent 523cb87773b79bb03865643007288944ac93abae
Author: Florian Dold <florian@dold.me>
Date: Fri, 17 Oct 2025 16:02:22 +0200
donau: fix use after free, fix memory leak
Diffstat:
1 file changed, 25 insertions(+), 13 deletions(-)
diff --git a/src/backend/taler-merchant-httpd_post-orders-ID-pay.c b/src/backend/taler-merchant-httpd_post-orders-ID-pay.c
@@ -3888,6 +3888,7 @@ append_output_token_sig (void *cls,
out.output_index = pc->output_index_gen;
out.h_issue.hash = *h_issue;
out.sig.signature = sig;
+ GNUNET_CRYPTO_blind_sig_incref (sig);
GNUNET_array_append (pc->output_tokens,
pc->output_tokens_len,
out);
@@ -4129,18 +4130,9 @@ phase_check_contract (struct PayContext *pc)
NULL));
return;
}
- if (paid)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_INFO,
- "Order `%s' paid, checking for double-payment\n",
- pc->order_id);
- pc->phase = PP_CONTRACT_PAID;
- return;
- }
- GNUNET_log (GNUNET_ERROR_TYPE_INFO,
- "Handling payment for order `%s' with contract hash `%s'\n",
- pc->order_id,
- GNUNET_h2s (&pc->check_contract.h_contract_terms.hash));
+
+ /* Parse the contract terms even for paid orders,
+ as later phases need it. */
pc->check_contract.contract_terms = TALER_MERCHANT_contract_parse (
pc->check_contract.contract_terms_json,
@@ -4159,7 +4151,20 @@ phase_check_contract (struct PayContext *pc)
return;
}
- /* Get details from contract and check fundamentals */
+ if (paid)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+ "Order `%s' paid, checking for double-payment\n",
+ pc->order_id);
+ pc->phase = PP_CONTRACT_PAID;
+ return;
+ }
+ GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+ "Handling payment for order `%s' with contract hash `%s'\n",
+ pc->order_id,
+ GNUNET_h2s (&pc->check_contract.h_contract_terms.hash));
+
+ /* Check fundamentals */
{
switch (pc->check_contract.contract_terms->version)
{
@@ -4918,6 +4923,13 @@ pay_context_cleanup (void *cls)
pc->parse_wallet_data.donau_keys = NULL;
}
#endif
+ if (NULL != pc->output_tokens)
+ {
+ for (unsigned int i = 0; i<pc->output_tokens_len; i++)
+ GNUNET_CRYPTO_blind_sig_incref (pc->output_tokens[i].sig.signature);
+ GNUNET_free (pc->output_tokens);
+ pc->output_tokens = NULL;
+ }
GNUNET_free (pc);
}