address fixme, fix use-after-free in testing traits

This commit is contained in:
Florian Dold 2020-01-17 20:50:09 +01:00
parent fbb4256d55
commit 33877b2c55
No known key found for this signature in database
GPG Key ID: D2E4F00F29D02A4B
5 changed files with 88 additions and 10 deletions

View File

@ -1261,12 +1261,11 @@ setup_general_response_headers (const struct TEH_KS_StateHandle *key_state,
m = GNUNET_TIME_relative_to_absolute (TEH_max_keys_caching); m = GNUNET_TIME_relative_to_absolute (TEH_max_keys_caching);
m = GNUNET_TIME_absolute_min (m, m = GNUNET_TIME_absolute_min (m,
key_state->next_reload); key_state->next_reload);
// FIXME: setting 'm' to FOREVER here exposes
// a crash-bug in lib/ where we access /keys
// data after it was already free'd!
// m = GNUNET_TIME_UNIT_FOREVER_ABS;
get_date_string (m, get_date_string (m,
dat); dat);
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
"settings /keys 'Expires' header to '%s'\n",
dat);
GNUNET_break (MHD_YES == GNUNET_break (MHD_YES ==
MHD_add_response_header (response, MHD_add_response_header (response,
MHD_HTTP_HEADER_EXPIRES, MHD_HTTP_HEADER_EXPIRES,

View File

@ -530,6 +530,28 @@ TALER_EXCHANGE_get_denomination_key (const struct TALER_EXCHANGE_Keys *keys,
TALER_DenominationPublicKey *pk); TALER_DenominationPublicKey *pk);
/**
* Create a copy of a denomination public key.
*
* @param key key to copy
* @returns a copy, must be freed with #TALER_EXCHANGE_destroy_denomination_key
*/
struct TALER_EXCHANGE_DenomPublicKey *
TALER_EXCHANGE_copy_denomination_key (const struct
TALER_EXCHANGE_DenomPublicKey *key);
/**
* Destroy a denomination public key.
* Should only be called with keys created by #TALER_EXCHANGE_copy_denomination_key.
*
* @param key key to destroy.
*/
void
TALER_EXCHANGE_destroy_denomination_key (struct
TALER_EXCHANGE_DenomPublicKey *key);
/** /**
* Obtain the denomination key details from the exchange. * Obtain the denomination key details from the exchange.
* *

View File

@ -2127,6 +2127,43 @@ TALER_EXCHANGE_get_denomination_key (const struct TALER_EXCHANGE_Keys *keys,
} }
/**
* Create a copy of a denomination public key.
*
* @param key key to copy
* @returns a copy, must be freed with #TALER_EXCHANGE_destroy_denomination_key
*/
struct TALER_EXCHANGE_DenomPublicKey *
TALER_EXCHANGE_copy_denomination_key (const struct
TALER_EXCHANGE_DenomPublicKey *key)
{
struct TALER_EXCHANGE_DenomPublicKey *copy;
copy = GNUNET_new (struct TALER_EXCHANGE_DenomPublicKey);
*copy = *key;
copy->key.rsa_public_key = GNUNET_CRYPTO_rsa_public_key_dup (
key->key.rsa_public_key);
return copy;
}
/**
* Destroy a denomination public key.
* Should only be called with keys created by #TALER_EXCHANGE_copy_denomination_key.
*
* @param key key to destroy.
*/
void
TALER_EXCHANGE_destroy_denomination_key (struct
TALER_EXCHANGE_DenomPublicKey *key)
{
GNUNET_CRYPTO_rsa_public_key_free (key->key.rsa_public_key);;
key->key.rsa_public_key = NULL;
GNUNET_free (key);
}
/** /**
* Obtain the denomination key details from the exchange. * Obtain the denomination key details from the exchange.
* *

View File

@ -988,6 +988,9 @@ refresh_melt_run (void *cls,
&melt_amount, &melt_amount,
&fresh_pk->fee_withdraw)); &fresh_pk->fee_withdraw));
rms->fresh_pks[i] = *fresh_pk; rms->fresh_pks[i] = *fresh_pk;
/* Make a deep copy of the RSA key */
rms->fresh_pks[i].key.rsa_public_key = GNUNET_CRYPTO_rsa_public_key_dup (
fresh_pk->key.rsa_public_key);
} }
rms->refresh_data = TALER_EXCHANGE_refresh_prepare rms->refresh_data = TALER_EXCHANGE_refresh_prepare
(rms->melt_priv, &melt_amount, melt_sig, (rms->melt_priv, &melt_amount, melt_sig,
@ -1041,6 +1044,11 @@ refresh_melt_cleanup (void *cls,
GNUNET_SCHEDULER_cancel (rms->retry_task); GNUNET_SCHEDULER_cancel (rms->retry_task);
rms->retry_task = NULL; rms->retry_task = NULL;
} }
if (NULL != rms->fresh_pks)
{
for (unsigned int i = 0; i < rms->num_fresh_coins; i++)
GNUNET_CRYPTO_rsa_public_key_free (rms->fresh_pks[i].key.rsa_public_key);
}
GNUNET_free_non_null (rms->fresh_pks); GNUNET_free_non_null (rms->fresh_pks);
rms->fresh_pks = NULL; rms->fresh_pks = NULL;
GNUNET_free_non_null (rms->refresh_data); GNUNET_free_non_null (rms->refresh_data);

View File

@ -55,7 +55,7 @@ struct WithdrawState
* use. Otherwise, this will be set (by the interpreter) to the * use. Otherwise, this will be set (by the interpreter) to the
* denomination PK matching @e amount. * denomination PK matching @e amount.
*/ */
const struct TALER_EXCHANGE_DenomPublicKey *pk; struct TALER_EXCHANGE_DenomPublicKey *pk;
/** /**
* Exchange base URL. Only used as offered trait. * Exchange base URL. Only used as offered trait.
@ -246,6 +246,7 @@ withdraw_run (void *cls,
struct WithdrawState *ws = cls; struct WithdrawState *ws = cls;
const struct TALER_ReservePrivateKeyP *rp; const struct TALER_ReservePrivateKeyP *rp;
const struct TALER_TESTING_Command *create_reserve; const struct TALER_TESTING_Command *create_reserve;
const struct TALER_EXCHANGE_DenomPublicKey *dpk;
(void) cmd; (void) cmd;
create_reserve = TALER_TESTING_interpreter_lookup_command create_reserve = TALER_TESTING_interpreter_lookup_command
@ -268,16 +269,21 @@ withdraw_run (void *cls,
TALER_planchet_setup_random (&ws->ps); TALER_planchet_setup_random (&ws->ps);
ws->is = is; ws->is = is;
ws->pk = TALER_TESTING_find_pk dpk = TALER_TESTING_find_pk (TALER_EXCHANGE_get_keys (is->exchange),
(TALER_EXCHANGE_get_keys (is->exchange), &ws->amount);
&ws->amount); if (NULL == dpk)
if (NULL == ws->pk)
{ {
GNUNET_log (GNUNET_ERROR_TYPE_ERROR, GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
"Failed to determine denomination key at %s\n", "Failed to determine denomination key at %s\n",
cmd->label); cmd->label);
GNUNET_assert (0); GNUNET_assert (0);
} }
else
{
/* We copy the denomination key, as re-querying /keys
* would free the old one. */
ws->pk = TALER_EXCHANGE_copy_denomination_key (dpk);
}
ws->wsh = TALER_EXCHANGE_reserve_withdraw (is->exchange, ws->wsh = TALER_EXCHANGE_reserve_withdraw (is->exchange,
ws->pk, ws->pk,
@ -325,6 +331,12 @@ withdraw_cleanup (void *cls,
GNUNET_CRYPTO_rsa_signature_free (ws->sig.rsa_signature); GNUNET_CRYPTO_rsa_signature_free (ws->sig.rsa_signature);
ws->sig.rsa_signature = NULL; ws->sig.rsa_signature = NULL;
} }
if (NULL != ws->pk)
{
TALER_EXCHANGE_destroy_denomination_key (ws->pk);
ws->pk = NULL;
}
GNUNET_free_non_null (ws->exchange_url); GNUNET_free_non_null (ws->exchange_url);
GNUNET_free (ws); GNUNET_free (ws);
} }
@ -493,7 +505,7 @@ TALER_TESTING_cmd_withdraw_denomination
} }
ws = GNUNET_new (struct WithdrawState); ws = GNUNET_new (struct WithdrawState);
ws->reserve_reference = reserve_reference; ws->reserve_reference = reserve_reference;
ws->pk = dk; ws->pk = TALER_EXCHANGE_copy_denomination_key (dk);
ws->expected_response_code = expected_response_code; ws->expected_response_code = expected_response_code;
{ {
struct TALER_TESTING_Command cmd = { struct TALER_TESTING_Command cmd = {