]> git.ipfire.org Git - thirdparty/elfutils.git/commitdiff
libdw: Only read CIE augmentation data if it is there
authorMark Wielaard <mark@klomp.org>
Sat, 11 Jul 2026 14:35:56 +0000 (16:35 +0200)
committerMark Wielaard <mark@klomp.org>
Sat, 11 Jul 2026 14:35:56 +0000 (16:35 +0200)
dwarf_next_cfi and intern_new_cie used slightly different methods
parsing the CIE augmentation data. Make sure both only read
augmentation data when it is there.

* libdw/cie.c (intern_new_cie): Check 'z' is the first char of
the augmentation. Only read augmentation data if
cie->sized_augmentation_data is set.
* libdw/dwarf_next_cfi.c (dwarf_next_cfi): Check limit for 'R'.

https://sourceware.org/bugzilla/show_bug.cgi?id=34387

Reported-by: Karan Kurani <karankurani3k@gmail.com>
Signed-off-by: Mark Wielaard <mark@klomp.org>
libdw/cie.c
libdw/dwarf_next_cfi.c

index 9753d9b97027da32018866f6cfe69e7872ebf6dc..052a704ec2d8520c160421f045afa030bec01c73 100644 (file)
@@ -74,21 +74,25 @@ intern_new_cie (Dwarf_CFI *cache, Dwarf_Off offset, const Dwarf_CIE *info)
 
   /* Grok the augmentation string and its data.  */
   const uint8_t *data = info->augmentation_data;
-  for (const char *ap = info->augmentation; *ap != '\0'; ++ap)
+  const char *ap = info->augmentation;
+  /* If present, 'z' must be the first char.  */
+  if (*ap == 'z')
+    {
+      cie->sized_augmentation_data = true;
+      ap++;
+    }
+  for (; *ap != '\0'; ++ap)
     {
       uint8_t encoding;
       switch (*ap)
        {
-       case 'z':
-         cie->sized_augmentation_data = true;
-         continue;
-
        case 'S':
          cie->signal_frame = true;
          continue;
 
        case 'L':               /* LSDA pointer encoding byte.  */
-         cie->lsda_encoding = *data++;
+         if (cie->sized_augmentation_data)
+           cie->lsda_encoding = *data++;
          if (!cie->sized_augmentation_data)
            cie->fde_augmentation_data_size
              += encoded_value_size (&cache->data->d, cache->e_ident,
@@ -96,13 +100,17 @@ intern_new_cie (Dwarf_CFI *cache, Dwarf_Off offset, const Dwarf_CIE *info)
          continue;
 
        case 'R':               /* FDE address encoding byte.  */
-         cie->fde_encoding = *data++;
+         if (cie->sized_augmentation_data)
+           cie->fde_encoding = *data++;
          continue;
 
        case 'P':               /* Skip personality routine.  */
-         encoding = *data++;
-         data += encoded_value_size (&cache->data->d, cache->e_ident,
-                                     encoding, data);
+         if (cie->sized_augmentation_data)
+           {
+             encoding = *data++;
+             data += encoded_value_size (&cache->data->d, cache->e_ident,
+                                         encoding, data);
+           }
          continue;
 
        default:
index 5bb74b8a0d66feb0369c316f6699e97eda386f7e..4ac64554023b9a813d18b3c246a2b07944bf7c39 100644 (file)
@@ -228,6 +228,8 @@ dwarf_next_cfi (const unsigned char e_ident[],
              if (sized_augmentation)
                {
                  /* Skip FDE address encoding byte.  */
+                 if (bytes >= limit)
+                   goto invalid;
                  bytes++;
                  continue;
                }