From: Alan Modra Date: Mon, 16 Feb 2026 23:27:52 +0000 (+1030) Subject: gas: further limit .rept count X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=dd2a080f6e1a144779a8a9dc9c107293d1fdad77;p=thirdparty%2Fbinutils-gdb.git gas: further limit .rept count 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. --- diff --git a/gas/read.c b/gas/read.c index 4f7420e4117..40804d44845 100644 --- a/gas/read.c +++ b/gas/read.c @@ -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