diff options
author | Alan Modra <amodra@gmail.com> | 2024-09-28 08:03:36 +0930 |
---|---|---|
committer | Alan Modra <amodra@gmail.com> | 2024-09-28 15:47:47 +0930 |
commit | eb5903a8e268ac4615f9f96a8254b0b72f585e07 (patch) | |
tree | 4eda0fc0e54822a6f4704276159b1be876bdbb76 /gas | |
parent | f6abafcd91fcdc63d301314c828989b39e061092 (diff) | |
download | binutils-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.c | 23 |
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 |