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:
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,