summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorUlrich Drepper <drepper@gmail.com>2022-08-11 15:17:33 +0200
committerUlrich Drepper <drepper@gmail.com>2022-08-11 15:17:33 +0200
commit27447fbc646e2a5abdf6af26967d829847180507 (patch)
tree524c1b663959b6df86e05cf796acd76d20aa8d8d
parent2f275fc12127db031592752136f077f5f3f3d273 (diff)
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/ChangeLog5
-rw-r--r--libdw/dwarf_next_cfi.c61
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;