summaryrefslogtreecommitdiff
path: root/bfd/opncls.c
diff options
context:
space:
mode:
Diffstat (limited to 'bfd/opncls.c')
-rw-r--r--bfd/opncls.c41
1 files changed, 19 insertions, 22 deletions
diff --git a/bfd/opncls.c b/bfd/opncls.c
index a2a35f4e058..75af627d293 100644
--- a/bfd/opncls.c
+++ b/bfd/opncls.c
@@ -937,14 +937,19 @@ void *
bfd_alloc (bfd *abfd, bfd_size_type size)
{
void *ret;
+ unsigned long ul_size = (unsigned long) size;
- if (size != (unsigned long) size)
+ if (size != ul_size
+ /* A small negative size can result in objalloc_alloc allocating just
+ 1 byte of memory, but the caller will be expecting more. So catch
+ this case here. */
+ || (size != 0 && (((ul_size + OBJALLOC_ALIGN - 1) &~ (OBJALLOC_ALIGN - 1)) == 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 +970,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 +978,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 +1170,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 +1188,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 +1226,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 +1247,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);