aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlan Modra <amodra@gmail.com>2025-01-17 15:55:12 +1030
committerAlan Modra <amodra@gmail.com>2025-01-17 16:07:48 +1030
commitb565ac119bdf8ed857cfa1352ddc732ccdac7b66 (patch)
tree469d164821bde6fe865154617705f83f7407edf5
parent7976c00c183f700e60031c67b3cc49875323c02e (diff)
downloadbinutils-b565ac119bdf8ed857cfa1352ddc732ccdac7b66.zip
binutils-b565ac119bdf8ed857cfa1352ddc732ccdac7b66.tar.gz
binutils-b565ac119bdf8ed857cfa1352ddc732ccdac7b66.tar.bz2
buffer overflow in score_elf_create_dynamic_relocation
score_elf_create_dynamic_relocation sets up three output dynamic relocs from rel[0], rel[1] and rel[2]. When rel[0] is the last reloc in a section this of course results in a buffer overflow. It's a weird thing to do given that only one relocation is output. * elf32-score.c (score_elf_create_dynamic_relocation): Do not set up three dynamic relocations when only one is output. * elf32-score7.c: Likewise.
-rw-r--r--bfd/elf32-score.c30
-rw-r--r--bfd/elf32-score7.c30
2 files changed, 20 insertions, 40 deletions
diff --git a/bfd/elf32-score.c b/bfd/elf32-score.c
index c656e0d..9563098 100644
--- a/bfd/elf32-score.c
+++ b/bfd/elf32-score.c
@@ -1287,7 +1287,7 @@ score_elf_create_dynamic_relocation (bfd *output_bfd,
bfd_vma symbol,
bfd_vma *addendp, asection *input_section)
{
- Elf_Internal_Rela outrel[3];
+ Elf_Internal_Rela outrel;
asection *sreloc;
bfd *dynobj;
int r_type;
@@ -1301,18 +1301,14 @@ score_elf_create_dynamic_relocation (bfd *output_bfd,
BFD_ASSERT (sreloc->contents != NULL);
BFD_ASSERT (sreloc->reloc_count * SCORE_ELF_REL_SIZE (output_bfd) < sreloc->size);
- outrel[0].r_offset =
- _bfd_elf_section_offset (output_bfd, info, input_section, rel[0].r_offset);
- outrel[1].r_offset =
- _bfd_elf_section_offset (output_bfd, info, input_section, rel[1].r_offset);
- outrel[2].r_offset =
- _bfd_elf_section_offset (output_bfd, info, input_section, rel[2].r_offset);
+ outrel.r_offset =
+ _bfd_elf_section_offset (output_bfd, info, input_section, rel->r_offset);
- if (outrel[0].r_offset == MINUS_ONE)
+ if (outrel.r_offset == MINUS_ONE)
/* The relocation field has been deleted. */
return true;
- if (outrel[0].r_offset == MINUS_TWO)
+ if (outrel.r_offset == MINUS_TWO)
{
/* The relocation field has been converted into a relative value of
some sort. Functions like _bfd_elf_write_section_eh_frame expect
@@ -1351,7 +1347,7 @@ score_elf_create_dynamic_relocation (bfd *output_bfd,
/* The relocation is always an REL32 relocation because we don't
know where the shared library will wind up at load-time. */
- outrel[0].r_info = ELF32_R_INFO ((unsigned long) indx, R_SCORE_REL32);
+ outrel.r_info = ELF32_R_INFO ((unsigned long) indx, R_SCORE_REL32);
/* For strict adherence to the ABI specification, we should
generate a R_SCORE_64 relocation record by itself before the
@@ -1365,24 +1361,18 @@ score_elf_create_dynamic_relocation (bfd *output_bfd,
invocation if ABI_64_P, and here we should generate an
additional relocation record with R_SCORE_64 by itself for a
NULL symbol before this relocation record. */
- outrel[1].r_info = ELF32_R_INFO (0, R_SCORE_NONE);
- outrel[2].r_info = ELF32_R_INFO (0, R_SCORE_NONE);
/* Adjust the output offset of the relocation to reference the
correct location in the output file. */
- outrel[0].r_offset += (input_section->output_section->vma
- + input_section->output_offset);
- outrel[1].r_offset += (input_section->output_section->vma
- + input_section->output_offset);
- outrel[2].r_offset += (input_section->output_section->vma
- + input_section->output_offset);
+ outrel.r_offset += (input_section->output_section->vma
+ + input_section->output_offset);
/* Put the relocation back out. We have to use the special
relocation outputter in the 64-bit case since the 64-bit
relocation format is non-standard. */
bfd_elf32_swap_reloc_out
- (output_bfd, &outrel[0],
- (sreloc->contents + sreloc->reloc_count * sizeof (Elf32_External_Rel)));
+ (output_bfd, &outrel,
+ sreloc->contents + sreloc->reloc_count * sizeof (Elf32_External_Rel));
/* We've now added another relocation. */
++sreloc->reloc_count;
diff --git a/bfd/elf32-score7.c b/bfd/elf32-score7.c
index f517162..2ecabf6 100644
--- a/bfd/elf32-score7.c
+++ b/bfd/elf32-score7.c
@@ -1147,7 +1147,7 @@ score_elf_create_dynamic_relocation (bfd *output_bfd,
bfd_vma symbol,
bfd_vma *addendp, asection *input_section)
{
- Elf_Internal_Rela outrel[3];
+ Elf_Internal_Rela outrel;
asection *sreloc;
bfd *dynobj;
int r_type;
@@ -1161,18 +1161,14 @@ score_elf_create_dynamic_relocation (bfd *output_bfd,
BFD_ASSERT (sreloc->contents != NULL);
BFD_ASSERT (sreloc->reloc_count * SCORE_ELF_REL_SIZE (output_bfd) < sreloc->size);
- outrel[0].r_offset =
- _bfd_elf_section_offset (output_bfd, info, input_section, rel[0].r_offset);
- outrel[1].r_offset =
- _bfd_elf_section_offset (output_bfd, info, input_section, rel[1].r_offset);
- outrel[2].r_offset =
- _bfd_elf_section_offset (output_bfd, info, input_section, rel[2].r_offset);
+ outrel.r_offset =
+ _bfd_elf_section_offset (output_bfd, info, input_section, rel->r_offset);
- if (outrel[0].r_offset == MINUS_ONE)
+ if (outrel.r_offset == MINUS_ONE)
/* The relocation field has been deleted. */
return true;
- if (outrel[0].r_offset == MINUS_TWO)
+ if (outrel.r_offset == MINUS_TWO)
{
/* The relocation field has been converted into a relative value of
some sort. Functions like _bfd_elf_write_section_eh_frame expect
@@ -1211,7 +1207,7 @@ score_elf_create_dynamic_relocation (bfd *output_bfd,
/* The relocation is always an REL32 relocation because we don't
know where the shared library will wind up at load-time. */
- outrel[0].r_info = ELF32_R_INFO ((unsigned long) indx, R_SCORE_REL32);
+ outrel.r_info = ELF32_R_INFO ((unsigned long) indx, R_SCORE_REL32);
/* For strict adherence to the ABI specification, we should
generate a R_SCORE_64 relocation record by itself before the
@@ -1225,24 +1221,18 @@ score_elf_create_dynamic_relocation (bfd *output_bfd,
invocation if ABI_64_P, and here we should generate an
additional relocation record with R_SCORE_64 by itself for a
NULL symbol before this relocation record. */
- outrel[1].r_info = ELF32_R_INFO (0, R_SCORE_NONE);
- outrel[2].r_info = ELF32_R_INFO (0, R_SCORE_NONE);
/* Adjust the output offset of the relocation to reference the
correct location in the output file. */
- outrel[0].r_offset += (input_section->output_section->vma
- + input_section->output_offset);
- outrel[1].r_offset += (input_section->output_section->vma
- + input_section->output_offset);
- outrel[2].r_offset += (input_section->output_section->vma
- + input_section->output_offset);
+ outrel.r_offset += (input_section->output_section->vma
+ + input_section->output_offset);
/* Put the relocation back out. We have to use the special
relocation outputter in the 64-bit case since the 64-bit
relocation format is non-standard. */
bfd_elf32_swap_reloc_out
- (output_bfd, &outrel[0],
- (sreloc->contents + sreloc->reloc_count * sizeof (Elf32_External_Rel)));
+ (output_bfd, &outrel,
+ sreloc->contents + sreloc->reloc_count * sizeof (Elf32_External_Rel));
/* We've now added another relocation. */
++sreloc->reloc_count;