Mirror of the gdb-patches mailing list
 help / color / mirror / Atom feed
From: Siddhesh Poyarekar <siddhesh@redhat.com>
To: gdb-patches@sourceware.org
Subject: [PATCH 2/3] bitpos: Additional checks to ensure that a type fits into size_t
Date: Sat, 04 Aug 2012 19:24:00 -0000	[thread overview]
Message-ID: <20120805005411.5fc2c25a@spoyarek> (raw)

[-- Attachment #1: Type: text/plain, Size: 367 bytes --]

Hi,

This is part 2 of the patch for bitpos expansion. This part adds
additional checks that ensure that a type is small enough to fit into
host gdb, i.e. it fits into size_t.

I have verified that the change does not introduce any regressions on
x86_64. I haven't made any test cases for this change, but I can try to
write one if it is necessary.

Regards,
Siddhesh

[-- Attachment #2: bitpos-cl-ensure_sizet.txt --]
[-- Type: text/plain, Size: 1416 bytes --]

gdb/ChangeLog

2012-08-05  Siddhesh Poyarekar  <siddhesh@redhat.com>

	* alpha-tdep.c (alpha_push_dummy_call) Ensure that ARG_TYPE fits
	into size_t.  Check for overflow in ACCUMULATE_SIZE.
	* avr-tdep.c (avr_push_dummy_call): Ensure TYPE fits into
	size_t.
	* cp-valprint (cp_print_value): Ensure BASECLASS fits into
	size_t.
	* cris-tdep.c (cris_push_dummy_call): Ensure that arguments fit
	into size_t.
	* findcmd.c (parse_find_args): Ensure type of V fits into
	size_t.
	* gdbtypes.c (ensure_type_fits_sizet): New function that throws
	an error if a type length is larger than size_t.
	* gdbtypes.h (TYPE_LENGTH_FITS_SIZET): New macro to check if
	type length fits into size_t.
	(ensure_type_fits_sizet): Declare.
	* h8300-tdep.c (h8300_push_dummy_call): Ensure TYPE fits into
	size_t.
	(h8300h_return_value): Likewise.
	* m88k-tdep.c (m88k_store_arguments): Likewise.
	* p-valprint (pascal_object_print_value): Ensure BASECLASS fits
	into size_t.
	* sh-tdep.c (sh_push_dummy_call_fpu): Expand REG_SIZE.  Ensure
	TYPE fits into size_t.
	(sh_push_dummy_call_nofpu): Likewise.
	* valops.c (search_struct_method): Ensure BASECLASS fits into
	size_t.
	* value.c (allocate_value_lazy): Ensure TYPE fits into size_t.
	(allocate_value_contents): Likewise.
	(set_value_enclosing_type): Ensure NEW_ENCL_TYPE fits into
	size_t.
	* xstormy16-tdep.c (xstormy16_push_dummy_call): Ensure that each
	argument fits into size_t.

[-- Attachment #3: bitpos-expand-ensure-sizet.patch --]
[-- Type: text/x-patch, Size: 9489 bytes --]

diff --git a/gdb/alpha-tdep.c b/gdb/alpha-tdep.c
index 7a6f38d..de72c9c 100644
--- a/gdb/alpha-tdep.c
+++ b/gdb/alpha-tdep.c
@@ -397,9 +397,15 @@ alpha_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
 	default:
 	  break;
 	}
+      ensure_type_fits_sizet (arg_type);
       m_arg->len = TYPE_LENGTH (arg_type);
       m_arg->offset = accumulate_size;
       accumulate_size = (accumulate_size + m_arg->len + 7) & ~7;
+
+      /* Check for overflow.  */
+      if (accumulate_size < 0)
+        error (_("Total size of arguments too large for host GDB memory."));
+
       m_arg->contents = value_contents (arg);
     }
 
diff --git a/gdb/avr-tdep.c b/gdb/avr-tdep.c
index b9a660a..fc0a3ea 100644
--- a/gdb/avr-tdep.c
+++ b/gdb/avr-tdep.c
@@ -1295,6 +1295,7 @@ avr_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
       else
         {
           /* From here on, we don't care about regnum.  */
+	  ensure_type_fits_sizet (type);
           si = push_stack_item (si, contents, len);
         }
     }
