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:
Alan Modra
2025-04-14 10:31:32 +09:30
parent a4224b4ce1
commit 4846e543de

View File

@@ -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_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_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 *,
unichar **, 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:
return bin_to_res_version (wrbfd, data, length);
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 *
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_res_resource *r;
rc_uint_type i;
if (length < 12)
toosmall (_("toolbar"));
ri = (rc_toolbar *) res_alloc (sizeof (rc_toolbar));
ri->button_width = windres_get_32 (wrbfd, data, 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;
data += 12;
for (i=0 ; i < ri->nitems; i++)
length -= 12;
for (i = 0; i < ri->nitems; i++)
{
rc_toolbar_item *it;
it = (rc_toolbar_item *) res_alloc (sizeof (rc_toolbar_item));
it->id.named = 0;
if (length < 4)
toosmall (_("toolbar item"));
it->id.u.id = (int) windres_get_32 (wrbfd, data, 4);
it->prev = it->next = NULL;
data += 4;
length -= 4;
if(ri->items) {
rc_toolbar_item *ii = ri->items;
while (ii->next != NULL)