Print this page
4005 libctf can't deal with extended sections
*** 191,200 ****
--- 191,201 ----
ctf_file_t *
ctf_fdopen(int fd, int *errp)
{
ctf_sect_t ctfsect, symsect, strsect;
ctf_file_t *fp = NULL;
+ size_t shstrndx, shnum;
struct stat64 st;
ssize_t nbytes;
union {
*** 253,267 ****
#ifdef _BIG_ENDIAN
uchar_t order = ELFDATA2MSB;
#else
uchar_t order = ELFDATA2LSB;
#endif
- GElf_Half i, n;
GElf_Shdr *sp;
void *strs_map;
! size_t strs_mapsz;
const char *strs;
if (hdr.e32.e_ident[EI_DATA] != order)
return (ctf_set_open_errno(errp, ECTF_ENDIAN));
if (hdr.e32.e_version != EV_CURRENT)
--- 254,267 ----
#ifdef _BIG_ENDIAN
uchar_t order = ELFDATA2MSB;
#else
uchar_t order = ELFDATA2LSB;
#endif
GElf_Shdr *sp;
void *strs_map;
! size_t strs_mapsz, i;
const char *strs;
if (hdr.e32.e_ident[EI_DATA] != order)
return (ctf_set_open_errno(errp, ECTF_ENDIAN));
if (hdr.e32.e_version != EV_CURRENT)
*** 273,287 ****
} else {
Elf32_Ehdr e32 = hdr.e32;
ehdr_to_gelf(&e32, &hdr.e64);
}
! if (hdr.e64.e_shstrndx >= hdr.e64.e_shnum)
return (ctf_set_open_errno(errp, ECTF_CORRUPT));
! n = hdr.e64.e_shnum;
! nbytes = sizeof (GElf_Shdr) * n;
if ((sp = malloc(nbytes)) == NULL)
return (ctf_set_open_errno(errp, errno));
/*
--- 273,314 ----
} else {
Elf32_Ehdr e32 = hdr.e32;
ehdr_to_gelf(&e32, &hdr.e64);
}
! shnum = hdr.e64.e_shnum;
! shstrndx = hdr.e64.e_shstrndx;
!
! /* Extended ELF sections */
! if ((shstrndx == SHN_XINDEX) || (shnum == 0)) {
! if (hdr.e32.e_ident[EI_CLASS] == ELFCLASS32) {
! Elf32_Shdr x32;
!
! if (pread64(fd, &x32, sizeof (x32),
! hdr.e64.e_shoff) != sizeof (x32))
! return (ctf_set_open_errno(errp,
! errno));
!
! shnum = x32.sh_size;
! shstrndx = x32.sh_link;
! } else {
! Elf64_Shdr x64;
!
! if (pread64(fd, &x64, sizeof (x64),
! hdr.e64.e_shoff) != sizeof (x64))
! return (ctf_set_open_errno(errp,
! errno));
!
! shnum = x64.sh_size;
! shstrndx = x64.sh_link;
! }
! }
!
! if (shstrndx >= shnum)
return (ctf_set_open_errno(errp, ECTF_CORRUPT));
! nbytes = sizeof (GElf_Shdr) * shnum;
if ((sp = malloc(nbytes)) == NULL)
return (ctf_set_open_errno(errp, errno));
/*
*** 289,307 ****
* from e_shoff so we can locate sections of interest.
*/
if (hdr.e32.e_ident[EI_CLASS] == ELFCLASS32) {
Elf32_Shdr *sp32;
! nbytes = sizeof (Elf32_Shdr) * n;
if ((sp32 = malloc(nbytes)) == NULL || pread64(fd,
sp32, nbytes, hdr.e64.e_shoff) != nbytes) {
free(sp);
return (ctf_set_open_errno(errp, errno));
}
! for (i = 0; i < n; i++)
shdr_to_gelf(&sp32[i], &sp[i]);
free(sp32);
} else if (pread64(fd, sp, nbytes, hdr.e64.e_shoff) != nbytes) {
--- 316,334 ----
* from e_shoff so we can locate sections of interest.
*/
if (hdr.e32.e_ident[EI_CLASS] == ELFCLASS32) {
Elf32_Shdr *sp32;
! nbytes = sizeof (Elf32_Shdr) * shnum;
if ((sp32 = malloc(nbytes)) == NULL || pread64(fd,
sp32, nbytes, hdr.e64.e_shoff) != nbytes) {
free(sp);
return (ctf_set_open_errno(errp, errno));
}
! for (i = 0; i < shnum; i++)
shdr_to_gelf(&sp32[i], &sp[i]);
free(sp32);
} else if (pread64(fd, sp, nbytes, hdr.e64.e_shoff) != nbytes) {
*** 311,347 ****
/*
* Now mmap the section header strings section so that we can
* perform string comparison on the section names.
*/
! strs_mapsz = sp[hdr.e64.e_shstrndx].sh_size +
! (sp[hdr.e64.e_shstrndx].sh_offset & ~_PAGEMASK);
strs_map = mmap64(NULL, strs_mapsz, PROT_READ, MAP_PRIVATE,
! fd, sp[hdr.e64.e_shstrndx].sh_offset & _PAGEMASK);
strs = (const char *)strs_map +
! (sp[hdr.e64.e_shstrndx].sh_offset & ~_PAGEMASK);
if (strs_map == MAP_FAILED) {
free(sp);
return (ctf_set_open_errno(errp, ECTF_MMAP));
}
/*
* Iterate over the section header array looking for the CTF
* section and symbol table. The strtab is linked to symtab.
*/
! for (i = 0; i < n; i++) {
const GElf_Shdr *shp = &sp[i];
const GElf_Shdr *lhp = &sp[shp->sh_link];
! if (shp->sh_link >= hdr.e64.e_shnum)
continue; /* corrupt sh_link field */
! if (shp->sh_name >= sp[hdr.e64.e_shstrndx].sh_size ||
! lhp->sh_name >= sp[hdr.e64.e_shstrndx].sh_size)
continue; /* corrupt sh_name field */
if (shp->sh_type == SHT_PROGBITS &&
strcmp(strs + shp->sh_name, _CTF_SECTION) == 0) {
ctfsect.cts_name = strs + shp->sh_name;
--- 338,374 ----
/*
* Now mmap the section header strings section so that we can
* perform string comparison on the section names.
*/
! strs_mapsz = sp[shstrndx].sh_size +
! (sp[shstrndx].sh_offset & ~_PAGEMASK);
strs_map = mmap64(NULL, strs_mapsz, PROT_READ, MAP_PRIVATE,
! fd, sp[shstrndx].sh_offset & _PAGEMASK);
strs = (const char *)strs_map +
! (sp[shstrndx].sh_offset & ~_PAGEMASK);
if (strs_map == MAP_FAILED) {
free(sp);
return (ctf_set_open_errno(errp, ECTF_MMAP));
}
/*
* Iterate over the section header array looking for the CTF
* section and symbol table. The strtab is linked to symtab.
*/
! for (i = 0; i < shnum; i++) {
const GElf_Shdr *shp = &sp[i];
const GElf_Shdr *lhp = &sp[shp->sh_link];
! if (shp->sh_link >= shnum)
continue; /* corrupt sh_link field */
! if (shp->sh_name >= sp[shstrndx].sh_size ||
! lhp->sh_name >= sp[shstrndx].sh_size)
continue; /* corrupt sh_name field */
if (shp->sh_type == SHT_PROGBITS &&
strcmp(strs + shp->sh_name, _CTF_SECTION) == 0) {
ctfsect.cts_name = strs + shp->sh_name;