This is the mail archive of the gdb-cvs@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[binutils-gdb/gdb-7.9-branch] Fix internal error when core file section is too big


https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=3b7a39661610038aad32563069b10fb2cfc55fab

commit 3b7a39661610038aad32563069b10fb2cfc55fab
Author: Andreas Arnez <arnez@linux.vnet.ibm.com>
Date:   Wed Jan 14 12:01:38 2015 +0000

    Fix internal error when core file section is too big
    
    As reported in PR 17808, a test case with a forged (invalid) core file
    can crash GDB with an assertion failure.  In that particular case the
    prstatus of an i386 core file looks like that from an AMD64 core file.
    Consequently the respective regset supply function i386_supply_gregset
    is invoked with a larger buffer than usual.  But i386_supply_gregset
    asserts a specific buffer size, and this assertion fails.
    
    The patch relaxes all buffer size assertions in regset supply
    functions such that they merely check for a sufficiently large buffer.
    For consistency the regset collect functions are adjusted as well.
    
    gdb/ChangeLog:
    
    	PR corefiles/17808:
    	* gdbarch.sh (iterate_over_regset_sections_cb): Document this
    	function type, particularly its SIZE parameter.
    	* gdbarch.h: Regenerate.
    	* amd64-tdep.c (amd64_supply_fpregset): In gdb_assert, compare
    	actual against required size using ">=" instead of "==".
    	(amd64_collect_fpregset): Likewise.
    	* i386-tdep.c (i386_supply_gregset): Likewise.
    	(i386_collect_gregset): Likewise.
    	(i386_supply_fpregset): Likewise.
    	(i386_collect_fpregset): Likewise.
    	* mips-linux-tdep.c (mips_supply_gregset_wrapper): Likewise.
    	(mips_fill_gregset_wrapper): Likewise.
    	(mips_supply_fpregset_wrapper): Likewise.
    	(mips_fill_fpregset_wrapper): Likewise.
    	(mips64_supply_gregset_wrapper): Likewise.
    	(mips64_fill_gregset_wrapper): Likewise.
    	(mips64_supply_fpregset_wrapper): Likewise.
    	(mips64_fill_fpregset_wrapper): Likewise.
    	* mn10300-linux-tdep.c (am33_supply_gregset_method): Likewise.
    	(am33_supply_fpregset_method): Likewise.
    	(am33_collect_gregset_method): Likewise.
    	(am33_collect_fpregset_method): Likewise.

Diff:
---
 gdb/ChangeLog            | 26 ++++++++++++++++++++++++++
 gdb/amd64-tdep.c         |  4 ++--
 gdb/gdbarch.h            |  6 ++++++
 gdb/gdbarch.sh           |  6 ++++++
 gdb/i386-tdep.c          |  8 ++++----
 gdb/mips-linux-tdep.c    | 16 ++++++++--------
 gdb/mn10300-linux-tdep.c |  8 ++++----
 7 files changed, 56 insertions(+), 18 deletions(-)

diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 4fc8c2d..ad032ba 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,3 +1,29 @@
+2015-02-20  Andreas Arnez  <arnez@linux.vnet.ibm.com>
+
+	PR corefiles/17808:
+	* gdbarch.sh (iterate_over_regset_sections_cb): Document this
+	function type, particularly its SIZE parameter.
+	* gdbarch.h: Regenerate.
+	* amd64-tdep.c (amd64_supply_fpregset): In gdb_assert, compare
+	actual against required size using ">=" instead of "==".
+	(amd64_collect_fpregset): Likewise.
+	* i386-tdep.c (i386_supply_gregset): Likewise.
+	(i386_collect_gregset): Likewise.
+	(i386_supply_fpregset): Likewise.
+	(i386_collect_fpregset): Likewise.
+	* mips-linux-tdep.c (mips_supply_gregset_wrapper): Likewise.
+	(mips_fill_gregset_wrapper): Likewise.
+	(mips_supply_fpregset_wrapper): Likewise.
+	(mips_fill_fpregset_wrapper): Likewise.
+	(mips64_supply_gregset_wrapper): Likewise.
+	(mips64_fill_gregset_wrapper): Likewise.
+	(mips64_supply_fpregset_wrapper): Likewise.
+	(mips64_fill_fpregset_wrapper): Likewise.
+	* mn10300-linux-tdep.c (am33_supply_gregset_method): Likewise.
+	(am33_supply_fpregset_method): Likewise.
+	(am33_collect_gregset_method): Likewise.
+	(am33_collect_fpregset_method): Likewise.
+
 2015-02-19  Joel Brobecker  <brobecker@adacore.com>
 
 	* version.in: Set GDB version number to 7.9.
diff --git a/gdb/amd64-tdep.c b/gdb/amd64-tdep.c
index fa658de..a661b88 100644
--- a/gdb/amd64-tdep.c
+++ b/gdb/amd64-tdep.c
@@ -2854,7 +2854,7 @@ amd64_supply_fpregset (const struct regset *regset, struct regcache *regcache,
   struct gdbarch *gdbarch = get_regcache_arch (regcache);
   const struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
 
-  gdb_assert (len == tdep->sizeof_fpregset);
+  gdb_assert (len >= tdep->sizeof_fpregset);
   amd64_supply_fxsave (regcache, regnum, fpregs);
 }
 
