exchange

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

commit 5e8bdb50dc4039833f018002132abbbaaf47013f
parent f0114f84d8e4aa3d36c839a84dccae6c24c70c68
Author: Christian Grothoff <christian@grothoff.org>
Date:   Sun, 11 Oct 2026 14:56:28 +0200

move VLA-allocations on heap and bound

Diffstat:
Msrc/lib/exchange_api_get-aml-OFFICER_PUB-attributes-H_NORMALIZED_PAYTO.c | 17++++++++++++-----
Msrc/lib/exchange_api_get-aml-OFFICER_PUB-decisions.c | 17++++++++++++-----
Msrc/lib/exchange_api_get-aml-OFFICER_PUB-kyc-statistics-NAMES.c | 17++++++++++++-----
Msrc/lib/exchange_api_get-aml-OFFICER_PUB-measures.c | 44++++++++++++++++++++++++++++++++------------
Msrc/lib/exchange_api_get-kyc-check-H_NORMALIZED_PAYTO.c | 12+++++++++++-
Msrc/lib/exchange_api_get-kyc-info-ACCESS_TOKEN.c | 33++++++++++++++++++++++-----------
Msrc/lib/exchange_api_get-reserves-RESERVE_PUB-attest.c | 11++++++++++-
7 files changed, 111 insertions(+), 40 deletions(-)

