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;