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

Anton Moryakov ant.v.moryakov@gmail.com
Wed Oct 29 14:16:05 GMT 2025


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>
---
 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);
-- 
2.39.2



More information about the Libc-alpha mailing list