From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 22431 invoked by alias); 4 Aug 2012 19:24:51 -0000 Received: (qmail 22422 invoked by uid 22791); 4 Aug 2012 19:24:49 -0000 X-SWARE-Spam-Status: No, hits=-6.7 required=5.0 tests=AWL,BAYES_00,KHOP_RCVD_UNTRUST,RCVD_IN_DNSWL_HI,RCVD_IN_HOSTKARMA_W,SPF_HELO_PASS,TW_BJ,TW_CP,TW_EG,TW_VP,TW_XZ,T_RP_MATCHES_RCVD X-Spam-Check-By: sourceware.org Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Sat, 04 Aug 2012 19:24:35 +0000 Received: from int-mx11.intmail.prod.int.phx2.redhat.com (int-mx11.intmail.prod.int.phx2.redhat.com [10.5.11.24]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id q74JOYQ5030380 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK) for ; Sat, 4 Aug 2012 15:24:34 -0400 Received: from spoyarek (vpn-237-183.phx2.redhat.com [10.3.237.183]) by int-mx11.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id q74JOWw4011978 for ; Sat, 4 Aug 2012 15:24:33 -0400 Date: Sat, 04 Aug 2012 19:24:00 -0000 From: Siddhesh Poyarekar To: gdb-patches@sourceware.org Subject: [PATCH 2/3] bitpos: Additional checks to ensure that a type fits into size_t Message-ID: <20120805005411.5fc2c25a@spoyarek> Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="MP_/UskdxdkqjQCzEDGMVV8Lxr=" Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org X-SW-Source: 2012-08/txt/msg00145.txt.bz2 --MP_/UskdxdkqjQCzEDGMVV8Lxr= Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 7bit Content-Disposition: inline Content-length: 367 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 --MP_/UskdxdkqjQCzEDGMVV8Lxr= Content-Type: text/plain Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename=bitpos-cl-ensure_sizet.txt Content-length: 1416 gdb/ChangeLog 2012-08-05 Siddhesh Poyarekar * 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. --MP_/UskdxdkqjQCzEDGMVV8Lxr= Content-Type: text/x-patch Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename=bitpos-expand-ensure-sizet.patch Content-length: 9489 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); --MP_/UskdxdkqjQCzEDGMVV8Lxr=--