aboutsummaryrefslogtreecommitdiff
path: root/gas
diff options
context:
space:
mode:
authorAlan Modra <amodra@gmail.com>2024-09-28 08:03:36 +0930
committerAlan Modra <amodra@gmail.com>2024-09-28 15:47:47 +0930
commiteb5903a8e268ac4615f9f96a8254b0b72f585e07 (patch)
tree4eda0fc0e54822a6f4704276159b1be876bdbb76 /gas
parentf6abafcd91fcdc63d301314c828989b39e061092 (diff)
downloadbinutils-eb5903a8e268ac4615f9f96a8254b0b72f585e07.zip
binutils-eb5903a8e268ac4615f9f96a8254b0b72f585e07.tar.gz
binutils-eb5903a8e268ac4615f9f96a8254b0b72f585e07.tar.bz2
gas buffer overflow with --listing-rhs-width
With listings enabled, gas keeps a small cache of source lines. They are stored in buffers of size LISTING_RHS_WIDTH, ie. 100. Given listing-rhs-width larger than 100 it is of course possible to overflow the buffer. Fix that by allocating as needed. We could allocate all buffers on the first call to print_source using listing_rhs_width, but I chose not to do that in case some future assembly directive allows changes to listing_rhs_width similarly to the way paper_width can change during assembly.
Diffstat (limited to 'gas')
-rw-r--r--gas/listing.c23
1 files changed, 18 insertions, 5 deletions
diff --git a/gas/listing.c b/gas/listing.c
index ef17980..23f76a7 100644
--- a/gas/listing.c
+++ b/gas/listing.c
@@ -1026,12 +1026,25 @@ list_symbol_table (void)
typedef struct cached_line
{
- file_info_type * file;
- unsigned int line;
- char buffer [LISTING_RHS_WIDTH];
+ file_info_type *file;
+ unsigned int line;
+ unsigned int bufsize;
+ char *buffer;
} cached_line;
static void
+alloc_cache (cached_line *cache, unsigned int width)
+{
+ if (cache->bufsize < width)
+ {
+ cache->bufsize = width;
+ free (cache->buffer);
+ cache->buffer = xmalloc (width);
+ }
+ cache->buffer[0] = 0;
+}
+
+static void
print_source (file_info_type * current_file,
list_info_type * list,
unsigned int width)
@@ -1080,7 +1093,7 @@ print_source (file_info_type * current_file,
cache->file = current_file;
cache->line = list->hll_line;
- cache->buffer[0] = 0;
+ alloc_cache (cache, width);
rebuffer_line (current_file, cache->line, cache->buffer, width);
}
@@ -1101,7 +1114,7 @@ print_source (file_info_type * current_file,
cache = cached_lines + next_free_line;
cache->file = current_file;
cache->line = current_file->linenum + 1;
- cache->buffer[0] = 0;
+ alloc_cache (cache, width);
p = buffer_line (current_file, cache->buffer, width);
/* Cache optimization: If printing a group of lines