diff --git a/gdb/cp-valprint.c b/gdb/cp-valprint.c
index 8bc329e..69440fd 100644
--- a/gdb/cp-valprint.c
+++ b/gdb/cp-valprint.c
@@ -558,6 +558,8 @@ cp_print_value (struct type *type, struct type *real_type,
 		  gdb_byte *buf;
 		  struct cleanup *back_to;
 
+		  ensure_type_fits_sizet (baseclass);
+
 		  buf = xmalloc (TYPE_LENGTH (baseclass));
 		  back_to = make_cleanup (xfree, buf);
 
diff --git a/gdb/cris-tdep.c b/gdb/cris-tdep.c
index abbcbf1..4af5322 100644
--- a/gdb/cris-tdep.c
+++ b/gdb/cris-tdep.c
@@ -896,6 +896,7 @@ cris_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
 	  /* Data passed by reference.  Push copy of data onto stack
 	     and pass pointer to this copy as argument.  */
 	  sp = (sp - len) & ~3;
+	  ensure_type_fits_sizet (value_type (args[argnum]));
 	  write_memory (sp, val, len);
 
 	  if (argreg <= ARG4_REGNUM)
@@ -914,7 +915,8 @@ cris_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
         {
           /* Data passed by value.  No available registers.  Put it on
              the stack.  */
-	   si = push_stack_item (si, val, len);
+	  ensure_type_fits_sizet (value_type (args[argnum]));
+	  si = push_stack_item (si, val, len);
         }
     }
 
diff --git a/gdb/findcmd.c b/gdb/findcmd.c
index 0445e4c..76ad331 100644
--- a/gdb/findcmd.c
+++ b/gdb/findcmd.c
@@ -215,6 +215,7 @@ parse_find_args (char *args, ULONGEST *max_countp,
 	}
       else
 	{
+	  ensure_type_fits_sizet (value_type (v));
 	  memcpy (pattern_buf_end, value_contents (v), val_bytes);
 	  pattern_buf_end += val_bytes;
 	}
diff --git a/gdb/gdbtypes.c b/gdb/gdbtypes.c
index 9479098..0e28bee 100644
--- a/gdb/gdbtypes.c
+++ b/gdb/gdbtypes.c
@@ -1406,6 +1406,15 @@ lookup_struct_elt_type (struct type *type, char *name, int noerr)
   error (_("Type %s has no component named %s."), typename, name);
 }
 
+/* Ensure that the input TYPE is not larger than the maximum capacity of the
+   host system, i.e. size_t.  */
+void
+ensure_type_fits_sizet (const struct type *type)
+{
+  if (!TYPE_LENGTH_FITS_SIZET (type))
+    error (_("Target object too large for host GDB memory."));
+}
+
 /* Lookup the vptr basetype/fieldno values for TYPE.
    If found store vptr_basetype in *BASETYPEP if non-NULL, and return
    vptr_fieldno.  Also, if found and basetype is from the same objfile,
diff --git a/gdb/gdbtypes.h b/gdb/gdbtypes.h
index a0921c5..cab8263 100644
--- a/gdb/gdbtypes.h
+++ b/gdb/gdbtypes.h
@@ -1059,6 +1059,10 @@ extern void allocate_gnat_aux_type (struct type *);
    so you only have to call check_typedef once.  Since allocate_value
    calls check_typedef, TYPE_LENGTH (VALUE_TYPE (X)) is safe.  */
 #define TYPE_LENGTH(thistype) (thistype)->length
