diff options
author | Ulrich Drepper <drepper@gmail.com> | 2022-08-11 15:17:33 +0200 |
---|---|---|
committer | Ulrich Drepper <drepper@gmail.com> | 2022-08-11 15:17:33 +0200 |
commit | 27447fbc646e2a5abdf6af26967d829847180507 (patch) | |
tree | 524c1b663959b6df86e05cf796acd76d20aa8d8d | |
parent | 2f275fc12127db031592752136f077f5f3f3d273 (diff) | |
download | elfutils-27447fbc646e2a5abdf6af26967d829847180507.tar.gz |
Fill in fde_augmentation_data_size in dwarf_next_cfi
(dwarf_next_cfi): Don't skip processing the augmentation string.
Be more stringent what to accept.
-rw-r--r-- | libdw/ChangeLog | 5 | ||||
-rw-r--r-- | libdw/dwarf_next_cfi.c | 61 |
2 files changed, 46 insertions, 20 deletions
diff --git a/libdw/ChangeLog b/libdw/ChangeLog index c9d94e0b..dd54afc2 100644 --- a/libdw/ChangeLog +++ b/libdw/ChangeLog @@ -1,3 +1,8 @@ +2022-08-09 Ulrich Drepper <drepper@redhat.com> + + * dwarf_next_cfi.c (dwarf_next_cfi): Don't skip processing the + augmentation string. Be more stringent what to accept. + 2022-07-28 Di Chen <dichen@redhat.com> * libdw.map (ELFUTILS_0.188): Add dwfl_frame_reg. diff --git a/libdw/dwarf_next_cfi.c b/libdw/dwarf_next_cfi.c index fa28d99b..23b16885 100644 --- a/libdw/dwarf_next_cfi.c +++ b/libdw/dwarf_next_cfi.c @@ -193,50 +193,71 @@ dwarf_next_cfi (const unsigned char e_ident[], else /* DWARF 2 */ entry->cie.return_address_register = *bytes++; - /* If we have sized augmentation data, - we don't need to grok it all. */ entry->cie.fde_augmentation_data_size = 0; + entry->cie.augmentation_data = bytes; bool sized_augmentation = *ap == 'z'; if (sized_augmentation) { + ++ap; if (bytes >= limit) goto invalid; get_uleb128 (entry->cie.augmentation_data_size, bytes, limit); if ((Dwarf_Word) (limit - bytes) < entry->cie.augmentation_data_size) goto invalid; entry->cie.augmentation_data = bytes; - bytes += entry->cie.augmentation_data_size; } - else - { - entry->cie.augmentation_data = bytes; - for (; *ap != '\0'; ++ap) + for (; *ap != '\0'; ++ap) + { + uint8_t encoding; + switch (*ap) { - uint8_t encoding; - switch (*ap) + case 'L': + if (sized_augmentation) { - case 'L': /* Skip LSDA pointer encoding byte. */ - case 'R': /* Skip FDE address encoding byte. */ + /* Skip LSDA pointer encoding byte. */ encoding = *bytes++; entry->cie.fde_augmentation_data_size += encoded_value_size (data, e_ident, encoding, NULL); continue; - case 'P': /* Skip encoded personality routine pointer. */ + } + break; + case 'R': + if (sized_augmentation) + { + /* Skip FDE address encoding byte. */ encoding = *bytes++; - bytes += encoded_value_size (data, e_ident, encoding, bytes); continue; - case 'S': /* Skip signal-frame flag. */ + } + break; + case 'P': + if (sized_augmentation) + { + /* Skip encoded personality routine pointer. */ + encoding = *bytes++; + bytes += encoded_value_size (data, e_ident, encoding, bytes); continue; - default: - /* Unknown augmentation string. initial_instructions might - actually start with some augmentation data. */ - break; } break; + case 'S': + if (sized_augmentation) + /* Skip signal-frame flag. */ + continue; + break; + default: + /* Unknown augmentation string. initial_instructions might + actually start with some augmentation data. */ + break; } - entry->cie.augmentation_data_size - = bytes - entry->cie.augmentation_data; + break; + } + if (! sized_augmentation) + entry->cie.augmentation_data_size = bytes - entry->cie.augmentation_data; + else + { + if (bytes > entry->cie.augmentation_data + entry->cie.augmentation_data_size) + goto invalid; + bytes = entry->cie.augmentation_data + entry->cie.augmentation_data_size; } entry->cie.initial_instructions = bytes; |