MFV r254746:

To quote original Illumos ticket:

libctf thinks that any ELF file containing more than 65536 sections is
corrupt, because it doesn't understand the SHN_XINDEX magic.

Illumos DTrace issues:
  4005 libctf can't deal with extended sections
This commit is contained in:
Xin LI 2013-08-23 23:58:56 +00:00
commit cc16dea626

View File

@ -216,6 +216,7 @@ 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;
@ -278,11 +279,10 @@ ctf_fdopen(int fd, int *errp)
#else
uchar_t order = ELFDATA2LSB;
#endif
GElf_Half i, n;
GElf_Shdr *sp;
void *strs_map;
size_t strs_mapsz;
size_t strs_mapsz, i;
char *strs;
if (hdr.e32.e_ident[EI_DATA] != order)
@ -298,11 +298,38 @@ ctf_fdopen(int fd, int *errp)
ehdr_to_gelf(&e32, &hdr.e64);
}
if (hdr.e64.e_shstrndx >= hdr.e64.e_shnum)
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));
n = hdr.e64.e_shnum;
nbytes = sizeof (GElf_Shdr) * n;
nbytes = sizeof (GElf_Shdr) * shnum;
if ((sp = malloc(nbytes)) == NULL)
return (ctf_set_open_errno(errp, errno));
@ -314,7 +341,7 @@ ctf_fdopen(int fd, int *errp)
if (hdr.e32.e_ident[EI_CLASS] == ELFCLASS32) {
Elf32_Shdr *sp32;
nbytes = sizeof (Elf32_Shdr) * n;
nbytes = sizeof (Elf32_Shdr) * shnum;
if ((sp32 = malloc(nbytes)) == NULL || pread64(fd,
sp32, nbytes, hdr.e64.e_shoff) != nbytes) {
@ -322,7 +349,7 @@ ctf_fdopen(int fd, int *errp)
return (ctf_set_open_errno(errp, errno));
}
for (i = 0; i < n; i++)
for (i = 0; i < shnum; i++)
shdr_to_gelf(&sp32[i], &sp[i]);
free(sp32);
@ -336,14 +363,14 @@ ctf_fdopen(int fd, int *errp)
* 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_mapsz = sp[shstrndx].sh_size +
(sp[shstrndx].sh_offset & ~_PAGEMASK);
strs_map = mmap64(NULL, strs_mapsz, PROT_READ, MAP_PRIVATE,
fd, sp[hdr.e64.e_shstrndx].sh_offset & _PAGEMASK);
fd, sp[shstrndx].sh_offset & _PAGEMASK);
strs = (char *)strs_map +
(sp[hdr.e64.e_shstrndx].sh_offset & ~_PAGEMASK);
(sp[shstrndx].sh_offset & ~_PAGEMASK);
if (strs_map == MAP_FAILED) {
free(sp);
@ -354,15 +381,15 @@ ctf_fdopen(int fd, int *errp)
* 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++) {
for (i = 0; i < shnum; i++) {
const GElf_Shdr *shp = &sp[i];
const GElf_Shdr *lhp = &sp[shp->sh_link];
if (shp->sh_link >= hdr.e64.e_shnum)
if (shp->sh_link >= 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)
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 &&