gas crash on unreasonably long lines

Nathan Sidwell nathan@acm.org
Wed Nov 2 22:39:00 GMT 2016


We encountered a gas segfault when assembling some C++ code that had a 
monstrous mangled name.  While I convinced the author to change their 
C++, it'd be nice if the assembler didn't blow up.

g++ was generating a mangled name of some 590K characters, and thus 
ending up with source lines of that order of magnitude.  However:

1) the buffer reading code presumed size_t, int and unsigned were all 
interchangeable types.  Fixed by using size_t consistently.

2) the 'buffer_length' global var was used for two different purposes:
   (a) holding the length of (approximately) half of the input buffer
   (b) indicating how many chars file_give_next_buffer would read.
But F_G_N_B (now?) always reads input_file_buffer_size() bytes (32K), 
and the former meaning is just crazy.  Fixed by having it hold the 
buffer length sans BEFORE and AFTER counts.

3) The buffer expansion code was just confused.  It would add another 
input buffer's worth of chars, but then double that.  This eventually 
led to the observed segfault when doubling 2GB to zero (remember, it was 
incorrectly using a plain int).  We were calling realloc every time 
round the 'read more chars' loop - even if it was already long enough. 
When the seg fault happened, the input line was 'only' around 500K. 
Fixed by using the usual doubling idiom, and only when there's fewer 
than I_F_B_S() bytes available.  So we call realloc much less often.

4) to top it all off, the code that scanned the just-read block looking 
for a newline, actually scanned the whole input buffer.  Even though a 
\n could only be in the newly read bit.  Fixed this O(N^2) behaviour by 
just scanning the newly read chars.

I attempted to reduce the 6GB testcase, but could only get it down to 
about 2GB.  I think this impractical for the testsuite.

ok?

nathan
-- 
Nathan Sidwell
-------------- next part --------------
A non-text attachment was scrubbed...
Name: gas-input-len.patch
Type: text/x-patch
Size: 6029 bytes
Desc: not available
URL: <https://sourceware.org/pipermail/binutils/attachments/20161102/c3ee2d46/attachment.bin>


More information about the Binutils mailing list