diff --git a/src/lib/exchange_api_get-aml-OFFICER_PUB-attributes-H_NORMALIZED_PAYTO.c b/src/lib/exchange_api_get-aml-OFFICER_PUB-attributes-H_NORMALIZED_PAYTO.c @@ -186,23 +186,30 @@ parse_get_aml_attributes_ok ( } lr.details.ok.details_length = json_array_size (jdetails); { - struct TALER_EXCHANGE_GetAmlAttributesCollectionEvent details[ - GNUNET_NZL (lr.details.ok.details_length)]; + struct TALER_EXCHANGE_GetAmlAttributesCollectionEvent *details; - memset (details, - 0, - sizeof (details)); + if (lr.details.ok.details_length > + GNUNET_MAX_MALLOC_CHECKED / sizeof (*details)) + { + GNUNET_break_op (0); + return GNUNET_SYSERR; + } + details = GNUNET_new_array ( + GNUNET_NZL (lr.details.ok.details_length), + struct TALER_EXCHANGE_GetAmlAttributesCollectionEvent); lr.details.ok.details = details; if (GNUNET_OK != parse_attributes (jdetails, details)) { GNUNET_break_op (0); + GNUNET_free (details); return GNUNET_SYSERR; } aagh->cb (aagh->cb_cls, &lr); aagh->cb = NULL; + GNUNET_free (details); } return GNUNET_OK; } diff --git a/src/lib/exchange_api_get-aml-OFFICER_PUB-decisions.c b/src/lib/exchange_api_get-aml-OFFICER_PUB-decisions.c @@ -391,6 +391,13 @@ parse_get_aml_decisions_ok (struct TALER_EXCHANGE_GetAmlDecisionsHandle *adgh, } lr.details.ok.records_length = json_array_size (jrecords); + if (lr.details.ok.records_length > + GNUNET_MAX_MALLOC_CHECKED + / sizeof (struct TALER_EXCHANGE_GetAmlDecisionsDecision)) + { + GNUNET_break_op (0); + return GNUNET_SYSERR; + } /* First pass: count total rules and measures across all records */ { @@ -434,13 +441,12 @@ parse_get_aml_decisions_ok (struct TALER_EXCHANGE_GetAmlDecisionsHandle *adgh, } { - struct TALER_EXCHANGE_GetAmlDecisionsDecision records[ - GNUNET_NZL (lr.details.ok.records_length)]; + struct TALER_EXCHANGE_GetAmlDecisionsDecision *records; enum GNUNET_GenericReturnValue ret; - memset (records, - 0, - sizeof (records)); + records = GNUNET_new_array ( + GNUNET_NZL (lr.details.ok.records_length), + struct TALER_EXCHANGE_GetAmlDecisionsDecision); lr.details.ok.records = records; ret = parse_aml_decisions (adgh, jrecords, @@ -452,6 +458,7 @@ parse_get_aml_decisions_ok (struct TALER_EXCHANGE_GetAmlDecisionsHandle *adgh, &lr); adgh->cb = NULL; } + GNUNET_free (records); GNUNET_free (adgh->all_rules); adgh->all_rules = NULL; GNUNET_free (adgh->all_mp); diff --git a/src/lib/exchange_api_get-aml-OFFICER_PUB-kyc-statistics-NAMES.c b/src/lib/exchange_api_get-aml-OFFICER_PUB-kyc-statistics-NAMES.c @@ -133,14 +133,19 @@ parse_stats_ok_new ( } lr.details.ok.statistics_length = json_array_size (jstatistics); { - struct TALER_EXCHANGE_GetAmlKycStatisticsEventCounter statistics[ - GNUNET_NZL (lr.details.ok.statistics_length)]; + struct TALER_EXCHANGE_GetAmlKycStatisticsEventCounter *statistics; json_t *obj; size_t idx; - memset (statistics, - 0, - sizeof (statistics)); + if (lr.details.ok.statistics_length > + GNUNET_MAX_MALLOC_CHECKED / sizeof (*statistics)) + { + GNUNET_break_op (0); + return GNUNET_SYSERR; + } + statistics = GNUNET_new_array ( + GNUNET_NZL (lr.details.ok.statistics_length), + struct TALER_EXCHANGE_GetAmlKycStatisticsEventCounter); lr.details.ok.statistics = statistics; json_array_foreach (jstatistics, idx, obj) { @@ -161,12 +166,14 @@ parse_stats_ok_new ( NULL)) { GNUNET_break_op (0); + GNUNET_free (statistics); return GNUNET_SYSERR; } } aksh->cb (aksh->cb_cls, &lr); aksh->cb = NULL; + GNUNET_free (statistics); } return GNUNET_OK; } diff --git a/src/lib/exchange_api_get-aml-OFFICER_PUB-measures.c b/src/lib/exchange_api_get-aml-OFFICER_PUB-measures.c @@ -505,20 +505,36 @@ parse_get_aml_measures_ok (struct TALER_EXCHANGE_GetAmlMeasuresHandle *amh, (NULL != jdefault_rules) ? json_array_size (jdefault_rules) : 0; { - struct TALER_EXCHANGE_GetAmlMeasuresMeasureInfo roots[ - GNUNET_NZL (lr.details.ok.roots_length)]; - struct TALER_EXCHANGE_GetAmlMeasuresProgramRequirement progs[ - GNUNET_NZL (lr.details.ok.programs_length)]; - struct TALER_EXCHANGE_GetAmlMeasuresCheckInfo checks[ - GNUNET_NZL (lr.details.ok.checks_length)]; - struct TALER_EXCHANGE_GetAmlMeasuresKycRule drules[ - GNUNET_NZL (lr.details.ok.default_rules_length)]; + struct TALER_EXCHANGE_GetAmlMeasuresMeasureInfo *roots; + struct TALER_EXCHANGE_GetAmlMeasuresProgramRequirement *progs; + struct TALER_EXCHANGE_GetAmlMeasuresCheckInfo *checks; + struct TALER_EXCHANGE_GetAmlMeasuresKycRule *drules; enum GNUNET_GenericReturnValue ret; - memset (roots, 0, sizeof (roots)); - memset (progs, 0, sizeof (progs)); - memset (checks, 0, sizeof (checks)); - memset (drules, 0, sizeof (drules)); + if ( (lr.details.ok.roots_length > + GNUNET_MAX_MALLOC_CHECKED / sizeof (*roots)) || + (lr.details.ok.programs_length > + GNUNET_MAX_MALLOC_CHECKED / sizeof (*progs)) || + (lr.details.ok.checks_length > + GNUNET_MAX_MALLOC_CHECKED / sizeof (*checks)) || + (lr.details.ok.default_rules_length > + GNUNET_MAX_MALLOC_CHECKED / sizeof (*drules)) ) + { + GNUNET_break_op (0); + return GNUNET_SYSERR; + } + roots = GNUNET_new_array ( + GNUNET_NZL (lr.details.ok.roots_length), + struct TALER_EXCHANGE_GetAmlMeasuresMeasureInfo); + progs = GNUNET_new_array ( + GNUNET_NZL (lr.details.ok.programs_length), + struct TALER_EXCHANGE_GetAmlMeasuresProgramRequirement); + checks = GNUNET_new_array ( + GNUNET_NZL (lr.details.ok.checks_length), + struct TALER_EXCHANGE_GetAmlMeasuresCheckInfo); + drules = GNUNET_new_array ( + GNUNET_NZL (lr.details.ok.default_rules_length), + struct TALER_EXCHANGE_GetAmlMeasuresKycRule); lr.details.ok.roots = roots; lr.details.ok.programs = progs; lr.details.ok.checks = checks; @@ -537,6 +553,10 @@ parse_get_aml_measures_ok (struct TALER_EXCHANGE_GetAmlMeasuresHandle *amh, &lr); amh->cb = NULL; } + GNUNET_free (roots); + GNUNET_free (progs); + GNUNET_free (checks); + GNUNET_free (drules); free_scrap (amh); return ret; } diff --git a/src/lib/exchange_api_get-kyc-check-H_NORMALIZED_PAYTO.c b/src/lib/exchange_api_get-kyc-check-H_NORMALIZED_PAYTO.c @@ -141,10 +141,18 @@ parse_account_status ( (0 != json_array_size (limits)) ) { size_t limit_length = json_array_size (limits); - struct TALER_EXCHANGE_AccountLimit ala[GNUNET_NZL (limit_length)]; + struct TALER_EXCHANGE_AccountLimit *ala; size_t i; json_t *limit; + if (limit_length > + GNUNET_MAX_MALLOC_CHECKED / sizeof (*ala)) + { + GNUNET_break_op (0); + return GNUNET_SYSERR; + } + ala = GNUNET_new_array (limit_length, + struct TALER_EXCHANGE_AccountLimit); json_array_foreach (limits, i, limit) { struct TALER_EXCHANGE_AccountLimit *al = &ala[i]; @@ -169,6 +177,7 @@ parse_account_status ( NULL, NULL)) { GNUNET_break_op (0); + GNUNET_free (ala); return GNUNET_SYSERR; } } @@ -176,6 +185,7 @@ parse_account_status ( status->limits_length = limit_length; gkch->cb (gkch->cb_cls, res); + GNUNET_free (ala); } else { diff --git a/src/lib/exchange_api_get-kyc-info-ACCESS_TOKEN.c b/src/lib/exchange_api_get-kyc-info-ACCESS_TOKEN.c @@ -125,22 +125,27 @@ parse_kyc_info_ok (struct TALER_EXCHANGE_GetKycInfoHandle *lh, lr.details.ok.requirements_length = json_array_size (jrequirements); { - struct TALER_EXCHANGE_VoluntaryCheckInformation vci[ - GNUNET_NZL (lr.details.ok.vci_length)]; - struct TALER_EXCHANGE_RequirementInformation requirements[ - GNUNET_NZL (lr.details.ok.requirements_length)]; + struct TALER_EXCHANGE_VoluntaryCheckInformation *vci; + struct TALER_EXCHANGE_RequirementInformation *requirements; const char *name; const json_t *jreq; const json_t *jvc; size_t off; - memset (vci, - 0, - sizeof (vci)); - memset (requirements, - 0, - sizeof (requirements)); - + if ( (lr.details.ok.vci_length > + GNUNET_MAX_MALLOC_CHECKED / sizeof (*vci)) || + (lr.details.ok.requirements_length > + GNUNET_MAX_MALLOC_CHECKED / sizeof (*requirements)) ) + { + GNUNET_break_op (0); + return GNUNET_SYSERR; + } + vci = GNUNET_new_array ( + GNUNET_NZL (lr.details.ok.vci_length), + struct TALER_EXCHANGE_VoluntaryCheckInformation); + requirements = GNUNET_new_array ( + GNUNET_NZL (lr.details.ok.requirements_length), + struct TALER_EXCHANGE_RequirementInformation); json_array_foreach ((json_t *) jrequirements, off, jreq) { struct TALER_EXCHANGE_RequirementInformation *req = &requirements[off]; @@ -166,6 +171,8 @@ parse_kyc_info_ok (struct TALER_EXCHANGE_GetKycInfoHandle *lh, NULL, NULL)) { GNUNET_break_op (0); + GNUNET_free (vci); + GNUNET_free (requirements); return GNUNET_SYSERR; } } @@ -192,6 +199,8 @@ parse_kyc_info_ok (struct TALER_EXCHANGE_GetKycInfoHandle *lh, NULL, NULL)) { GNUNET_break_op (0); + GNUNET_free (vci); + GNUNET_free (requirements); return GNUNET_SYSERR; } } @@ -202,6 +211,8 @@ parse_kyc_info_ok (struct TALER_EXCHANGE_GetKycInfoHandle *lh, lh->cb (lh->cb_cls, &lr); lh->cb = NULL; + GNUNET_free (vci); + GNUNET_free (requirements); return GNUNET_OK; } } diff --git a/src/lib/exchange_api_get-reserves-RESERVE_PUB-attest.c b/src/lib/exchange_api_get-reserves-RESERVE_PUB-attest.c @@ -108,8 +108,15 @@ handle_reserves_get_attestable_ok ( } { size_t dlen = json_array_size (details); - const char *attributes[GNUNET_NZL (dlen)]; + const char **attributes; + if (dlen > GNUNET_MAX_MALLOC_CHECKED / sizeof (*attributes)) + { + GNUNET_break_op (0); + return GNUNET_SYSERR; + } + attributes = GNUNET_new_array (GNUNET_NZL (dlen), + const char *); for (unsigned int i = 0; i < dlen; i++) { json_t *detail = json_array_get (details, @@ -118,6 +125,7 @@ handle_reserves_get_attestable_ok ( if (NULL == attributes[i]) { GNUNET_break_op (0); + GNUNET_free (attributes); return GNUNET_SYSERR; } } @@ -126,6 +134,7 @@ handle_reserves_get_attestable_ok ( grah->cb (grah->cb_cls, &rs); grah->cb = NULL; + GNUNET_free (attributes); } return GNUNET_OK; }