aboutsummaryrefslogtreecommitdiff
path: root/binutils/resbin.c
diff options
context:
space:
mode:
authorAlan Modra <amodra@gmail.com>2025-04-14 10:31:32 +0930
committerAlan Modra <amodra@gmail.com>2025-04-15 06:59:15 +0930
commit4846e543de9543bff001f58d6a47097e0edd588d (patch)
tree7752e1619ee89f71a1f1d58fbd5dfb4e21e14528 /binutils/resbin.c
parenta4224b4ce14224ff81bd70f134254a088aca3931 (diff)
downloadbinutils-4846e543de9543bff001f58d6a47097e0edd588d.zip
binutils-4846e543de9543bff001f58d6a47097e0edd588d.tar.gz
binutils-4846e543de9543bff001f58d6a47097e0edd588d.tar.bz2
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.
Diffstat (limited to 'binutils/resbin.c')
-rw-r--r--binutils/resbin.c15
1 files changed, 11 insertions, 4 deletions
diff --git a/binutils/resbin.c b/binutils/resbin.c
index 388b016..a42a846 100644
--- a/binutils/resbin.c
+++ b/binutils/resbin.c
@@ -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)