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

*** 97,118 **** * DW_EH_PE_indirect 0x80 bit to signal indirection after relocation * DW_EH_PE_omit 0xff No value is present. * */ ! uint64_t ! uleb_extract(unsigned char *data, uint64_t *dotp) { uint64_t dot = *dotp; uint64_t res = 0; int more = 1; int shift = 0; int val; data += dot; while (more) { /* * Pull off lower 7 bits */ val = (*data) & 0x7f; --- 97,121 ---- * DW_EH_PE_indirect 0x80 bit to signal indirection after relocation * DW_EH_PE_omit 0xff No value is present. * */ ! dwarf_error_t ! uleb_extract(unsigned char *data, uint64_t *dotp, size_t len, uint64_t *ret) { uint64_t dot = *dotp; uint64_t res = 0; int more = 1; int shift = 0; int val; data += dot; while (more) { + if (dot > len) + return (DW_OVERFLOW); + /* * Pull off lower 7 bits */ val = (*data) & 0x7f;
*** 132,156 **** * is the last byte. */ more = ((*data++) & 0x80) >> 7; } *dotp = dot; ! return (res); } ! int64_t ! sleb_extract(unsigned char *data, uint64_t *dotp) { uint64_t dot = *dotp; int64_t res = 0; int more = 1; int shift = 0; int val; data += dot; while (more) { /* * Pull off lower 7 bits */ val = (*data) & 0x7f; --- 135,163 ---- * is the last byte. */ more = ((*data++) & 0x80) >> 7; } *dotp = dot; ! *ret = res; ! return (DW_SUCCESS); } ! dwarf_error_t ! sleb_extract(unsigned char *data, uint64_t *dotp, size_t len, int64_t *ret) { uint64_t dot = *dotp; int64_t res = 0; int more = 1; int shift = 0; int val; data += dot; while (more) { + if (dot > len) + return (DW_OVERFLOW); + /* * Pull off lower 7 bits */ val = (*data) & 0x7f;
*** 175,186 **** /* * Make sure value is properly sign extended. */ res = (res << (64 - shift)) >> (64 - shift); ! ! return (res); } /* * Extract a DWARF encoded datum * --- 182,193 ---- /* * Make sure value is properly sign extended. */ res = (res << (64 - shift)) >> (64 - shift); ! *ret = res; ! return (DW_SUCCESS); } /* * Extract a DWARF encoded datum *
*** 194,207 **** * sh_base - Base address of ELF section containing desired datum * sh_offset - Offset relative to sh_base of desired datum. * dbase - The base address to which DW_EH_PE_datarel is relative * (if frame_hdr is false) */ ! uint64_t ! dwarf_ehe_extract(unsigned char *data, uint64_t *dotp, uint_t ehe_flags, ! unsigned char *eident, boolean_t frame_hdr, uint64_t sh_base, ! uint64_t sh_offset, uint64_t dbase) { uint64_t dot = *dotp; uint_t lsb; uint_t wordsize; uint_t fsize; --- 201,215 ---- * sh_base - Base address of ELF section containing desired datum * sh_offset - Offset relative to sh_base of desired datum. * dbase - The base address to which DW_EH_PE_datarel is relative * (if frame_hdr is false) */ ! dwarf_error_t ! dwarf_ehe_extract(unsigned char *data, size_t len, uint64_t *dotp, ! uint64_t *ret, uint_t ehe_flags, unsigned char *eident, ! boolean_t frame_hdr, uint64_t sh_base, uint64_t sh_offset, ! uint64_t dbase) { uint64_t dot = *dotp; uint_t lsb; uint_t wordsize; uint_t fsize;
*** 217,227 **** else wordsize = 4; switch (ehe_flags & 0x0f) { case DW_EH_PE_omit: ! return (0); case DW_EH_PE_absptr: fsize = wordsize; break; case DW_EH_PE_udata8: case DW_EH_PE_sdata8: --- 225,236 ---- else wordsize = 4; switch (ehe_flags & 0x0f) { case DW_EH_PE_omit: ! *ret = 0; ! return (DW_SUCCESS); case DW_EH_PE_absptr: fsize = wordsize; break; case DW_EH_PE_udata8: case DW_EH_PE_sdata8:
*** 234,248 **** case DW_EH_PE_udata2: case DW_EH_PE_sdata2: fsize = 2; break; case DW_EH_PE_uleb128: ! return (uleb_extract(data, dotp)); case DW_EH_PE_sleb128: ! return ((uint64_t)sleb_extract(data, dotp)); default: ! return (0); } if (lsb) { /* * Extract unaligned LSB formated data --- 243,258 ---- case DW_EH_PE_udata2: case DW_EH_PE_sdata2: fsize = 2; break; case DW_EH_PE_uleb128: ! return (uleb_extract(data, dotp, len, ret)); case DW_EH_PE_sleb128: ! return (sleb_extract(data, dotp, len, (int64_t *)ret)); default: ! *ret = 0; ! return (DW_BAD_ENCODING); } if (lsb) { /* * Extract unaligned LSB formated data
*** 251,260 **** --- 261,273 ---- result = 0; for (cnt = 0; cnt < fsize; cnt++, dot++) { uint64_t val; + + if (dot > len) + return (DW_OVERFLOW); val = data[dot]; result |= val << (cnt * 8); } } else { /*
*** 263,272 **** --- 276,288 ---- uint_t cnt; result = 0; for (cnt = 0; cnt < fsize; cnt++, dot++) { uint64_t val; + + if (dot > len) + return (DW_OVERFLOW); val = data[dot]; result |= val << ((fsize - cnt - 1) * 8); } } /*
*** 305,311 **** /* Truncate the result to its specified size */ result = (result << ((sizeof (uint64_t) - fsize) * 8)) >> ((sizeof (uint64_t) - fsize) * 8); *dotp = dot; ! return (result); } --- 321,328 ---- /* Truncate the result to its specified size */ result = (result << ((sizeof (uint64_t) - fsize) * 8)) >> ((sizeof (uint64_t) - fsize) * 8); *dotp = dot; ! *ret = result; ! return (DW_SUCCESS); }