Fix internal error when core file section is too big
authorAndreas Arnez <arnez@linux.vnet.ibm.com>
Wed, 14 Jan 2015 12:01:38 +0000 (12:01 +0000)
committerUlrich Weigand <ulrich.weigand@de.ibm.com>
Wed, 4 Feb 2015 13:14:31 +0000 (14:14 +0100)
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.

gdb/ChangeLog
gdb/amd64-tdep.c
gdb/gdbarch.h
gdb/gdbarch.sh
gdb/i386-tdep.c
gdb/mips-linux-tdep.c
gdb/mn10300-linux-tdep.c

index d5ec6d1617e1d31cb8d268f0efbd77d81d83606f..a2cc9a5a3228ab2021bd5f3ca20415d321e04761 100644 (file)
@@ -1,3 +1,29 @@
+2015-02-04  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-04  Doug Evans  <dje@google.com>
            Pedro Alves  <palves@redhat.com>
            Eli Zaretskii  <eliz@gnu.org>
index fa658ded40db88afeec2312d97090d9ac1784c99..a661b8831b4fecf11af5a0b5de699e1901c084ee 100644 (file)
@@ -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);
 }
 
index b2665305c9147b5924b1ae5a055ae9c21e67e911..b67d9f69d3168c3962715e5ca3fbc31987ba2e03 100644 (file)
@@ -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);
index e12b8b0c04e5d6d4924a5a181b624a2e2fb21622..cffefc5fbf3bfc2439c216c3152a836b2ab6cc81 100755 (executable)
@@ -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);
index 7d174c4ce1e82e2e635c975dde7bfe3f6d703057..1c8842c42c1ae1b2eed68ff63c8e2b0f3cf40a95 100644 (file)
@@ -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);
 }
 
index 5239c3787c08aa77dd47878e3e8c3c368087da6c..fe45dcc3bdbca8ddd6225346fa1331e5d0c7c69a 100644 (file)
@@ -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);
 }
index d92e93d346139c438c863e58a12773631ef68819..9ac6c15e6d9c2a43dc4ee0e1d72b172b37b3db17 100644 (file)
@@ -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)
     {