#!/bin/sh -e ## 312_pr5011.dpatch ## ## DP: Description: Fix PR binutils/5011 ## DP: Upstream status: CVS head 20070908 if [ $# -ne 1 ]; then echo >&2 "`basename $0`: script expects -patch|-unpatch as argument" exit 1 fi [ -f debian/patches/00patch-opts ] && . debian/patches/00patch-opts patch_opts="${patch_opts:--f --no-backup-if-mismatch}" case "$1" in -patch) patch $patch_opts -p1 < $0;; -unpatch) patch $patch_opts -p1 -R < $0;; *) echo >&2 "`basename $0`: script expects -patch|-unpatch as argument" exit 1;; esac exit 0 PR binutils/5011 * readelf.c (process_version_sections): Don't read past end of various section buffers. @DPATCH@ Index: ./binutils/readelf.c =================================================================== RCS file: /cvs/src/src/binutils/readelf.c,v retrieving revision 1.376 diff -u -p -r1.376 readelf.c --- ./binutils/readelf.c 30 Aug 2007 13:47:35 -0000 1.376 +++ ./binutils/readelf.c 10 Sep 2007 08:59:40 -0000 @@ -6454,6 +6454,7 @@ process_version_sections (FILE *file) Elf_External_Verdef *edefs; unsigned int idx; unsigned int cnt; + char *endbuf; found = 1; @@ -6473,6 +6474,7 @@ process_version_sections (FILE *file) edefs = get_data (NULL, file, section->sh_offset, 1, section->sh_size, _("version definition section")); + endbuf = (char *) edefs + section->sh_size; if (!edefs) break; @@ -6487,6 +6489,8 @@ process_version_sections (FILE *file) int isum; vstart = ((char *) edefs) + idx; + if (vstart + sizeof (*edef) > endbuf) + break; edef = (Elf_External_Verdef *) vstart; @@ -6524,6 +6528,8 @@ process_version_sections (FILE *file) vstart += aux.vda_next; eaux = (Elf_External_Verdaux *) vstart; + if (vstart + sizeof (*eaux) > endbuf) + break; aux.vda_name = BYTE_GET (eaux->vda_name); aux.vda_next = BYTE_GET (eaux->vda_next); @@ -6535,9 +6541,13 @@ process_version_sections (FILE *file) printf (_(" %#06x: Parent %d, name index: %ld\n"), isum, j, aux.vda_name); } + if (j < ent.vd_cnt) + printf (_(" Version def aux past end of section\n")); idx += ent.vd_next; } + if (cnt < section->sh_info) + printf (_(" Version definition past end of section\n")); free (edefs); } @@ -6548,6 +6558,7 @@ process_version_sections (FILE *file) Elf_External_Verneed *eneed; unsigned int idx; unsigned int cnt; + char *endbuf; found = 1; @@ -6566,6 +6577,7 @@ process_version_sections (FILE *file) eneed = get_data (NULL, file, section->sh_offset, 1, section->sh_size, _("version need section")); + endbuf = (char *) eneed + section->sh_size; if (!eneed) break; @@ -6578,6 +6590,8 @@ process_version_sections (FILE *file) char *vstart; vstart = ((char *) eneed) + idx; + if (vstart + sizeof (*entry) > endbuf) + break; entry = (Elf_External_Verneed *) vstart; @@ -6603,6 +6617,8 @@ process_version_sections (FILE *file) Elf_External_Vernaux *eaux; Elf_Internal_Vernaux aux; + if (vstart + sizeof (*eaux) > endbuf) + break; eaux = (Elf_External_Vernaux *) vstart; aux.vna_hash = BYTE_GET (eaux->vna_hash); @@ -6624,9 +6640,13 @@ process_version_sections (FILE *file) isum += aux.vna_next; vstart += aux.vna_next; } + if (j < ent.vn_cnt) + printf (_(" Version need aux past end of section\n")); idx += ent.vn_next; } + if (cnt < section->sh_info) + printf (_(" Version need past end of section\n")); free (eneed); } @@ -6771,7 +6791,10 @@ process_version_sections (FILE *file) { ivna.vna_name = BYTE_GET (evna.vna_name); - name = strtab + ivna.vna_name; + if (ivna.vna_name >= string_sec->sh_size) + name = _("*invalid*"); + else + name = strtab + ivna.vna_name; nn += printf ("(%s%-*s", name, 12 - (int) strlen (name), @@ -6823,7 +6846,10 @@ process_version_sections (FILE *file) ivda.vda_name = BYTE_GET (evda.vda_name); - name = strtab + ivda.vda_name; + if (ivda.vda_name >= string_sec->sh_size) + name = _("*invalid*"); + else + name = strtab + ivda.vda_name; nn += printf ("(%s%-*s", name, 12 - (int) strlen (name),