mirror of
https://github.com/bminor/binutils-gdb.git
synced 2025-12-06 07:33:08 +00:00
PR22303, print_core_note out of bounds read
The print_core_note change here fixes the PR, the rest is making readelf a little more bombproof against maliciously crafted binaries. PR 22303 * readelf.c (print_core_note): Ensure "count" sanity check calculation doesn't overflow. (process_notes_at): Perform note namesz and descsz checks using unsigned comparisons against data remaining. Catch alignment overflow of namesz and descsz too. Don't allocate a temp for terminating "name" when there is space available before descdata.
This commit is contained in:
@@ -1,3 +1,14 @@
|
|||||||
|
2017-10-18 Alan Modra <amodra@gmail.com>
|
||||||
|
|
||||||
|
PR 22303
|
||||||
|
* readelf.c (print_core_note): Ensure "count" sanity check
|
||||||
|
calculation doesn't overflow.
|
||||||
|
(process_notes_at): Perform note namesz and descsz checks
|
||||||
|
using unsigned comparisons against data remaining. Catch
|
||||||
|
alignment overflow of namesz and descsz too. Don't allocate a
|
||||||
|
temp for terminating "name" when there is space available
|
||||||
|
before descdata.
|
||||||
|
|
||||||
2017-10-17 Tom Tromey <tom@tromey.com>
|
2017-10-17 Tom Tromey <tom@tromey.com>
|
||||||
|
|
||||||
* MAINTAINERS: Add myself as dwarf-mode.el maintainer.
|
* MAINTAINERS: Add myself as dwarf-mode.el maintainer.
|
||||||
|
|||||||
@@ -16335,7 +16335,8 @@ print_core_note (Elf_Internal_Note *pnote)
|
|||||||
page_size = byte_get (descdata, addr_size);
|
page_size = byte_get (descdata, addr_size);
|
||||||
descdata += addr_size;
|
descdata += addr_size;
|
||||||
|
|
||||||
if (pnote->descsz < 2 * addr_size + count * 3 * addr_size)
|
if (count > ((bfd_vma) -1 - 2 * addr_size) / (3 * addr_size)
|
||||||
|
|| pnote->descsz < 2 * addr_size + count * 3 * addr_size)
|
||||||
{
|
{
|
||||||
error (_(" Malformed note - too short for supplied file count\n"));
|
error (_(" Malformed note - too short for supplied file count\n"));
|
||||||
return FALSE;
|
return FALSE;
|
||||||
@@ -17658,20 +17659,13 @@ process_notes_at (FILE * file,
|
|||||||
(int) data_remaining);
|
(int) data_remaining);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
data_remaining -= min_notesz;
|
||||||
|
|
||||||
inote.type = BYTE_GET (external->type);
|
inote.type = BYTE_GET (external->type);
|
||||||
inote.namesz = BYTE_GET (external->namesz);
|
inote.namesz = BYTE_GET (external->namesz);
|
||||||
inote.namedata = external->name;
|
inote.namedata = external->name;
|
||||||
inote.descsz = BYTE_GET (external->descsz);
|
inote.descsz = BYTE_GET (external->descsz);
|
||||||
inote.descdata = inote.namedata + align_power (inote.namesz, 2);
|
inote.descdata = inote.namedata + align_power (inote.namesz, 2);
|
||||||
/* PR 17531: file: 3443835e. */
|
|
||||||
if (inote.descdata < (char *) pnotes || inote.descdata > end)
|
|
||||||
{
|
|
||||||
warn (_("Corrupt note: name size is too big: (got: %lx, expected no more than: %lx)\n"),
|
|
||||||
inote.namesz, (long)(end - inote.namedata));
|
|
||||||
inote.descdata = inote.namedata;
|
|
||||||
inote.namesz = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
inote.descpos = offset + (inote.descdata - (char *) pnotes);
|
inote.descpos = offset + (inote.descdata - (char *) pnotes);
|
||||||
next = inote.descdata + align_power (inote.descsz, 2);
|
next = inote.descdata + align_power (inote.descsz, 2);
|
||||||
}
|
}
|
||||||
@@ -17688,6 +17682,7 @@ process_notes_at (FILE * file,
|
|||||||
(int) data_remaining);
|
(int) data_remaining);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
data_remaining -= min_notesz;
|
||||||
|
|
||||||
vms_external = (Elf64_External_VMS_Note *) external;
|
vms_external = (Elf64_External_VMS_Note *) external;
|
||||||
inote.type = BYTE_GET (vms_external->type);
|
inote.type = BYTE_GET (vms_external->type);
|
||||||
@@ -17699,12 +17694,13 @@ process_notes_at (FILE * file,
|
|||||||
next = inote.descdata + align_power (inote.descsz, 3);
|
next = inote.descdata + align_power (inote.descsz, 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (inote.descdata < (char *) external + min_notesz
|
/* PR 17531: file: 3443835e. */
|
||||||
|| next < (char *) external + min_notesz
|
/* PR 17531: file: id:000000,sig:11,src:006986,op:havoc,rep:4. */
|
||||||
/* PR binutils/17531: file: id:000000,sig:11,src:006986,op:havoc,rep:4. */
|
if ((size_t) (inote.descdata - inote.namedata) < inote.namesz
|
||||||
|| inote.namedata + inote.namesz < inote.namedata
|
|| (size_t) (inote.descdata - inote.namedata) > data_remaining
|
||||||
|| inote.descdata + inote.descsz < inote.descdata
|
|| (size_t) (next - inote.descdata) < inote.descsz
|
||||||
|| data_remaining < (size_t)(next - (char *) external))
|
|| ((size_t) (next - inote.descdata)
|
||||||
|
> data_remaining - (size_t) (inote.descdata - inote.namedata)))
|
||||||
{
|
{
|
||||||
warn (_("note with invalid namesz and/or descsz found at offset 0x%lx\n"),
|
warn (_("note with invalid namesz and/or descsz found at offset 0x%lx\n"),
|
||||||
(unsigned long) ((char *) external - (char *) pnotes));
|
(unsigned long) ((char *) external - (char *) pnotes));
|
||||||
@@ -17721,19 +17717,20 @@ process_notes_at (FILE * file,
|
|||||||
namesz. */
|
namesz. */
|
||||||
if (inote.namedata[inote.namesz - 1] != '\0')
|
if (inote.namedata[inote.namesz - 1] != '\0')
|
||||||
{
|
{
|
||||||
temp = (char *) malloc (inote.namesz + 1);
|
if ((size_t) (inote.descdata - inote.namedata) == inote.namesz)
|
||||||
if (temp == NULL)
|
|
||||||
{
|
{
|
||||||
error (_("Out of memory allocating space for inote name\n"));
|
temp = (char *) malloc (inote.namesz + 1);
|
||||||
res = FALSE;
|
if (temp == NULL)
|
||||||
break;
|
{
|
||||||
|
error (_("Out of memory allocating space for inote name\n"));
|
||||||
|
res = FALSE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy (temp, inote.namedata, inote.namesz);
|
||||||
|
inote.namedata = temp;
|
||||||
}
|
}
|
||||||
|
inote.namedata[inote.namesz] = 0;
|
||||||
memcpy (temp, inote.namedata, inote.namesz);
|
|
||||||
temp[inote.namesz] = 0;
|
|
||||||
|
|
||||||
/* warn (_("'%s' NOTE name not properly null terminated\n"), temp); */
|
|
||||||
inote.namedata = temp;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (! process_note (& inote, file))
|
if (! process_note (& inote, file))
|
||||||
|
|||||||
Reference in New Issue
Block a user