X-Git-Url: http://drtracing.org/?a=blobdiff_plain;ds=sidebyside;f=bfd%2Fopncls.c;h=b86bbab1d302dd2ec60d5734b15efe97bdc81739;hb=4ad0bb5f3a5b2d03079819cf419b174a762c2d52;hp=54744ced625e8457fbc20b385c73188ee1d3621f;hpb=1be5090bcaf4bcab333cf03f4157b16d33881222;p=deliverable%2Fbinutils-gdb.git diff --git a/bfd/opncls.c b/bfd/opncls.c index 54744ced62..b86bbab1d3 100644 --- a/bfd/opncls.c +++ b/bfd/opncls.c @@ -1,5 +1,5 @@ /* opncls.c -- open and close a BFD. - Copyright 1990-2013 Free Software Foundation, Inc. + Copyright (C) 1990-2016 Free Software Foundation, Inc. Written by Cygnus Support. @@ -109,6 +109,8 @@ _bfd_new_bfd_contained_in (bfd *obfd) nbfd->my_archive = obfd; nbfd->direction = read_direction; nbfd->target_defaulted = obfd->target_defaulted; + nbfd->lto_output = obfd->lto_output; + nbfd->no_export = obfd->no_export; return nbfd; } @@ -937,14 +939,23 @@ void * bfd_alloc (bfd *abfd, bfd_size_type size) { void *ret; - - if (size != (unsigned long) size) + unsigned long ul_size = (unsigned long) size; + + if (size != ul_size + /* Note - although objalloc_alloc takes an unsigned long as its + argument, internally the size is treated as a signed long. This can + lead to problems where, for example, a request to allocate -1 bytes + can result in just 1 byte being allocated, rather than + ((unsigned long) -1) bytes. Also memory checkers will often + complain about attempts to allocate a negative amount of memory. + So to stop these problems we fail if the size is negative. */ + || ((signed long) ul_size) < 0) { bfd_set_error (bfd_error_no_memory); return NULL; } - ret = objalloc_alloc ((struct objalloc *) abfd->memory, (unsigned long) size); + ret = objalloc_alloc ((struct objalloc *) abfd->memory, ul_size); if (ret == NULL) bfd_set_error (bfd_error_no_memory); return ret; @@ -965,8 +976,6 @@ DESCRIPTION void * bfd_alloc2 (bfd *abfd, bfd_size_type nmemb, bfd_size_type size) { - void *ret; - if ((nmemb | size) >= HALF_BFD_SIZE_TYPE && size != 0 && nmemb > ~(bfd_size_type) 0 / size) @@ -975,18 +984,7 @@ bfd_alloc2 (bfd *abfd, bfd_size_type nmemb, bfd_size_type size) return NULL; } - size *= nmemb; - - if (size != (unsigned long) size) - { - bfd_set_error (bfd_error_no_memory); - return NULL; - } - - ret = objalloc_alloc ((struct objalloc *) abfd->memory, (unsigned long) size); - if (ret == NULL) - bfd_set_error (bfd_error_no_memory); - return ret; + return bfd_alloc (abfd, size * nmemb); } /* @@ -1178,7 +1176,7 @@ bfd_get_debug_link_info (bfd *abfd, unsigned long *crc32_out) asection *sect; unsigned long crc32; bfd_byte *contents; - int crc_offset; + unsigned int crc_offset; char *name; BFD_ASSERT (abfd); @@ -1196,10 +1194,13 @@ bfd_get_debug_link_info (bfd *abfd, unsigned long *crc32_out) return NULL; } - /* Crc value is stored after the filename, aligned up to 4 bytes. */ + /* CRC value is stored after the filename, aligned up to 4 bytes. */ name = (char *) contents; - crc_offset = strlen (name) + 1; + /* PR 17597: avoid reading off the end of the buffer. */ + crc_offset = strnlen (name, bfd_get_section_size (sect)) + 1; crc_offset = (crc_offset + 3) & ~3; + if (crc_offset >= bfd_get_section_size (sect)) + return NULL; crc32 = bfd_get_32 (abfd, contents + crc_offset); @@ -1231,7 +1232,7 @@ bfd_get_alt_debug_link_info (bfd * abfd, bfd_size_type *buildid_len, { asection *sect; bfd_byte *contents; - int buildid_offset; + unsigned int buildid_offset; char *name; BFD_ASSERT (abfd); @@ -1252,7 +1253,9 @@ bfd_get_alt_debug_link_info (bfd * abfd, bfd_size_type *buildid_len, /* BuildID value is stored after the filename. */ name = (char *) contents; - buildid_offset = strlen (name) + 1; + buildid_offset = strnlen (name, bfd_get_section_size (sect)) + 1; + if (buildid_offset >= bfd_get_section_size (sect)) + return NULL; *buildid_len = bfd_get_section_size (sect) - buildid_offset; *buildid_out = bfd_malloc (*buildid_len); @@ -1375,7 +1378,7 @@ find_separate_debug_file (bfd * abfd, } base = get_func (abfd, & crc32); - + if (base == NULL) return NULL;