diff options
author | Alan Modra <amodra@gmail.com> | 2025-04-14 10:31:32 +0930 |
---|---|---|
committer | Alan Modra <amodra@gmail.com> | 2025-04-15 06:59:15 +0930 |
commit | 4846e543de9543bff001f58d6a47097e0edd588d (patch) | |
tree | 7752e1619ee89f71a1f1d58fbd5dfb4e21e14528 /binutils/resbin.c | |
parent | a4224b4ce14224ff81bd70f134254a088aca3931 (diff) | |
download | binutils-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.c | 15 |
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) |