anastasis

Credential backup and recovery protocol and service
Log | Files | Refs | Submodules | README | LICENSE

commit eaa48160b91b4b6146b3549435f11d06383d960d
parent 21c29c4bfb379593797e91a108b49f249587e8bd
Author: Christian Grothoff <christian@grothoff.org>
Date:   Wed, 29 Jul 2026 13:08:13 +0200

reducer: bound the number of optional attributes in policy discovery

Diffstat:
Msrc/reducer/anastasis_api_discovery.c | 24++++++++++++++++++++++++
1 file changed, 24 insertions(+), 0 deletions(-)

diff --git a/src/reducer/anastasis_api_discovery.c b/src/reducer/anastasis_api_discovery.c @@ -29,6 +29,16 @@ /** + * Maximum number of *optional* identity attributes we are willing to + * enumerate subsets of in #ANASTASIS_policy_discovery_start(). The mask + * loop there is 2^n, so this bounds the work at 65536 combinations; it also + * keeps `1LLU << opt_cnt` well-defined (it is undefined for n >= 64) and the + * 64-bit loop counter from wrapping. + */ +#define MAX_OPTIONAL_ATTRIBUTES 16 + + +/** * Handle for one request we are doing at a specific provider. */ struct ProviderOperation @@ -392,6 +402,20 @@ ANASTASIS_policy_discovery_start (const json_t *state, if (present && a->optional) opt_cnt++; } + /* `opt_cnt` drives the 2^opt_cnt mask loop below; both it and + `identity_attributes` come from the untrusted `state`, so a crafted + state with ~40 optional attributes would queue ~10^12 provider + downloads. Fail closed instead. */ + if (opt_cnt > MAX_OPTIONAL_ATTRIBUTES) + { + GNUNET_break_op (0); + GNUNET_log (GNUNET_ERROR_TYPE_WARNING, + "Refusing policy discovery over %u optional attributes (max %u)\n", + opt_cnt, + (unsigned int) MAX_OPTIONAL_ATTRIBUTES); + ANASTASIS_REDUX_state_free_ (rs); + return NULL; + } pd = GNUNET_new (struct ANASTASIS_PolicyDiscovery); pd->dd_map = GNUNET_CONTAINER_multihashmap_create (128,