Print this page
5688 ELF tools need to be more careful with dwarf data

Split Close
Expand all
Collapse all
          --- old/usr/src/cmd/sgs/libld/common/unwind.c
          +++ new/usr/src/cmd/sgs/libld/common/unwind.c
↓ open down ↓ 529 lines elided ↑ open up ↑
 530  530           *      4 bytes     fde_count           +4
 531  531           */
 532  532          /* LINTED */
 533  533          binarytable =  (uint_t *)(hdrdata + 12);
 534  534          first_unwind = 0;
 535  535          fde_count = 0;
 536  536  
 537  537          for (APLIST_TRAVERSE(ofl->ofl_unwind, idx, osp)) {
 538  538                  uchar_t         *data;
 539  539                  size_t          size;
 540      -                uint64_t        off = 0;
      540 +                uint64_t        off = 0, ujunk;
      541 +                int64_t         sjunk;
 541  542                  uint_t          cieRflag = 0, ciePflag = 0;
 542  543                  Shdr            *shdr;
 543  544  
 544  545                  /*
 545  546                   * remember first UNWIND section to
 546  547                   * point to in the frame_ptr entry.
 547  548                   */
 548  549                  if (first_unwind == 0)
 549  550                          first_unwind = osp;
 550  551  
↓ open down ↓ 43 lines elided ↑ open up ↑
 594  595  
 595  596                                  /*
 596  597                                   * augstr
 597  598                                   */
 598  599                                  cieaugstr = (char *)(&data[off + ndx]);
 599  600                                  ndx += strlen(cieaugstr) + 1;
 600  601  
 601  602                                  /*
 602  603                                   * calign & dalign
 603  604                                   */
 604      -                                (void) uleb_extract(&data[off], &ndx);
 605      -                                (void) sleb_extract(&data[off], &ndx);
      605 +                                if (uleb_extract(&data[off], &ndx,
      606 +                                    size - off, &ujunk) == DW_OVERFLOW) {
      607 +                                        ld_eprintf(ofl, ERR_FATAL,
      608 +                                            MSG_INTL(MSG_SCN_DWFOVRFLW),
      609 +                                            ofl->ofl_name,
      610 +                                            osp->os_name);
      611 +                                        return (S_ERROR);
      612 +                                }
      613 +
      614 +                                if (sleb_extract(&data[off], &ndx,
      615 +                                    size - off, &sjunk) == DW_OVERFLOW) {
      616 +                                        ld_eprintf(ofl, ERR_FATAL,
      617 +                                            MSG_INTL(MSG_SCN_DWFOVRFLW),
      618 +                                            ofl->ofl_name,
      619 +                                            osp->os_name);
      620 +                                        return (S_ERROR);
      621 +                                }
 606  622  
 607  623                                  /*
 608  624                                   * retreg
 609  625                                   */
 610      -                                if (cieversion == 1)
      626 +                                if (cieversion == 1) {
 611  627                                          ndx++;
 612      -                                else
 613      -                                        (void) uleb_extract(&data[off], &ndx);
      628 +                                } else {
      629 +                                        if (uleb_extract(&data[off], &ndx,
      630 +                                            size - off, &ujunk) ==
      631 +                                            DW_OVERFLOW) {
      632 +                                                ld_eprintf(ofl, ERR_FATAL,
      633 +                                                    MSG_INTL(MSG_SCN_DWFOVRFLW),
      634 +                                                    ofl->ofl_name,
      635 +                                                    osp->os_name);
      636 +                                                return (S_ERROR);
      637 +                                        }
      638 +                                }
 614  639                                  /*
 615  640                                   * we walk through the augmentation
 616  641                                   * section now looking for the Rflag
 617  642                                   */
 618  643                                  for (cieaugndx = 0; cieaugstr[cieaugndx];
 619  644                                      cieaugndx++) {
 620  645                                          /* BEGIN CSTYLED */
 621  646                                          switch (cieaugstr[cieaugndx]) {
 622  647                                          case 'z':
 623  648                                              /* size */
 624      -                                            (void) uleb_extract(&data[off],
 625      -                                                &ndx);
      649 +                                            if (uleb_extract(&data[off],
      650 +                                                &ndx, size - off, &ujunk) ==
      651 +                                                DW_OVERFLOW) {
      652 +                                                ld_eprintf(ofl, ERR_FATAL,
      653 +                                                    MSG_INTL(MSG_SCN_DWFOVRFLW),
      654 +                                                    ofl->ofl_name,
      655 +                                                    osp->os_name);
      656 +                                                return (S_ERROR);
      657 +                                            }
 626  658                                              break;
 627  659                                          case 'P':
 628  660                                              /* personality */
 629  661                                              ciePflag = data[off + ndx];
 630  662                                              ndx++;
 631  663                                                  /*
 632  664                                                   * Just need to extract the
 633  665                                                   * value to move on to the next
 634  666                                                   * field.
 635  667                                                   */
 636      -                                            (void) dwarf_ehe_extract(
 637      -                                                &data[off],
 638      -                                                &ndx, ciePflag,
      668 +                                            switch (dwarf_ehe_extract(
      669 +                                                &data[off], size - off,
      670 +                                                &ndx, &ujunk, ciePflag,
 639  671                                                  ofl->ofl_dehdr->e_ident, B_FALSE,
 640      -                                                shdr->sh_addr, off + ndx, 0);
      672 +                                                shdr->sh_addr, off + ndx, 0)) {
      673 +                                            case DW_OVERFLOW:
      674 +                                                ld_eprintf(ofl, ERR_FATAL,
      675 +                                                    MSG_INTL(MSG_SCN_DWFOVRFLW),
      676 +                                                    ofl->ofl_name,
      677 +                                                    osp->os_name);
      678 +                                                return (S_ERROR);
      679 +                                            case DW_BAD_ENCODING:
      680 +                                                ld_eprintf(ofl, ERR_FATAL,
      681 +                                                    MSG_INTL(MSG_SCN_DWFBADENC),
      682 +                                                    ofl->ofl_name,
      683 +                                                    osp->os_name, ciePflag);
      684 +                                                return (S_ERROR);
      685 +                                            case DW_SUCCESS:
      686 +                                                break;
      687 +                                            }
 641  688                                              break;
 642  689                                          case 'R':
 643  690                                              /* code encoding */
 644  691                                              cieRflag = data[off + ndx];
 645  692                                              ndx++;
 646  693                                              break;
 647  694                                          case 'L':
 648  695                                              /* lsda encoding */
 649  696                                              ndx++;
 650  697                                              break;
↓ open down ↓ 3 lines elided ↑ open up ↑
 654  701                          } else {
 655  702                                  uint_t      bintabndx;
 656  703                                  uint64_t    initloc;
 657  704                                  uint64_t    fdeaddr;
 658  705                                  uint64_t    gotaddr = 0;
 659  706  
 660  707                                  if (ofl->ofl_osgot != NULL)
 661  708                                          gotaddr =
 662  709                                              ofl->ofl_osgot->os_shdr->sh_addr;
 663  710  
 664      -                                initloc = dwarf_ehe_extract(&data[off],
 665      -                                    &ndx, cieRflag, ofl->ofl_dehdr->e_ident,
 666      -                                    B_FALSE,
 667      -                                    shdr->sh_addr, off + ndx,
 668      -                                    gotaddr);
      711 +                                switch (dwarf_ehe_extract(&data[off],
      712 +                                    size - off, &ndx, &initloc, cieRflag,
      713 +                                    ofl->ofl_dehdr->e_ident, B_FALSE,
      714 +                                    shdr->sh_addr, off + ndx, gotaddr)) {
      715 +                                case DW_OVERFLOW:
      716 +                                        ld_eprintf(ofl, ERR_FATAL,
      717 +                                            MSG_INTL(MSG_SCN_DWFOVRFLW),
      718 +                                            ofl->ofl_name,
      719 +                                            osp->os_name);
      720 +                                        return (S_ERROR);
      721 +                                case DW_BAD_ENCODING:
      722 +                                        ld_eprintf(ofl, ERR_FATAL,
      723 +                                            MSG_INTL(MSG_SCN_DWFBADENC),
      724 +                                            ofl->ofl_name,
      725 +                                            osp->os_name, cieRflag);
      726 +                                        return (S_ERROR);
      727 +                                case DW_SUCCESS:
      728 +                                        break;
      729 +                                }
 669  730  
 670  731                                  /*
 671  732                                   * Ignore FDEs with initloc set to 0.
 672  733                                   * initloc will not be 0 unless this FDE was
 673  734                                   * abandoned due to GNU linkonce processing.
 674  735                                   * The 0 value occurs because we don't resolve
 675  736                                   * sloppy relocations for unwind header target
 676  737                                   * sections.
 677  738                                   */
 678  739                                  if (initloc != 0) {
↓ open down ↓ 118 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX