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);
}