forked from Imagelibrary/binutils-gdb
windres: buffer overflow in bin_to_res_toolbar
oss-fuzz testcase manages to hit a buffer overflow. Sanity check by passing the buffer length to bin_to_res_toolbar and ensuring reads don't go off the end of the buffer.
This commit is contained in:
@@ -54,7 +54,7 @@ static rc_res_resource *bin_to_res_group_cursor (windres_bfd *, const bfd_byte *
|
|||||||
static rc_res_resource *bin_to_res_group_icon (windres_bfd *, const bfd_byte *, rc_uint_type);
|
static rc_res_resource *bin_to_res_group_icon (windres_bfd *, const bfd_byte *, rc_uint_type);
|
||||||
static rc_res_resource *bin_to_res_version (windres_bfd *, const bfd_byte *, rc_uint_type);
|
static rc_res_resource *bin_to_res_version (windres_bfd *, const bfd_byte *, rc_uint_type);
|
||||||
static rc_res_resource *bin_to_res_userdata (windres_bfd *, const bfd_byte *, rc_uint_type);
|
static rc_res_resource *bin_to_res_userdata (windres_bfd *, const bfd_byte *, rc_uint_type);
|
||||||
static rc_res_resource *bin_to_res_toolbar (windres_bfd *, const bfd_byte *);
|
static rc_res_resource *bin_to_res_toolbar (windres_bfd *, const bfd_byte *, rc_uint_type);
|
||||||
static void get_version_header (windres_bfd *, const bfd_byte *, rc_uint_type, const char *,
|
static void get_version_header (windres_bfd *, const bfd_byte *, rc_uint_type, const char *,
|
||||||
unichar **, rc_uint_type *, rc_uint_type *, rc_uint_type *,
|
unichar **, rc_uint_type *, rc_uint_type *, rc_uint_type *,
|
||||||
rc_uint_type *);
|
rc_uint_type *);
|
||||||
@@ -105,7 +105,7 @@ bin_to_res (windres_bfd *wrbfd, rc_res_id type, const bfd_byte *data,
|
|||||||
case RT_VERSION:
|
case RT_VERSION:
|
||||||
return bin_to_res_version (wrbfd, data, length);
|
return bin_to_res_version (wrbfd, data, length);
|
||||||
case RT_TOOLBAR:
|
case RT_TOOLBAR:
|
||||||
return bin_to_res_toolbar (wrbfd, data);
|
return bin_to_res_toolbar (wrbfd, data, length);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1216,12 +1216,15 @@ bin_to_res_userdata (windres_bfd *wrbfd ATTRIBUTE_UNUSED, const bfd_byte *data,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static rc_res_resource *
|
static rc_res_resource *
|
||||||
bin_to_res_toolbar (windres_bfd *wrbfd, const bfd_byte *data)
|
bin_to_res_toolbar (windres_bfd *wrbfd, const bfd_byte *data,
|
||||||
|
rc_uint_type length)
|
||||||
{
|
{
|
||||||
rc_toolbar *ri;
|
rc_toolbar *ri;
|
||||||
rc_res_resource *r;
|
rc_res_resource *r;
|
||||||
rc_uint_type i;
|
rc_uint_type i;
|
||||||
|
|
||||||
|
if (length < 12)
|
||||||
|
toosmall (_("toolbar"));
|
||||||
ri = (rc_toolbar *) res_alloc (sizeof (rc_toolbar));
|
ri = (rc_toolbar *) res_alloc (sizeof (rc_toolbar));
|
||||||
ri->button_width = windres_get_32 (wrbfd, data, 4);
|
ri->button_width = windres_get_32 (wrbfd, data, 4);
|
||||||
ri->button_height = windres_get_32 (wrbfd, data + 4, 4);
|
ri->button_height = windres_get_32 (wrbfd, data + 4, 4);
|
||||||
@@ -1229,14 +1232,18 @@ bin_to_res_toolbar (windres_bfd *wrbfd, const bfd_byte *data)
|
|||||||
ri->items = NULL;
|
ri->items = NULL;
|
||||||
|
|
||||||
data += 12;
|
data += 12;
|
||||||
for (i=0 ; i < ri->nitems; i++)
|
length -= 12;
|
||||||
|
for (i = 0; i < ri->nitems; i++)
|
||||||
{
|
{
|
||||||
rc_toolbar_item *it;
|
rc_toolbar_item *it;
|
||||||
it = (rc_toolbar_item *) res_alloc (sizeof (rc_toolbar_item));
|
it = (rc_toolbar_item *) res_alloc (sizeof (rc_toolbar_item));
|
||||||
it->id.named = 0;
|
it->id.named = 0;
|
||||||
|
if (length < 4)
|
||||||
|
toosmall (_("toolbar item"));
|
||||||
it->id.u.id = (int) windres_get_32 (wrbfd, data, 4);
|
it->id.u.id = (int) windres_get_32 (wrbfd, data, 4);
|
||||||
it->prev = it->next = NULL;
|
it->prev = it->next = NULL;
|
||||||
data += 4;
|
data += 4;
|
||||||
|
length -= 4;
|
||||||
if(ri->items) {
|
if(ri->items) {
|
||||||
rc_toolbar_item *ii = ri->items;
|
rc_toolbar_item *ii = ri->items;
|
||||||
while (ii->next != NULL)
|
while (ii->next != NULL)
|
||||||
|
|||||||
Reference in New Issue
Block a user