[PATCH] locale: programs: repertoire.c: Limit maximum range size to prevent resource exhaustion

Adhemerval Zanella Netto adhemerval.zanella@linaro.org
Wed Oct 29 16:59:58 GMT 2025



On 29/10/25 11:16, Anton Moryakov wrote:
> The function `repertoire_new_char` uses values parsed from untrusted input
> via `strtoul()` as loop bounds without enforcing a reasonable upper limit.
> An attacker could craft a malformed repertoire map with an extremely large
> range (e.g., SYMBOL1...SYMBOL999999999), causing excessive memory usage and
> CPU consumption, leading to a denial-of-service condition.
> 
> This patch introduces a new constant `MAX_RANGE_SIZE` (set to 1000) and
> validates that the range size (to_nr - from_nr) does not exceed it before
> entering the loop. This ensures predictable resource usage while still
> supporting legitimate use cases.
> 
> The fix enhances robustness against malicious input, aligning with security
> best practices for parsing untrusted data in system libraries.
> 
> Signed-off-by: Anton Moryakov <ant.v.moryakov@gmail.com>


Do we have a testcase that triggers this issue? And do we need a bug report
for this?

> ---
>  locale/programs/repertoire.c | 9 ++++++++-
>  1 file changed, 8 insertions(+), 1 deletion(-)
> 
> diff --git a/locale/programs/repertoire.c b/locale/programs/repertoire.c
> index 7ed8c915dd..e0b791633e 100644
> --- a/locale/programs/repertoire.c
> +++ b/locale/programs/repertoire.c
> @@ -379,7 +379,7 @@ repertoiremap_hash (const char *str, size_t len)
>    return NULL;
>  }
>  
> -
> +#define MAX_RANGE_SIZE 1000
>  static void
>  repertoire_new_char (struct linereader *lr, hash_table *ht, hash_table *rt,
>  		     struct obstack *ob, uint32_t value, const char *from,
> @@ -455,6 +455,13 @@ hexadecimal range format should use only capital characters"));
>        return;
>      }
>  
> +	if (to_nr - from_nr > MAX_RANGE_SIZE)
> +	  {
> +	    lr_error (lr, _("character range too large: %lu entries, limit is %d"),
> +	              to_nr - from_nr + 1, MAX_RANGE_SIZE);
> +	    return;
> +	  }
> +
>    for (cnt = from_nr; cnt <= to_nr; ++cnt)
>      {
>        uint32_t this_value = value + (cnt - from_nr);



More information about the Libc-alpha mailing list