--- /dev/null
+#!/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),
+