@@ -2871,7 +2871,7 @@ amd64_collect_fpregset (const struct regset *regset,
   struct gdbarch *gdbarch = get_regcache_arch (regcache);
   const struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
 
-  gdb_assert (len == tdep->sizeof_fpregset);
+  gdb_assert (len >= tdep->sizeof_fpregset);
   amd64_collect_fxsave (regcache, regnum, fpregs);
 }
 
diff --git a/gdb/gdbarch.h b/gdb/gdbarch.h
index b266530..b67d9f6 100644
--- a/gdb/gdbarch.h
+++ b/gdb/gdbarch.h
@@ -85,6 +85,12 @@ extern struct gdbarch *target_gdbarch (void);
 typedef int (iterate_over_objfiles_in_search_order_cb_ftype)
   (struct objfile *objfile, void *cb_data);
 
+/* Callback type for regset section iterators.  The callback usually
+   invokes the REGSET's supply or collect method, to which it must
+   pass a buffer with at least the given SIZE.  SECT_NAME is a BFD
+   section name, and HUMAN_NAME is used for diagnostic messages.
+   CB_DATA should have been passed unchanged through the iterator.  */
+
 typedef void (iterate_over_regset_sections_cb)
   (const char *sect_name, int size, const struct regset *regset,
    const char *human_name, void *cb_data);
diff --git a/gdb/gdbarch.sh b/gdb/gdbarch.sh
index e12b8b0..cffefc5 100755
--- a/gdb/gdbarch.sh
+++ b/gdb/gdbarch.sh
@@ -1239,6 +1239,12 @@ extern struct gdbarch *target_gdbarch (void);
 typedef int (iterate_over_objfiles_in_search_order_cb_ftype)
   (struct objfile *objfile, void *cb_data);
 
+/* Callback type for regset section iterators.  The callback usually
+   invokes the REGSET's supply or collect method, to which it must
+   pass a buffer with at least the given SIZE.  SECT_NAME is a BFD
+   section name, and HUMAN_NAME is used for diagnostic messages.
+   CB_DATA should have been passed unchanged through the iterator.  */
+
 typedef void (iterate_over_regset_sections_cb)
   (const char *sect_name, int size, const struct regset *regset,
    const char *human_name, void *cb_data);