+/* Make sure that TYPE_LENGTH fits into a size_t.  */
+#define TYPE_LENGTH_FITS_SIZET(thistype) ((size_t) TYPE_LENGTH (thistype) \
+					  == TYPE_LENGTH (thistype))
+
 /* Note that TYPE_CODE can be TYPE_CODE_TYPEDEF, so if you want the real
    type, you need to do TYPE_CODE (check_type (this_type)).  */
 #define TYPE_CODE(thistype) TYPE_MAIN_TYPE(thistype)->code
@@ -1658,4 +1662,6 @@ extern struct type *copy_type_recursive (struct objfile *objfile,
 
 extern struct type *copy_type (const struct type *type);
 
+extern void ensure_type_fits_sizet (const struct type *type);
+
 #endif /* GDBTYPES_H */
diff --git a/gdb/h8300-tdep.c b/gdb/h8300-tdep.c
index ee5aa2d..56bd27e 100644
--- a/gdb/h8300-tdep.c
+++ b/gdb/h8300-tdep.c
@@ -672,8 +672,11 @@ h8300_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
 
       /* Pad the argument appropriately.  */
       LONGEST padded_len = align_up (len, wordsize);
+
+      /* FIXME: This alloca could be dangerous.  */
       gdb_byte *padded = alloca (padded_len);
 
+      ensure_type_fits_sizet (type);
       memset (padded, 0, padded_len);
       memcpy (len < wordsize ? padded + padded_len - len : padded,
 	      contents, len);
@@ -925,6 +928,7 @@ h8300h_return_value (struct gdbarch *gdbarch, struct value *function,
 	  ULONGEST addr;
 
 	  regcache_raw_read_unsigned (regcache, E_R0_REGNUM, &addr);
+	  ensure_type_fits_sizet (type);
 	  read_memory (addr, readbuf, TYPE_LENGTH (type));
 	}
 
diff --git a/gdb/m88k-tdep.c b/gdb/m88k-tdep.c
index c990d6b..d97e06b 100644
--- a/gdb/m88k-tdep.c
+++ b/gdb/m88k-tdep.c
@@ -336,6 +336,8 @@ m88k_store_arguments (struct regcache *regcache, int nargs,
       if (stack_word % 2 == -1 && m88k_8_byte_align_p (type))
 	stack_word++;
 
+      ensure_type_fits_sizet (type);
+
       write_memory (sp + stack_word * 4, valbuf, len);
       num_stack_words = (stack_word + (len + 3) / 4);
     }
diff --git a/gdb/p-valprint.c b/gdb/p-valprint.c
index 2f9f60d..0b30fde 100644
--- a/gdb/p-valprint.c
+++ b/gdb/p-valprint.c
@@ -801,6 +801,7 @@ pascal_object_print_value (struct type *type, const gdb_byte *valaddr,
 	      gdb_byte *buf;
 	      struct cleanup *back_to;
 
+	      ensure_type_fits_sizet (baseclass);
 	      buf = xmalloc (TYPE_LENGTH (baseclass));
 	      back_to = make_cleanup (xfree, buf);
 
diff --git a/gdb/sh-tdep.c b/gdb/sh-tdep.c
index 00d7401..e16e4dc 100644
--- a/gdb/sh-tdep.c
+++ b/gdb/sh-tdep.c
@@ -1068,7 +1068,7 @@ sh_push_dummy_call_fpu (struct gdbarch *gdbarch,
   CORE_ADDR regval;
   char *val;
   LONGEST len;
-  int reg_size = 0;
+  ssize_t reg_size = 0;
   int pass_on_stack = 0;
   int treat_as_flt;
   int last_reg_arg = INT_MAX;
@@ -1126,6 +1126,7 @@ sh_push_dummy_call_fpu (struct gdbarch *gdbarch,
 	                            || pass_on_stack))
 	      || argnum > last_reg_arg)
 	    {
+	      ensure_type_fits_sizet (type);
 	      /* The data goes entirely on the stack, 4-byte aligned.  */
 	      reg_size = (len + 3) & ~3;
 	      write_memory (sp + stack_offset, val, reg_size);
@@ -1210,7 +1211,7 @@ sh_push_dummy_call_nofpu (struct gdbarch *gdbarch,
   CORE_ADDR regval;
   char *val;
   LONGEST len;
-  int reg_size = 0;
+  ssize_t reg_size = 0;
   int pass_on_stack = 0;
   int last_reg_arg = INT_MAX;
 
@@ -1254,6 +1255,7 @@ sh_push_dummy_call_nofpu (struct gdbarch *gdbarch,
 	    {
 	      /* The remainder of the data goes entirely on the stack,
 	         4-byte aligned.  */
+	      ensure_type_fits_sizet (type);
 	      reg_size = (len + 3) & ~3;
 	      write_memory (sp + stack_offset, val, reg_size);
 	      stack_offset += reg_size;
diff --git a/gdb/valops.c b/gdb/valops.c
index 36fe229..7fc282d 100644
--- a/gdb/valops.c
+++ b/gdb/valops.c
@@ -2288,6 +2288,7 @@ search_struct_method (const char *name, struct value **arg1p,
 	      struct cleanup *back_to;
 	      CORE_ADDR address;
 
+	      ensure_type_fits_sizet (baseclass);
 	      tmp = xmalloc (TYPE_LENGTH (baseclass));
 	      back_to = make_cleanup (xfree, tmp);
 	      address = value_address (*arg1p);
diff --git a/gdb/value.c b/gdb/value.c
index 3fddba0..a5f654b 100644
--- a/gdb/value.c
+++ b/gdb/value.c
@@ -662,6 +662,7 @@ allocate_value_lazy (struct type *type)
      description correctly.  */
   check_typedef (type);
 
+  ensure_type_fits_sizet (type);
   val = (struct value *) xzalloc (sizeof (struct value));
   val->contents = NULL;
   val->next = all_values;
@@ -693,6 +694,8 @@ allocate_value_lazy (struct type *type)
 void
 allocate_value_contents (struct value *val)
 {
+  ensure_type_fits_sizet (val->enclosing_type);
+
   if (!val->contents)
     val->contents = (gdb_byte *) xzalloc (TYPE_LENGTH (val->enclosing_type));
 }
@@ -2596,8 +2599,12 @@ void
 set_value_enclosing_type (struct value *val, struct type *new_encl_type)
 {
   if (TYPE_LENGTH (new_encl_type) > TYPE_LENGTH (value_enclosing_type (val))) 
-    val->contents =
-      (gdb_byte *) xrealloc (val->contents, TYPE_LENGTH (new_encl_type));
+    {
+      ensure_type_fits_sizet (new_encl_type);
+
+      val->contents =
+	(gdb_byte *) xrealloc (val->contents, TYPE_LENGTH (new_encl_type));
+    }
 
   val->enclosing_type = new_encl_type;
 }
diff --git a/gdb/xstormy16-tdep.c b/gdb/xstormy16-tdep.c
index d73e2d6..6650cc6 100644
--- a/gdb/xstormy16-tdep.c
+++ b/gdb/xstormy16-tdep.c
@@ -285,6 +285,9 @@ xstormy16_push_dummy_call (struct gdbarch *gdbarch,
 
       typelen = TYPE_LENGTH (value_enclosing_type (args[j]));
       slacklen = typelen & 1;
+      ensure_type_fits_sizet (value_enclosing_type (args[j]));
+
+      /* FIXME: This alloca is dangerous.  */
       val = alloca (typelen + slacklen);
       memcpy (val, value_contents (args[j]), typelen);
       memset (val + typelen, 0, slacklen);

             reply	other threads:[~2012-08-04 19:24 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2012-08-04 19:24 Siddhesh Poyarekar [this message]
2012-08-11  5:44 ` Siddhesh Poyarekar
2012-08-17  9:35   ` Siddhesh Poyarekar

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20120805005411.5fc2c25a@spoyarek \
    --to=siddhesh@redhat.com \
    --cc=gdb-patches@sourceware.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox