* [PATCH 2/3] bitpos: Additional checks to ensure that a type fits into size_t
@ 2012-08-04 19:24 Siddhesh Poyarekar
2012-08-11 5:44 ` Siddhesh Poyarekar
0 siblings, 1 reply; 3+ messages in thread
From: Siddhesh Poyarekar @ 2012-08-04 19:24 UTC (permalink / raw)
To: gdb-patches
[-- 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);
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [PATCH 2/3] bitpos: Additional checks to ensure that a type fits into size_t
2012-08-04 19:24 [PATCH 2/3] bitpos: Additional checks to ensure that a type fits into size_t Siddhesh Poyarekar
@ 2012-08-11 5:44 ` Siddhesh Poyarekar
2012-08-17 9:35 ` Siddhesh Poyarekar
0 siblings, 1 reply; 3+ messages in thread
From: Siddhesh Poyarekar @ 2012-08-11 5:44 UTC (permalink / raw)
To: gdb-patches; +Cc: Jan Kratochvil
[-- Attachment #1: Type: text/plain, Size: 1687 bytes --]
Hi,
This is the updated patch based on Jan's suggestions for change. I have
not consolidated the error messages for the argument overflow and the
generic size_t overflows (or more accurately, size_t/8 overflow)
because the error text is different.
It builds correctly and does not cause regressions in the testsuite.
Regards,
Siddhesh
gdb/ChangeLog
2012-08-11 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 (type_fits_size_t_or_error): New function that
throws an error if a type length is larger than size_t / 8.
* gdbtypes.h (type_fits_size_t_or_error): Likewise.
* 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 #2: bitpos-expand-ensure-sizet-2.patch --]
[-- Type: text/x-patch, Size: 9089 bytes --]
diff --git a/gdb/alpha-tdep.c b/gdb/alpha-tdep.c
index 7a6f38d..59ef631 100644
--- a/gdb/alpha-tdep.c
+++ b/gdb/alpha-tdep.c
@@ -397,9 +397,17 @@ alpha_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
default:
break;
}
+ type_fits_size_t_or_error (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 (_("Insufficient memory in GDB host for arguments, "
+ "only %s bytes available."),
+ plongest (SIZE_MAX / 2));
+
m_arg->contents = value_contents (arg);
}
diff --git a/gdb/avr-tdep.c b/gdb/avr-tdep.c
index b9a660a..aaac6f6 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. */
+ type_fits_size_t_or_error (type);
si = push_stack_item (si, contents, len);
}
}
diff --git a/gdb/cp-valprint.c b/gdb/cp-valprint.c
index 8bc329e..223c2fb 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;
+ type_fits_size_t_or_error (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..dd6a762 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;
+ type_fits_size_t_or_error (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);
+ type_fits_size_t_or_error (value_type (args[argnum]));
+ si = push_stack_item (si, val, len);
}
}
diff --git a/gdb/findcmd.c b/gdb/findcmd.c
index 0445e4c..36622a1 100644
--- a/gdb/findcmd.c
+++ b/gdb/findcmd.c
@@ -215,6 +215,7 @@ parse_find_args (char *args, ULONGEST *max_countp,
}
else
{
+ type_fits_size_t_or_error (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..544b1c6 100644
--- a/gdb/gdbtypes.c
+++ b/gdb/gdbtypes.c
@@ -1406,6 +1406,17 @@ 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
+type_fits_size_t_or_error (const struct type *type)
+{
+ if (TYPE_LENGTH (type) > SIZE_MAX / 8)
+ error (_("Insufficient memory in host GDB for object of size %s bytes, "
+ "maximum allowed %s bytes."), plongest (TYPE_LENGTH (type)),
+ plongest (SIZE_MAX / 8));
+}
+
/* 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 a728210..d71cacd 100644
--- a/gdb/gdbtypes.h
+++ b/gdb/gdbtypes.h
@@ -1658,4 +1658,6 @@ extern struct type *copy_type_recursive (struct objfile *objfile,
extern struct type *copy_type (const struct type *type);
+extern void type_fits_size_t_or_error (const struct type *type);
+
#endif /* GDBTYPES_H */
diff --git a/gdb/h8300-tdep.c b/gdb/h8300-tdep.c
index ee5aa2d..45cbc63 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);
+ type_fits_size_t_or_error (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);
+ type_fits_size_t_or_error (type);
read_memory (addr, readbuf, TYPE_LENGTH (type));
}
diff --git a/gdb/m88k-tdep.c b/gdb/m88k-tdep.c
index c990d6b..1d7991d 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++;
+ type_fits_size_t_or_error (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..3293b6d 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;
+ type_fits_size_t_or_error (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..f1d8c6a 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)
{
+ type_fits_size_t_or_error (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. */
+ type_fits_size_t_or_error (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..0ecd77b 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;
+ type_fits_size_t_or_error (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..8444cb7 100644
--- a/gdb/value.c
+++ b/gdb/value.c
@@ -662,6 +662,7 @@ allocate_value_lazy (struct type *type)
description correctly. */
check_typedef (type);
+ type_fits_size_t_or_error (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)
{
+ type_fits_size_t_or_error (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));
+ {
+ type_fits_size_t_or_error (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..33d1e83 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;
+ type_fits_size_t_or_error (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);
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [PATCH 2/3] bitpos: Additional checks to ensure that a type fits into size_t
2012-08-11 5:44 ` Siddhesh Poyarekar
@ 2012-08-17 9:35 ` Siddhesh Poyarekar
0 siblings, 0 replies; 3+ messages in thread
From: Siddhesh Poyarekar @ 2012-08-17 9:35 UTC (permalink / raw)
To: Jan Kratochvil; +Cc: gdb-patches
[-- Attachment #1: Type: text/plain, Size: 1744 bytes --]
Hi,
Here's another update to the ensure_size_t patch. The following changes
have been made to the patch:
* The function is now called ulongest_fits_host_or_error and is now
in utils.c. I have named it so to give room for a future
'longest_fits_host_orr_error' if needed. They have to be different
because the error message will have to be printed differently
(plongest vs pulongest). The name also looks neater in general.
* I have reverted the size_t checks from most tdep files in favour of
promoting the value_contents call ahead. In fact, barring
h8300h_return_value, all of them have an earlier value_contents call,
making the check unnecessary.
This change applies on top of the bitpos patch and I have verified that
the change does not cause any regressions.
Regards,
Siddhesh
gdb/ChangeLog
* alpha-tdep.c (alpha_push_dummy_call) Check for underflow in
SP.
* cp-valprint (cp_print_value): Ensure BASECLASS fits into
size_t.
* dwarf2loc.c (read_pieced_value): Ensure that THIS_SIZE fits
into size_t.
(write_pieced_value): Likewise.
* h8300-tdep.c (h8300h_return_value): Ensure that TYPE fits
into size_t.
* p-valprint (pascal_object_print_value): Ensure BASECLASS fits
into size_t.
* utils.c (ulongest_fits_host_or_error): New function to find if
a ULONGEST number fits into size_t.
* utils.h: Declare ulongest_fits_host_or_error.
* 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): Call
value_contents earlier to ensure that the argument fits into
host memory.
[-- Attachment #2: bitpos-expand-ensure-sizet-3.patch --]
[-- Type: text/x-patch, Size: 5971 bytes --]
diff --git a/gdb/alpha-tdep.c b/gdb/alpha-tdep.c
index 7a6f38d..0ce378f 100644
--- a/gdb/alpha-tdep.c
+++ b/gdb/alpha-tdep.c
@@ -414,6 +414,13 @@ alpha_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
accumulate_size = 0;
else
accumulate_size -= sizeof(arg_reg_buffer);
+
+ /* Check for underflow. */
+ if (sp - accumulate_size > sp)
+ error (_("Insufficient memory in GDB host for arguments, "
+ "need %s bytes, but less than %s bytes available."),
+ plongest (accumulate_size), plongest (CORE_ADDR_MAX - sp));
+
sp -= accumulate_size;
/* Keep sp aligned to a multiple of 16 as the ABI requires. */
diff --git a/gdb/cp-valprint.c b/gdb/cp-valprint.c
index 8bc329e..2373419 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;
+ ulongest_fits_host_or_error (TYPE_LENGTH (baseclass));
+
buf = xmalloc (TYPE_LENGTH (baseclass));
back_to = make_cleanup (xfree, buf);
diff --git a/gdb/dwarf2loc.c b/gdb/dwarf2loc.c
index bef4355..7106805 100644
--- a/gdb/dwarf2loc.c
+++ b/gdb/dwarf2loc.c
@@ -1593,6 +1593,8 @@ read_pieced_value (struct value *v)
this_size = (this_size_bits + source_offset_bits % 8 + 7) / 8;
source_offset = source_offset_bits / 8;
+ ulongest_fits_host_or_error (this_size);
+
if (buffer_size < this_size)
{
buffer_size = this_size;
@@ -1784,6 +1786,7 @@ write_pieced_value (struct value *to, struct value *from)
}
else
{
+ ulongest_fits_host_or_error (this_size);
if (buffer_size < this_size)
{
buffer_size = this_size;
diff --git a/gdb/h8300-tdep.c b/gdb/h8300-tdep.c
index ee5aa2d..c2e786f 100644
--- a/gdb/h8300-tdep.c
+++ b/gdb/h8300-tdep.c
@@ -925,6 +925,7 @@ h8300h_return_value (struct gdbarch *gdbarch, struct value *function,
ULONGEST addr;
regcache_raw_read_unsigned (regcache, E_R0_REGNUM, &addr);
+ ulongest_fits_host_or_error (TYPE_LENGTH (type));
read_memory (addr, readbuf, TYPE_LENGTH (type));
}
diff --git a/gdb/p-valprint.c b/gdb/p-valprint.c
index 56f9e30..c153669 100644
--- a/gdb/p-valprint.c
+++ b/gdb/p-valprint.c
@@ -791,6 +791,7 @@ pascal_object_print_value (struct type *type, const gdb_byte *valaddr,
gdb_byte *buf;
struct cleanup *back_to;
+ ulongest_fits_host_or_error (TYPE_LENGTH (baseclass));
buf = xmalloc (TYPE_LENGTH (baseclass));
back_to = make_cleanup (xfree, buf);
diff --git a/gdb/utils.c b/gdb/utils.c
index 607d7bc..f6602b5 100644
--- a/gdb/utils.c
+++ b/gdb/utils.c
@@ -3141,6 +3141,18 @@ host_address_to_string (const void *addr)
return str;
}
+/* Ensure that the input NUM is not larger than the maximum capacity of the
+ host system. We choose SIZE_MAX / 8 as a conservative estimate of the size
+ of a resource that a system may allocate. */
+void
+ulongest_fits_host_or_error (ULONGEST num)
+{
+ if (num > SIZE_MAX / 8)
+ error (_("Insufficient memory in host GDB for object of size %s bytes, "
+ "maximum allowed %s bytes."), pulongest (num),
+ pulongest (SIZE_MAX / 8));
+}
+
char *
gdb_realpath (const char *filename)
{
diff --git a/gdb/utils.h b/gdb/utils.h
index 4bb6ac8..d7d2e1a 100644
--- a/gdb/utils.h
+++ b/gdb/utils.h
@@ -23,6 +23,8 @@
#include "cleanups.h"
+extern void ulongest_fits_host_or_error (ULONGEST num);
+
extern void initialize_utils (void);
/* String utilities. */
diff --git a/gdb/valops.c b/gdb/valops.c
index 7c0a478..1708a4b 100644
--- a/gdb/valops.c
+++ b/gdb/valops.c
@@ -2275,6 +2275,7 @@ search_struct_method (const char *name, struct value **arg1p,
struct cleanup *back_to;
CORE_ADDR address;
+ ulongest_fits_host_or_error (TYPE_LENGTH (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 09ecb70..7c3bdb4 100644
--- a/gdb/value.c
+++ b/gdb/value.c
@@ -662,6 +662,7 @@ allocate_value_lazy (struct type *type)
description correctly. */
check_typedef (type);
+ ulongest_fits_host_or_error (TYPE_LENGTH (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)
{
+ ulongest_fits_host_or_error (TYPE_LENGTH (val->enclosing_type));
+
if (!val->contents)
val->contents = (gdb_byte *) xzalloc (TYPE_LENGTH (val->enclosing_type));
}
@@ -2602,8 +2605,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));
+ {
+ ulongest_fits_host_or_error (TYPE_LENGTH (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..1667c14 100644
--- a/gdb/xstormy16-tdep.c
+++ b/gdb/xstormy16-tdep.c
@@ -282,11 +282,15 @@ xstormy16_push_dummy_call (struct gdbarch *gdbarch,
for (j = nargs - 1; j >= i; j--)
{
char *val;
+ const gdb_byte *bytes = value_contents (args[j]);
+ struct type *t = value_enclosing_type (args[j]);
- typelen = TYPE_LENGTH (value_enclosing_type (args[j]));
+ typelen = TYPE_LENGTH (t);
slacklen = typelen & 1;
+
+ /* FIXME: This alloca is dangerous. */
val = alloca (typelen + slacklen);
- memcpy (val, value_contents (args[j]), typelen);
+ memcpy (val, bytes, typelen);
memset (val + typelen, 0, slacklen);
/* Now write this data to the stack. The stack grows upwards. */
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2012-08-17 9:35 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-08-04 19:24 [PATCH 2/3] bitpos: Additional checks to ensure that a type fits into size_t Siddhesh Poyarekar
2012-08-11 5:44 ` Siddhesh Poyarekar
2012-08-17 9:35 ` Siddhesh Poyarekar
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox