Print this page
5547 libproc's fake_elf should give up if there's no .hash
5546 libproc's fake_elf may free stack junk when reading corrupt dumps


 232         /*
 233          * Mask of dynamic options that must be present in a well
 234          * formed dynamic section. We need all of these in order to
 235          * put together a complete set of elf sections. They are
 236          * mandatory in both executables and shared objects so if one
 237          * of them is missing, we're in some trouble and should abort.
 238          * The PLT items are expected, but we will let them slide if
 239          * need be. The DI_SUNW_SYM* items are completely optional, so
 240          * we use them if they are present and ignore them otherwise.
 241          */
 242         const int di_req_mask = (1 << DI_SYMTAB) | (1 << DI_HASH) |
 243                 (1 << DI_SYMENT) | (1 << DI_STRTAB) | (1 << DI_STRSZ);
 244         int di_mask = 0;
 245         size_t size = 0;
 246         caddr_t elfdata = NULL;
 247         Elf *elf;
 248         size_t dynsym_size = 0, ldynsym_size;
 249         int dynstr_shndx;
 250         Ehdr *ep;
 251         Shdr *sp;
 252         Dyn *dp;
 253         Dyn *d[DI_NENT] = { 0 };
 254         uint_t i;
 255         Off off;
 256         size_t pltsz = 0, pltentries = 0;
 257         uintptr_t hptr = NULL;
 258         Word hnchains, hnbuckets;
 259 
 260         if (ehdr->e_type == ET_DYN)
 261                 phdr->p_vaddr += addr;
 262 
 263         if (P->rap != NULL) {
 264                 if (rd_get_dyns(P->rap, addr, (void **)&dp, NULL) != RD_OK)
 265                         goto bad;
 266         } else {
 267                 if ((dp = malloc(phdr->p_filesz)) == NULL)
 268                         goto bad;
 269                 if (Pread(P, dp, phdr->p_filesz, phdr->p_vaddr) !=
 270                     phdr->p_filesz)
 271                         goto bad;
 272         }


 349         size += sizeof (Shdr);
 350         size += roundup(sizeof (shstr), SH_ADDRALIGN);
 351 
 352         if (d[DI_HASH] != NULL) {
 353                 Word hash[2];
 354 
 355                 hptr = d[DI_HASH]->d_un.d_ptr;
 356                 if (ehdr->e_type == ET_DYN)
 357                         hptr += addr;
 358 
 359                 if (Pread(P, hash, sizeof (hash), hptr) != sizeof (hash)) {
 360                         dprintf("Pread of .hash at %lx failed\n",
 361                             (long)(hptr));
 362                         goto bad;
 363                 }
 364 
 365                 hnbuckets = hash[0];
 366                 hnchains = hash[1];
 367         }
 368 





 369         /*
 370          * .dynsym and .SUNW_ldynsym sections.
 371          *
 372          * The string table section used for the symbol table and
 373          * dynamic sections lies immediately after the dynsym, so the
 374          * presence of SUNW_ldynsym changes the dynstr section index.
 375          */
 376         if (d[DI_SUNW_SYMTAB] != NULL) {
 377                 size += sizeof (Shdr);  /* SUNW_ldynsym shdr */
 378                 ldynsym_size = (size_t)d[DI_SUNW_SYMSZ]->d_un.d_val;
 379                 dynsym_size = ldynsym_size - (d[DI_SYMTAB]->d_un.d_ptr
 380                     - d[DI_SUNW_SYMTAB]->d_un.d_ptr);
 381                 ldynsym_size -= dynsym_size;
 382                 dynstr_shndx = 4;
 383         } else {
 384                 dynsym_size = sizeof (Sym) * hnchains;
 385                 ldynsym_size = 0;
 386                 dynstr_shndx = 3;
 387         }
 388         size += sizeof (Shdr) + ldynsym_size + dynsym_size;




 232         /*
 233          * Mask of dynamic options that must be present in a well
 234          * formed dynamic section. We need all of these in order to
 235          * put together a complete set of elf sections. They are
 236          * mandatory in both executables and shared objects so if one
 237          * of them is missing, we're in some trouble and should abort.
 238          * The PLT items are expected, but we will let them slide if
 239          * need be. The DI_SUNW_SYM* items are completely optional, so
 240          * we use them if they are present and ignore them otherwise.
 241          */
 242         const int di_req_mask = (1 << DI_SYMTAB) | (1 << DI_HASH) |
 243                 (1 << DI_SYMENT) | (1 << DI_STRTAB) | (1 << DI_STRSZ);
 244         int di_mask = 0;
 245         size_t size = 0;
 246         caddr_t elfdata = NULL;
 247         Elf *elf;
 248         size_t dynsym_size = 0, ldynsym_size;
 249         int dynstr_shndx;
 250         Ehdr *ep;
 251         Shdr *sp;
 252         Dyn *dp = NULL;
 253         Dyn *d[DI_NENT] = { 0 };
 254         uint_t i;
 255         Off off;
 256         size_t pltsz = 0, pltentries = 0;
 257         uintptr_t hptr = NULL;
 258         Word hnchains, hnbuckets;
 259 
 260         if (ehdr->e_type == ET_DYN)
 261                 phdr->p_vaddr += addr;
 262 
 263         if (P->rap != NULL) {
 264                 if (rd_get_dyns(P->rap, addr, (void **)&dp, NULL) != RD_OK)
 265                         goto bad;
 266         } else {
 267                 if ((dp = malloc(phdr->p_filesz)) == NULL)
 268                         goto bad;
 269                 if (Pread(P, dp, phdr->p_filesz, phdr->p_vaddr) !=
 270                     phdr->p_filesz)
 271                         goto bad;
 272         }


 349         size += sizeof (Shdr);
 350         size += roundup(sizeof (shstr), SH_ADDRALIGN);
 351 
 352         if (d[DI_HASH] != NULL) {
 353                 Word hash[2];
 354 
 355                 hptr = d[DI_HASH]->d_un.d_ptr;
 356                 if (ehdr->e_type == ET_DYN)
 357                         hptr += addr;
 358 
 359                 if (Pread(P, hash, sizeof (hash), hptr) != sizeof (hash)) {
 360                         dprintf("Pread of .hash at %lx failed\n",
 361                             (long)(hptr));
 362                         goto bad;
 363                 }
 364 
 365                 hnbuckets = hash[0];
 366                 hnchains = hash[1];
 367         }
 368 
 369         if ((d[DI_HASH] == NULL) || (hnbuckets == 0) || (hnchains == 0)) {
 370                 dprintf("empty or missing .hash\n");
 371                 goto bad;
 372         }
 373 
 374         /*
 375          * .dynsym and .SUNW_ldynsym sections.
 376          *
 377          * The string table section used for the symbol table and
 378          * dynamic sections lies immediately after the dynsym, so the
 379          * presence of SUNW_ldynsym changes the dynstr section index.
 380          */
 381         if (d[DI_SUNW_SYMTAB] != NULL) {
 382                 size += sizeof (Shdr);  /* SUNW_ldynsym shdr */
 383                 ldynsym_size = (size_t)d[DI_SUNW_SYMSZ]->d_un.d_val;
 384                 dynsym_size = ldynsym_size - (d[DI_SYMTAB]->d_un.d_ptr
 385                     - d[DI_SUNW_SYMTAB]->d_un.d_ptr);
 386                 ldynsym_size -= dynsym_size;
 387                 dynstr_shndx = 4;
 388         } else {
 389                 dynsym_size = sizeof (Sym) * hnchains;
 390                 ldynsym_size = 0;
 391                 dynstr_shndx = 3;
 392         }
 393         size += sizeof (Shdr) + ldynsym_size + dynsym_size;