diff --git a/gdb/i386-tdep.c b/gdb/i386-tdep.c
index 7d174c4..1c8842c 100644
--- a/gdb/i386-tdep.c
+++ b/gdb/i386-tdep.c
@@ -3727,7 +3727,7 @@ i386_supply_gregset (const struct regset *regset, struct regcache *regcache,
   const gdb_byte *regs = gregs;
   int i;
 
-  gdb_assert (len == tdep->sizeof_gregset);
+  gdb_assert (len >= tdep->sizeof_gregset);
 
   for (i = 0; i < tdep->gregset_num_regs; i++)
     {
@@ -3752,7 +3752,7 @@ i386_collect_gregset (const struct regset *regset,
   gdb_byte *regs = gregs;
   int i;
 
-  gdb_assert (len == tdep->sizeof_gregset);
+  gdb_assert (len >= tdep->sizeof_gregset);
 
   for (i = 0; i < tdep->gregset_num_regs; i++)
     {
@@ -3779,7 +3779,7 @@ i386_supply_fpregset (const struct regset *regset, struct regcache *regcache,
       return;
     }
 
-  gdb_assert (len == tdep->sizeof_fpregset);
+  gdb_assert (len >= tdep->sizeof_fpregset);
   i387_supply_fsave (regcache, regnum, fpregs);
 }
 
@@ -3802,7 +3802,7 @@ i386_collect_fpregset (const struct regset *regset,
       return;
     }
 
-  gdb_assert (len == tdep->sizeof_fpregset);
+  gdb_assert (len >= tdep->sizeof_fpregset);
   i387_collect_fsave (regcache, regnum, fpregs);
 }
 
diff --git a/gdb/mips-linux-tdep.c b/gdb/mips-linux-tdep.c
index 5239c37..fe45dcc 100644
--- a/gdb/mips-linux-tdep.c
+++ b/gdb/mips-linux-tdep.c
@@ -163,7 +163,7 @@ mips_supply_gregset_wrapper (const struct regset *regset,
 			     struct regcache *regcache,
 			     int regnum, const void *gregs, size_t len)
 {
-  gdb_assert (len == sizeof (mips_elf_gregset_t));
+  gdb_assert (len >= sizeof (mips_elf_gregset_t));
 
   mips_supply_gregset (regcache, (const mips_elf_gregset_t *)gregs);
 }
@@ -231,7 +231,7 @@ mips_fill_gregset_wrapper (const struct regset *regset,
 			   const struct regcache *regcache,
 			   int regnum, void *gregs, size_t len)
 {
-  gdb_assert (len == sizeof (mips_elf_gregset_t));
+  gdb_assert (len >= sizeof (mips_elf_gregset_t));
 
   mips_fill_gregset (regcache, (mips_elf_gregset_t *)gregs, regnum);
 }
@@ -268,7 +268,7 @@ mips_supply_fpregset_wrapper (const struct regset *regset,
 			      struct regcache *regcache,
 			      int regnum, const void *gregs, size_t len)
 {
-  gdb_assert (len == sizeof (mips_elf_fpregset_t));
+  gdb_assert (len >= sizeof (mips_elf_fpregset_t));
 
   mips_supply_fpregset (regcache, (const mips_elf_fpregset_t *)gregs);
 }
@@ -311,7 +311,7 @@ mips_fill_fpregset_wrapper (const struct regset *regset,
 			    const struct regcache *regcache,
 			    int regnum, void *gregs, size_t len)
 {
-  gdb_assert (len == sizeof (mips_elf_fpregset_t));
+  gdb_assert (len >= sizeof (mips_elf_fpregset_t));
 
   mips_fill_fpregset (regcache, (mips_elf_fpregset_t *)gregs, regnum);
 }
@@ -413,7 +413,7 @@ mips64_supply_gregset_wrapper (const struct regset *regset,
 			       struct regcache *regcache,
 			       int regnum, const void *gregs, size_t len)
 {
-  gdb_assert (len == sizeof (mips64_elf_gregset_t));
+  gdb_assert (len >= sizeof (mips64_elf_gregset_t));
 
   mips64_supply_gregset (regcache, (const mips64_elf_gregset_t *)gregs);
 }
@@ -484,7 +484,7 @@ mips64_fill_gregset_wrapper (const struct regset *regset,
 			     const struct regcache *regcache,
 			     int regnum, void *gregs, size_t len)
 {
-  gdb_assert (len == sizeof (mips64_elf_gregset_t));
+  gdb_assert (len >= sizeof (mips64_elf_gregset_t));
 
   mips64_fill_gregset (regcache, (mips64_elf_gregset_t *)gregs, regnum);
 }
@@ -533,7 +533,7 @@ mips64_supply_fpregset_wrapper (const struct regset *regset,
 				struct regcache *regcache,
 				int regnum, const void *gregs, size_t len)
 {
-  gdb_assert (len == sizeof (mips64_elf_fpregset_t));
+  gdb_assert (len >= sizeof (mips64_elf_fpregset_t));
 
   mips64_supply_fpregset (regcache, (const mips64_elf_fpregset_t *)gregs);
 }
@@ -611,7 +611,7 @@ mips64_fill_fpregset_wrapper (const struct regset *regset,
 			      const struct regcache *regcache,
 			      int regnum, void *gregs, size_t len)
 {
-  gdb_assert (len == sizeof (mips64_elf_fpregset_t));
+  gdb_assert (len >= sizeof (mips64_elf_fpregset_t));
 
   mips64_fill_fpregset (regcache, (mips64_elf_fpregset_t *)gregs, regnum);
 }
diff --git a/gdb/mn10300-linux-tdep.c b/gdb/mn10300-linux-tdep.c
index d92e93d..9ac6c15 100644
--- a/gdb/mn10300-linux-tdep.c
+++ b/gdb/mn10300-linux-tdep.c
@@ -90,7 +90,7 @@ am33_supply_gregset_method (const struct regset *regset,
   const mn10300_elf_greg_t *regp = (const mn10300_elf_greg_t *) gregs;
   int i;
 
-  gdb_assert (len == sizeof (mn10300_elf_gregset_t));
+  gdb_assert (len >= sizeof (mn10300_elf_gregset_t));
 
   switch (regnum) {
   case E_D0_REGNUM:
@@ -245,7 +245,7 @@ am33_supply_fpregset_method (const struct regset *regset,
 {
   const mn10300_elf_fpregset_t *fpregset = fpregs;
 
-  gdb_assert (len == sizeof (mn10300_elf_fpregset_t));
+  gdb_assert (len >= sizeof (mn10300_elf_fpregset_t));
 
   if (regnum == -1)
     {
@@ -278,7 +278,7 @@ am33_collect_gregset_method (const struct regset *regset,
   mn10300_elf_gregset_t *regp = gregs;
   int i;
 
-  gdb_assert (len == sizeof (mn10300_elf_gregset_t));
+  gdb_assert (len >= sizeof (mn10300_elf_gregset_t));
 
   switch (regnum) {
   case E_D0_REGNUM:
@@ -425,7 +425,7 @@ am33_collect_fpregset_method (const struct regset *regset,
 {
   mn10300_elf_fpregset_t *fpregset = fpregs;
 
-  gdb_assert (len == sizeof (mn10300_elf_fpregset_t));
+  gdb_assert (len >= sizeof (mn10300_elf_fpregset_t));
 
   if (regnum == -1)
     {


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]