diff options
Diffstat (limited to 'bfd/elf.c')
-rw-r--r-- | bfd/elf.c | 141 |
1 files changed, 86 insertions, 55 deletions
@@ -354,8 +354,8 @@ bfd_elf_string_from_elf_section (bfd *abfd, unsigned int shstrndx = elf_elfheader(abfd)->e_shstrndx; _bfd_error_handler /* xgettext:c-format */ - (_("%B: invalid string offset %u >= %lu for section `%s'"), - abfd, strindex, (unsigned long) hdr->sh_size, + (_("%B: invalid string offset %u >= %Lu for section `%s'"), + abfd, strindex, hdr->sh_size, (shindex == shstrndx && strindex == hdr->sh_name ? ".shstrtab" : bfd_elf_string_from_elf_section (abfd, shstrndx, hdr->sh_name))); @@ -742,12 +742,22 @@ setup_group (bfd *abfd, Elf_Internal_Shdr *hdr, asection *newsect) { Elf_Internal_Shdr *shdr = elf_tdata (abfd)->group_sect_ptr[i]; Elf_Internal_Group *idx; - unsigned int n_elt; + bfd_size_type n_elt; if (shdr == NULL) continue; idx = (Elf_Internal_Group *) shdr->contents; + if (idx == NULL || shdr->sh_size < 4) + { + /* See PR 21957 for a reproducer. */ + /* xgettext:c-format */ + _bfd_error_handler (_("%B: group section '%A' has no contents"), + abfd, shdr->bfd_section); + elf_tdata (abfd)->group_sect_ptr[i] = NULL; + bfd_set_error (bfd_error_bad_value); + return FALSE; + } n_elt = shdr->sh_size / 4; /* Look through this group's sections to see if current @@ -801,7 +811,7 @@ setup_group (bfd *abfd, Elf_Internal_Shdr *hdr, asection *newsect) if (elf_group_name (newsect) == NULL) { /* xgettext:c-format */ - _bfd_error_handler (_("%B: no group info for section %A"), + _bfd_error_handler (_("%B: no group info for section '%A'"), abfd, newsect); return FALSE; } @@ -896,32 +906,39 @@ _bfd_elf_setup_sections (bfd *abfd) n_elt = shdr->sh_size / 4; while (--n_elt != 0) - if ((++idx)->shdr->bfd_section) - elf_sec_group (idx->shdr->bfd_section) = shdr->bfd_section; - else if (idx->shdr->sh_type == SHT_RELA - || idx->shdr->sh_type == SHT_REL) - /* We won't include relocation sections in section groups in - output object files. We adjust the group section size here - so that relocatable link will work correctly when - relocation sections are in section group in input object - files. */ - shdr->bfd_section->size -= 4; - else - { - /* There are some unknown sections in the group. */ - _bfd_error_handler - /* xgettext:c-format */ - (_("%B: unknown type [%#x] section `%s' in group [%A]"), - abfd, - idx->shdr->sh_type, - bfd_elf_string_from_elf_section (abfd, - (elf_elfheader (abfd) - ->e_shstrndx), - idx->shdr->sh_name), - shdr->bfd_section); - result = FALSE; - } + { + ++ idx; + + if (idx->shdr == NULL) + continue; + else if (idx->shdr->bfd_section) + elf_sec_group (idx->shdr->bfd_section) = shdr->bfd_section; + else if (idx->shdr->sh_type == SHT_RELA + || idx->shdr->sh_type == SHT_REL) + /* We won't include relocation sections in section groups in + output object files. We adjust the group section size here + so that relocatable link will work correctly when + relocation sections are in section group in input object + files. */ + shdr->bfd_section->size -= 4; + else + { + /* There are some unknown sections in the group. */ + _bfd_error_handler + /* xgettext:c-format */ + (_("%B: unknown type [%#x] section `%s' in group [%A]"), + abfd, + idx->shdr->sh_type, + bfd_elf_string_from_elf_section (abfd, + (elf_elfheader (abfd) + ->e_shstrndx), + idx->shdr->sh_name), + shdr->bfd_section); + result = FALSE; + } + } } + return result; } @@ -5115,7 +5132,7 @@ elf_sort_sections (const void *arg1, const void *arg2) else adjustment = vma_offset - off_offset; - which can can be collapsed into the expression below. */ + which can be collapsed into the expression below. */ static file_ptr vma_page_aligned_bias (bfd_vma vma, ufile_ptr off, bfd_vma maxpagesize) @@ -8954,7 +8971,7 @@ elfcore_maybe_make_sect (bfd *abfd, char *name, asection *sect) such a section already exists. - For the multi-threaded case, a section named "NAME/PID", where PID is elfcore_make_pid (abfd). - Both pseudosections have identical contents. */ + Both pseudosections have identical contents. */ bfd_boolean _bfd_elfcore_make_pseudosection (bfd *abfd, char *name, @@ -9681,14 +9698,14 @@ elfcore_grok_note (bfd *abfd, Elf_Internal_Note *note) case NT_S390_GS_CB: if (note->namesz == 6 && strcmp (note->namedata, "LINUX") == 0) - return elfcore_grok_s390_gs_bc (abfd, note); + return elfcore_grok_s390_gs_cb (abfd, note); else return TRUE; case NT_S390_GS_BC: if (note->namesz == 6 && strcmp (note->namedata, "LINUX") == 0) - return elfcore_grok_s390_gs_cb (abfd, note); + return elfcore_grok_s390_gs_bc (abfd, note); else return TRUE; @@ -9883,58 +9900,68 @@ elfcore_grok_freebsd_prstatus (bfd *abfd, Elf_Internal_Note *note) { size_t offset; size_t size; + size_t min_size; - /* Check for version 1 in pr_version. */ - if (bfd_h_get_32 (abfd, (bfd_byte *) note->descdata) != 1) - return FALSE; - offset = 4; - - /* Skip over pr_statussz. */ + /* Compute offset of pr_getregsz, skipping over pr_statussz. + Also compute minimum size of this note. */ switch (elf_elfheader (abfd)->e_ident[EI_CLASS]) { case ELFCLASS32: - offset += 4; + offset = 4 + 4; + min_size = offset + (4 * 2) + 4 + 4 + 4; break; case ELFCLASS64: - offset += 4; /* Padding before pr_statussz. */ - offset += 8; + offset = 4 + 4 + 8; /* Includes padding before pr_statussz. */ + min_size = offset + (8 * 2) + 4 + 4 + 4 + 4; break; default: return FALSE; } - /* Extract size of pr_reg from pr_gregsetsz. */ - if (elf_elfheader (abfd)->e_ident[EI_CLASS] == ELFCLASS32) - size = bfd_h_get_32 (abfd, (bfd_byte *) note->descdata + offset); - else - size = bfd_h_get_64 (abfd, (bfd_byte *) note->descdata + offset); + if (note->descsz < min_size) + return FALSE; - /* Skip over pr_gregsetsz and pr_fpregsetsz. */ + /* Check for version 1 in pr_version. */ + if (bfd_h_get_32 (abfd, (bfd_byte *) note->descdata) != 1) + return FALSE; + + /* Extract size of pr_reg from pr_gregsetsz. */ + /* Skip over pr_gregsetsz and pr_fpregsetsz. */ if (elf_elfheader (abfd)->e_ident[EI_CLASS] == ELFCLASS32) - offset += 4 * 2; + { + size = bfd_h_get_32 (abfd, (bfd_byte *) note->descdata + offset); + offset += 4 * 2; + } else - offset += 8 * 2; + { + size = bfd_h_get_64 (abfd, (bfd_byte *) note->descdata + offset); + offset += 8 * 2; + } - /* Skip over pr_osreldate. */ + /* Skip over pr_osreldate. */ offset += 4; - /* Read signal from pr_cursig. */ + /* Read signal from pr_cursig. */ if (elf_tdata (abfd)->core->signal == 0) elf_tdata (abfd)->core->signal = bfd_h_get_32 (abfd, (bfd_byte *) note->descdata + offset); offset += 4; - /* Read TID from pr_pid. */ + /* Read TID from pr_pid. */ elf_tdata (abfd)->core->lwpid = bfd_h_get_32 (abfd, (bfd_byte *) note->descdata + offset); offset += 4; - /* Padding before pr_reg. */ + /* Padding before pr_reg. */ if (elf_elfheader (abfd)->e_ident[EI_CLASS] == ELFCLASS64) offset += 4; + /* Make sure that there is enough data remaining in the note. */ + if ((note->descsz - offset) < size) + return FALSE; + /* Make a ".reg/999" section and a ".reg" section. */ return _bfd_elfcore_make_pseudosection (abfd, ".reg", size, note->descpos + offset); @@ -9980,6 +10007,10 @@ elfcore_grok_freebsd_note (bfd *abfd, Elf_Internal_Note *note) else return TRUE; + case NT_FREEBSD_PTLWPINFO: + return elfcore_make_note_pseudosection (abfd, ".note.freebsdcore.lwpinfo", + note); + default: return TRUE; } @@ -10976,7 +11007,7 @@ elf_read_notes (bfd *abfd, file_ptr offset, bfd_size_type size) { char *buf; - if (size <= 0) + if (size == 0 || (size + 1) == 0) return TRUE; if (bfd_seek (abfd, offset, SEEK_SET) != 0) |