[PATCH] Fix tekhex (take 2)
Jakub Jelinek
jakub@redhat.com
Thu Jan 4 18:51:00 GMT 2007
Hi!
Additionally I found if the first hex number (2 hex digits after %) are
smaller than 5, the buffer could be overflown. Before the patch I posted
it would overflow the buffer and if that call returned, abort (), but with
that patch it could go on and segfault or be exploited.
Sample input where this happens:
%016C6480004E56FFFC4E717063B0AEFFFC6D0652AEFFFC60F24E5E4E752109481290842190421111111414323333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333
Well, even the current version could overflow without hitting the abort
%right after it, say when
%016C6 is followed by 4GB of arbitrary data on a 64-bit host.
Here is an updated version, ok?
2007-01-04 Jakub Jelinek <jakub@redhat.com>
* texhex.c (first_phase): Don't fall through into the default
case.
(pass_over): Replace abort () calls with return FALSE. Fix
buffer overflow.
--- bfd/tekhex.c.jj 2006-06-19 15:17:43.000000000 +0200
+++ bfd/tekhex.c 2007-01-04 19:40:39.000000000 +0100
@@ -436,6 +436,7 @@ first_phase (bfd *abfd, int type, char *
if (!getvalue (&src, &val))
return FALSE;
new->symbol.value = val - section->vma;
+ break;
}
default:
return FALSE;
@@ -457,7 +458,7 @@ pass_over (bfd *abfd, bfd_boolean (*func
/* To the front of the file. */
if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0)
- abort ();
+ return FALSE;
while (! eof)
{
char buffer[MAXCHUNK];
@@ -471,22 +472,24 @@ pass_over (bfd *abfd, bfd_boolean (*func
if (eof)
break;
- src++;
/* Fetch the type and the length and the checksum. */
if (bfd_bread (src, (bfd_size_type) 5, abfd) != 5)
- abort (); /* FIXME. */
+ return FALSE;
type = src[2];
if (!ISHEX (src[0]) || !ISHEX (src[1]))
break;
- /* Already read five char. */
+ /* Already read five chars. */
chars_on_line = HEX (src) - 5;
+ if (chars_on_line >= MAXCHUNK)
+ return FALSE;
+
if (bfd_bread (src, (bfd_size_type) chars_on_line, abfd) != chars_on_line)
- abort (); /* FIXME. */
+ return FALSE;
/* Put a null at the end. */
src[chars_on_line] = 0;
Jakub
More information about the Binutils
mailing list