Changeset 74883be5 in rtems


Ignore:
Timestamp:
May 13, 2019, 12:46:45 AM (6 days ago)
Author:
Chris Johns <chrisj@…>
Branches:
master
Children:
d0f627d
Parents:
0b698ba5
git-author:
Chris Johns <chrisj@…> (05/13/19 00:46:45)
git-committer:
Chris Johns <chrisj@…> (05/13/19 22:54:19)
Message:

libdl: Fix loading symbol that reference unknown sections.

  • Make the symbol parsing and loading stage match.
  • Check for possible overflow of the tables when loading.

Closes #3746

File:
1 edited

Legend:

Unmodified
Added
Removed
  • cpukit/libdl/rtl-elf.c

    r0b698ba5 r74883be5  
    5151  .flags = RTEMS_RTL_FMT_ELF
    5252};
     53
     54static const char*
     55rtems_rtl_elf_sym_type_label (Elf_Byte st_info)
     56{
     57  const char* label;
     58  switch (ELF_ST_TYPE (st_info))
     59  {
     60    case STT_NOTYPE:
     61      label = "STT_NOTYPE";
     62      break;
     63    case STT_OBJECT:
     64      label = "STT_OBJECT";
     65      break;
     66    case STT_FUNC:
     67      label = "STT_FUNC";
     68      break;
     69    case STT_SECTION:
     70      label = "STT_SECTION";
     71      break;
     72    case STT_FILE:
     73      label = "STT_FILE";
     74      break;
     75    case STT_COMMON:
     76      label = "STT_COMMON";
     77      break;
     78    case STT_TLS:
     79      label = "STT_TLS";
     80      break;
     81    default:
     82      label = "unknown";
     83      break;
     84  }
     85  return label;
     86}
     87
     88static const char*
     89rtems_rtl_elf_sym_bind_label (Elf_Byte st_info)
     90{
     91  const char* label;
     92  switch (ELF_ST_BIND (st_info))
     93  {
     94    case STB_LOCAL:
     95      label = "STB_LOCAL";
     96      break;
     97    case STB_GLOBAL:
     98      label = "STB_GLOBAL";
     99      break;
     100    case STB_WEAK:
     101      label = "STB_WEAK";
     102      break;
     103    default:
     104      label = "unknown";
     105      break;
     106  }
     107  return label;
     108}
    53109
    54110static bool
     
    843899     */
    844900    if (rtems_rtl_trace (RTEMS_RTL_TRACE_SYMBOL))
    845       printf ("rtl: sym:elf:%-4d name:%-4d: %-20s: bind:%-2d " \
    846               "type:%-2d sect:%-5d size:%-5d value:%d\n",
     901      printf ("rtl: sym:elf:%-4d name:%-4d: %-20s: bind:%-2d:%-12s " \
     902              "type:%-2d:%-10s sect:%-5d size:%-5d value:%d\n",
    847903              sym, (int) symbol.st_name, name,
    848904              (int) ELF_ST_BIND (symbol.st_info),
     905              rtems_rtl_elf_sym_bind_label (symbol.st_info),
    849906              (int) ELF_ST_TYPE (symbol.st_info),
     907              rtems_rtl_elf_sym_type_label (symbol.st_info),
    850908              symbol.st_shndx,
    851909              (int) symbol.st_size,
     
    9991057          (ELF_ST_BIND (symbol.st_info) == STB_LOCAL)))
    10001058    {
    1001       rtems_rtl_obj_sym* osym;
    1002       char*              string;
    1003       Elf_Word           value;
    1004       const char*        name;
    1005 
    1006       off = obj->ooffset + strtab->offset + symbol.st_name;
    1007       len = RTEMS_RTL_ELF_STRING_MAX;
    1008 
    1009       if (!rtems_rtl_obj_cache_read (strings, fd, off, (void**) &name, &len))
    1010         return false;
     1059      rtems_rtl_obj_sect* symsect;
    10111060
    10121061      /*
    1013        * If a duplicate forget it.
     1062       * There needs to be a valid section for the symbol.
    10141063       */
    1015       if (rtems_rtl_symbol_global_find (name))
    1016         continue;
    1017 
    1018       if ((ELF_ST_BIND (symbol.st_info) == STB_GLOBAL) ||
    1019           (ELF_ST_BIND (symbol.st_info) == STB_WEAK))
     1064      symsect = rtems_rtl_obj_find_section_by_index (obj, symbol.st_shndx);
     1065
     1066      if (symsect != NULL)
    10201067      {
    1021         osym = gsym;
    1022         string = gstring;
    1023         gstring += strlen (name) + 1;
    1024         ++gsym;
     1068        rtems_rtl_obj_sym*  osym;
     1069        char*               string;
     1070        Elf_Word            value;
     1071        const char*         name;
     1072
     1073        off = obj->ooffset + strtab->offset + symbol.st_name;
     1074        len = RTEMS_RTL_ELF_STRING_MAX;
     1075
     1076        if (!rtems_rtl_obj_cache_read (strings, fd, off, (void**) &name, &len))
     1077          return false;
     1078
     1079        /*
     1080         * If a duplicate forget it.
     1081         */
     1082        if (rtems_rtl_symbol_global_find (name))
     1083          continue;
     1084
     1085        if ((ELF_ST_BIND (symbol.st_info) == STB_GLOBAL) ||
     1086            (ELF_ST_BIND (symbol.st_info) == STB_WEAK))
     1087        {
     1088          size_t slen = strlen (name) + 1;
     1089          if ((gstring + slen) > (char*) obj->global_table + obj->global_size)
     1090            string = NULL;
     1091          else
     1092          {
     1093            osym = gsym;
     1094            string = gstring;
     1095            gstring += slen + 1;
     1096            ++gsym;
     1097          }
     1098        }
     1099        else
     1100        {
     1101          size_t slen = strlen (name) + 1;
     1102          if ((lstring + slen) > (char*) obj->local_table + obj->local_size)
     1103            string = NULL;
     1104          else
     1105          {
     1106            osym = lsym;
     1107            string = lstring;
     1108            lstring += slen + 1;
     1109            ++lsym;
     1110          }
     1111        }
     1112
     1113        /*
     1114         * See if the loading has overflowed the allocated tables.
     1115         */
     1116        if (string == NULL)
     1117        {
     1118          if (obj->local_syms)
     1119          {
     1120            rtems_rtl_alloc_del (RTEMS_RTL_ALLOC_SYMBOL, obj->local_table);
     1121            obj->local_table = NULL;
     1122            obj->local_size = 0;
     1123            obj->local_syms = 0;
     1124          }
     1125          if (obj->global_syms)
     1126          {
     1127            rtems_rtl_alloc_del (RTEMS_RTL_ALLOC_SYMBOL, obj->global_table);
     1128            obj->global_table = NULL;
     1129            obj->global_syms = 0;
     1130            obj->global_size = 0;
     1131          }
     1132          rtems_rtl_set_error (ENOMEM, "syms overlow, parsing/loading size mismatch");
     1133          return false;
     1134        }
     1135
     1136        /*
     1137         * Allocate any common symbols in the common section.
     1138         */
     1139        if (symbol.st_shndx == SHN_COMMON)
     1140        {
     1141          size_t value_off = rtems_rtl_obj_align (common_offset,
     1142                                                  symbol.st_value);
     1143          common_offset = value_off + symbol.st_size;
     1144          value = value_off;
     1145        }
     1146        else
     1147        {
     1148          value = symbol.st_value;
     1149        }
     1150
     1151        rtems_chain_set_off_chain (&osym->node);
     1152        memcpy (string, name, strlen (name) + 1);
     1153        osym->name = string;
     1154        osym->value = (uint8_t*) value;
     1155        osym->data = symbol.st_shndx;
     1156
     1157        if (rtems_rtl_trace (RTEMS_RTL_TRACE_SYMBOL))
     1158          printf ("rtl: sym:add:%-4d name:%-4d: %-20s: bind:%-2d " \
     1159                  "type:%-2d val:%-8p sect:%-3d size:%d\n",
     1160                  sym, (int) symbol.st_name, osym->name,
     1161                  (int) ELF_ST_BIND (symbol.st_info),
     1162                  (int) ELF_ST_TYPE (symbol.st_info),
     1163                  osym->value, symbol.st_shndx,
     1164                  (int) symbol.st_size);
    10251165      }
    1026       else
    1027       {
    1028         osym = lsym;
    1029         string = lstring;
    1030         lstring += strlen (name) + 1;
    1031         ++lsym;
    1032       }
    1033 
    1034       /*
    1035        * Allocate any common symbols in the common section.
    1036        */
    1037       if (symbol.st_shndx == SHN_COMMON)
    1038       {
    1039         size_t value_off = rtems_rtl_obj_align (common_offset,
    1040                                                 symbol.st_value);
    1041         common_offset = value_off + symbol.st_size;
    1042         value = value_off;
    1043       }
    1044       else
    1045       {
    1046         value = symbol.st_value;
    1047       }
    1048 
    1049       rtems_chain_set_off_chain (&osym->node);
    1050       memcpy (string, name, strlen (name) + 1);
    1051       osym->name = string;
    1052       osym->value = (uint8_t*) value;
    1053       osym->data = symbol.st_shndx;
    1054 
    1055       if (rtems_rtl_trace (RTEMS_RTL_TRACE_SYMBOL))
    1056         printf ("rtl: sym:add:%-4d name:%-4d: %-20s: bind:%-2d " \
    1057                 "type:%-2d val:%-8p sect:%-3d size:%d\n",
    1058                 sym, (int) symbol.st_name, osym->name,
    1059                 (int) ELF_ST_BIND (symbol.st_info),
    1060                 (int) ELF_ST_TYPE (symbol.st_info),
    1061                 osym->value, symbol.st_shndx,
    1062                 (int) symbol.st_size);
    10631166    }
    10641167  }
Note: See TracChangeset for help on using the changeset viewer.