public inbox for gdb-patches@sourceware.org
 help / color / mirror / Atom feed
* [PATCH] [gdb/symtab] Fix overly large gdb-index file check for 32-bit
@ 2023-09-15  9:08 Tom de Vries
  2023-09-15 21:38 ` Kevin Buettner
  0 siblings, 1 reply; 2+ messages in thread
From: Tom de Vries @ 2023-09-15  9:08 UTC (permalink / raw)
  To: gdb-patches; +Cc: Kevin Buettner

Add a unit test which checks that write_gdb_index_1 will throw
an error when the size of the file would exceed the maximum value
capable of being represented by 'offset_type'.

The unit test fails on 32-bit systems due to wrapping overflow.  Fix this by
changing the type of total_len in write_gdbindex_1 from size_t to uint64_t.

Tested on x86_64-linux.

Co-Authored-By: Kevin Buettner <kevinb@redhat.com>
---
 gdb/dwarf2/index-write.c | 84 +++++++++++++++++++++++++++++++++++++++-
 1 file changed, 82 insertions(+), 2 deletions(-)

diff --git a/gdb/dwarf2/index-write.c b/gdb/dwarf2/index-write.c
index 3827a810130..1b5d4c10b0c 100644
--- a/gdb/dwarf2/index-write.c
+++ b/gdb/dwarf2/index-write.c
@@ -137,7 +137,7 @@ class data_buf
   }
 
   /* Return the size of the buffer.  */
-  size_t size () const
+  virtual size_t size () const
   {
     return m_vec.size ();
   }
@@ -1083,7 +1083,7 @@ write_gdbindex_1 (FILE *out_file,
 {
   data_buf contents;
   const offset_type size_of_header = 6 * sizeof (offset_type);
-  size_t total_len = size_of_header;
+  uint64_t total_len = size_of_header;
 
   /* The version number.  */
   contents.append_offset (8);
@@ -1117,6 +1117,9 @@ write_gdbindex_1 (FILE *out_file,
   if (total_len > max_size)
     error (_("gdb-index maximum file size of %zu exceeded"), max_size);
 
+  if (out_file == nullptr)
+    return;
+
   contents.file_write (out_file);
   cu_list.file_write (out_file);
   types_cu_list.file_write (out_file);
@@ -1537,10 +1540,87 @@ save_gdb_index_command (const char *arg, int from_tty)
     }
 }
 
+#if GDB_SELF_TEST
+#include "gdbsupport/selftest.h"
+
+namespace selftests {
+
+class pretend_data_buf : public data_buf
+{
+public:
+  /* Set the pretend size.  */
+  void set_pretend_size (size_t s) {
+    m_pretend_size = s;
+  }
+
+  /* Override size method of data_buf, returning the pretend size instead.  */
+  size_t size () const override {
+    return m_pretend_size;
+  }
+
+private:
+  size_t m_pretend_size = 0;
+};
+
+static void
+gdb_index ()
+{
+  pretend_data_buf cu_list;
+  pretend_data_buf types_cu_list;
+  pretend_data_buf addr_vec;
+  pretend_data_buf symtab_vec;
+  pretend_data_buf constant_pool;
+
+  const size_t size_of_header = 6 * sizeof (offset_type);
+
+  /* Test that an overly large index will throw an error.  */
+  symtab_vec.set_pretend_size (~(offset_type)0 - size_of_header);
+  constant_pool.set_pretend_size (1);
+
+  bool saw_exception = false;
+  try
+    {
+      write_gdbindex_1 (nullptr, cu_list, types_cu_list, addr_vec,
+			symtab_vec, constant_pool);
+    }
+  catch (const gdb_exception_error &e)
+    {
+      SELF_CHECK (e.reason == RETURN_ERROR);
+      SELF_CHECK (e.error == GENERIC_ERROR);
+      SELF_CHECK (e.message->find (_("gdb-index maximum file size of"))
+		  != std::string::npos);
+      SELF_CHECK (e.message->find (_("exceeded")) != std::string::npos);
+      saw_exception = true;
+    }
+  SELF_CHECK (saw_exception);
+
+  /* Test that the largest possible index will not throw an error.  */
+  constant_pool.set_pretend_size (0);
+
+  saw_exception = false;
+  try
+    {
+      write_gdbindex_1 (nullptr, cu_list, types_cu_list, addr_vec,
+			symtab_vec, constant_pool);
+    }
+  catch (const gdb_exception_error &e)
+    {
+      saw_exception = true;
+    }
+  SELF_CHECK (!saw_exception);
+}
+
+} /* selftests namespace.  */
+#endif
+
 void _initialize_dwarf_index_write ();
 void
 _initialize_dwarf_index_write ()
 {
+#if GDB_SELF_TEST
+  selftests::register_test ("gdb_index", selftests::gdb_index);
+#endif
+
   cmd_list_element *c = add_cmd ("gdb-index", class_files,
 				 save_gdb_index_command, _("\
 Save a gdb-index file.\n\

base-commit: 95fc47d5c6b363b9b195baf1850b0ba95438ce69
-- 
2.35.3


^ permalink raw reply	[flat|nested] 2+ messages in thread

* Re: [PATCH] [gdb/symtab] Fix overly large gdb-index file check for 32-bit
  2023-09-15  9:08 [PATCH] [gdb/symtab] Fix overly large gdb-index file check for 32-bit Tom de Vries
@ 2023-09-15 21:38 ` Kevin Buettner
  0 siblings, 0 replies; 2+ messages in thread
From: Kevin Buettner @ 2023-09-15 21:38 UTC (permalink / raw)
  To: Tom de Vries; +Cc: gdb-patches

On Fri, 15 Sep 2023 11:08:37 +0200
Tom de Vries <tdevries@suse.de> wrote:

> Add a unit test which checks that write_gdb_index_1 will throw
> an error when the size of the file would exceed the maximum value
> capable of being represented by 'offset_type'.
> 
> The unit test fails on 32-bit systems due to wrapping overflow.  Fix this by
> changing the type of total_len in write_gdbindex_1 from size_t to uint64_t.
> 
> Tested on x86_64-linux.
> 
> Co-Authored-By: Kevin Buettner <kevinb@redhat.com>
> ---
>  gdb/dwarf2/index-write.c | 84 +++++++++++++++++++++++++++++++++++++++-
>  1 file changed, 82 insertions(+), 2 deletions(-)

Thanks for adding the additional test along with fixing the wrapping
overflow problem on 32-bit systems.

Approved-by: Kevin Buettner <kevinb@redhat.com>


^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2023-09-15 21:38 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-09-15  9:08 [PATCH] [gdb/symtab] Fix overly large gdb-index file check for 32-bit Tom de Vries
2023-09-15 21:38 ` Kevin Buettner

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).