]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
gas: further limit .rept count
authorAlan Modra <amodra@gmail.com>
Mon, 16 Feb 2026 23:27:52 +0000 (09:57 +1030)
committerAlan Modra <amodra@gmail.com>
Tue, 17 Feb 2026 00:45:47 +0000 (11:15 +1030)
gas currently limits a rept count at 0x7fffffff.  With a minimal rept
body this requires at least 2G * 16 due to the .linefile directive
added by buffer_and_nest.  I'm inclined to think 32G is excessive.

This patch limits the total memory used by rept to 4G (2G on 32-bit
systems).  That of course reduces allowed repeat counts by a factor of
at least 8, and note that the file name affects the max repeat.

The patch also changes the repeat count to 1 rather than 0 when
we hit the limit, so that the body of the rept is not entirely ignored.

Nested rept can still easily cause OOM of course.

* read.c (do_repeat): Limit allowed repeat count based on
total memory needed.

gas/read.c

index 4f7420e4117b7f5a64c273f049ee2ff8681b2ae4..40804d44845ae880bdf611790040385e0efc32dd 100644 (file)
@@ -3200,12 +3200,9 @@ do_repeat (size_t count, const char *start, const char *end,
 {
   sb one;
   sb many;
-
-  if (count > 0x7fffffff)
-    {
-      as_bad (_("excessive count %zu for %s - ignored"), count, start);
-      count = 0;
-    }
+  size_t total, limit;
+  unsigned int line;
+  const char *file = as_where_top (&line);
 
   demand_empty_rest_of_line ();
   --input_line_pointer;
@@ -3220,6 +3217,14 @@ do_repeat (size_t count, const char *start, const char *end,
 
   sb_terminate (&one);
 
+  limit = (size_t) LONG_MAX < 0xffffffff ? (size_t) LONG_MAX : 0xffffffff;
+  if (gas_mul_overflow (count, one.len, &total) || total > limit)
+    {
+      as_bad_where (file, line,
+                   _("excessive count %zu for %s - ignored"), count, start);
+      count = 1;
+    }
+
   if (expander != NULL && !*expander && strstr (one.ptr, "\\+") != NULL)
     {
       /* The 3 here and below are arbitrary, added in an attempt to limit