diff options
| author | pgowda <pgowda.cve@gmail.com> | 2022-09-21 23:09:17 +0530 |
|---|---|---|
| committer | Richard Purdie <richard.purdie@linuxfoundation.org> | 2022-09-22 12:11:49 +0100 |
| commit | 72d141568694ac4c2f9ac0919a4c791754fdb4d2 (patch) | |
| tree | 56a679750c3723b41b1c687662be0d0212ca44f2 /meta/recipes-devtools/binutils | |
| parent | 6505dd4ec25459c59f8c8b323058063bff81cb26 (diff) | |
| download | poky-72d141568694ac4c2f9ac0919a4c791754fdb4d2.tar.gz | |
binutils : Fix CVE-2022-38128
Upstream-Status: Backport [https://sourceware.org/git/?p=binutils-gdb.git;a=commitdiff;h=f07c08e115e27cddf5a0030dc6332bbee1bd9c6a]
Upstream-Status: Backport [https://sourceware.org/git/?p=binutils-gdb.git;a=commitdiff;h=175b91507b83ad42607d2f6dadaf55b7b511bdbe]
Upstream-Status: Backport [https://sourceware.org/git/?p=binutils-gdb.git;a=patch;h=695c6dfe7e85006b98c8b746f3fd5f913c94ebff]
(From OE-Core rev: b9348a0937185a14dfb5e5be4f4269c965541769)
Signed-off-by: pgowda <pgowda.cve@gmail.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Diffstat (limited to 'meta/recipes-devtools/binutils')
4 files changed, 984 insertions, 0 deletions
diff --git a/meta/recipes-devtools/binutils/binutils-2.39.inc b/meta/recipes-devtools/binutils/binutils-2.39.inc index e4fdb73243..b040e57037 100644 --- a/meta/recipes-devtools/binutils/binutils-2.39.inc +++ b/meta/recipes-devtools/binutils/binutils-2.39.inc | |||
| @@ -32,6 +32,9 @@ SRC_URI = "\ | |||
| 32 | file://0011-Check-for-clang-before-checking-gcc-version.patch \ | 32 | file://0011-Check-for-clang-before-checking-gcc-version.patch \ |
| 33 | file://0012-Only-generate-an-RPATH-entry-if-LD_RUN_PATH-is-not-e.patch \ | 33 | file://0012-Only-generate-an-RPATH-entry-if-LD_RUN_PATH-is-not-e.patch \ |
| 34 | file://0013-CVE-2022-38533.patch \ | 34 | file://0013-CVE-2022-38533.patch \ |
| 35 | file://0014-CVE-2022-38128-1.patch \ | ||
| 36 | file://0014-CVE-2022-38128-2.patch \ | ||
| 37 | file://0014-CVE-2022-38128-3.patch \ | ||
| 35 | " | 38 | " |
| 36 | S = "${WORKDIR}/git" | 39 | S = "${WORKDIR}/git" |
| 37 | # Already in 2.39 branch | 40 | # Already in 2.39 branch |
diff --git a/meta/recipes-devtools/binutils/binutils/0014-CVE-2022-38128-1.patch b/meta/recipes-devtools/binutils/binutils/0014-CVE-2022-38128-1.patch new file mode 100644 index 0000000000..0a490d86b3 --- /dev/null +++ b/meta/recipes-devtools/binutils/binutils/0014-CVE-2022-38128-1.patch | |||
| @@ -0,0 +1,350 @@ | |||
| 1 | From f07c08e115e27cddf5a0030dc6332bbee1bd9c6a Mon Sep 17 00:00:00 2001 | ||
| 2 | From: Alan Modra <amodra@gmail.com> | ||
| 3 | Date: Thu, 21 Jul 2022 08:38:14 +0930 | ||
| 4 | Subject: [PATCH] binutils/dwarf.c: abbrev caching | ||
| 5 | |||
| 6 | I'm inclined to think that abbrev caching is counter-productive. The | ||
| 7 | time taken to search the list of abbrevs converted to internal form is | ||
| 8 | non-zero, and it's easy to decode the raw abbrevs. It's especially | ||
| 9 | silly to cache empty lists of decoded abbrevs (happens with zero | ||
| 10 | padding in .debug_abbrev), or abbrevs as they are displayed when there | ||
| 11 | is no further use of those abbrevs. This patch stops caching in those | ||
| 12 | cases. | ||
| 13 | |||
| 14 | * dwarf.c (record_abbrev_list_for_cu): Add free_list param. | ||
| 15 | Put abbrevs on abbrev_lists here. | ||
| 16 | (new_abbrev_list): Delete function. | ||
| 17 | (process_abbrev_set): Return newly allocated list. Move | ||
| 18 | abbrev base, offset and size checking to.. | ||
| 19 | (find_and_process_abbrev_set): ..here, new function. Handle | ||
| 20 | lookup of cached abbrevs here, and calculate start and end | ||
| 21 | for process_abbrev_set. Return free_list if newly alloc'd. | ||
| 22 | (process_debug_info): Consolidate cached list lookup, new list | ||
| 23 | alloc and processing into find_and_process_abbrev_set call. | ||
| 24 | Free list when not cached. | ||
| 25 | (display_debug_abbrev): Similarly. | ||
| 26 | |||
| 27 | Upstream-Status: Backport [https://sourceware.org/git/?p=binutils-gdb.git;a=commitdiff;h=f07c08e115e27cddf5a0030dc6332bbee1bd9c6a] | ||
| 28 | |||
| 29 | Signed-off-by: Pgowda <pgowda.cve@gmail.com> | ||
| 30 | --- | ||
| 31 | binutils/dwarf.c | 208 +++++++++++++++++++++++++---------------------- | ||
| 32 | 1 file changed, 110 insertions(+), 98 deletions(-) | ||
| 33 | |||
| 34 | diff --git a/binutils/dwarf.c b/binutils/dwarf.c | ||
| 35 | index 267ed3bb382..2fc352f74c5 100644 | ||
| 36 | --- a/binutils/dwarf.c | ||
| 37 | +++ b/binutils/dwarf.c | ||
| 38 | @@ -882,8 +882,15 @@ static unsigned long next_free_abbrev_m | ||
| 39 | #define ABBREV_MAP_ENTRIES_INCREMENT 8 | ||
| 40 | |||
| 41 | static void | ||
| 42 | -record_abbrev_list_for_cu (dwarf_vma start, dwarf_vma end, abbrev_list * list) | ||
| 43 | +record_abbrev_list_for_cu (dwarf_vma start, dwarf_vma end, | ||
| 44 | + abbrev_list *list, abbrev_list *free_list) | ||
| 45 | { | ||
| 46 | + if (free_list != NULL) | ||
| 47 | + { | ||
| 48 | + list->next = abbrev_lists; | ||
| 49 | + abbrev_lists = list; | ||
| 50 | + } | ||
| 51 | + | ||
| 52 | if (cu_abbrev_map == NULL) | ||
| 53 | { | ||
| 54 | num_abbrev_map_entries = INITIAL_NUM_ABBREV_MAP_ENTRIES; | ||
| 55 | @@ -936,20 +943,6 @@ free_all_abbrevs (void) | ||
| 56 | } | ||
| 57 | |||
| 58 | static abbrev_list * | ||
| 59 | -new_abbrev_list (dwarf_vma abbrev_base, dwarf_vma abbrev_offset) | ||
| 60 | -{ | ||
| 61 | - abbrev_list * list = (abbrev_list *) xcalloc (sizeof * list, 1); | ||
| 62 | - | ||
| 63 | - list->abbrev_base = abbrev_base; | ||
| 64 | - list->abbrev_offset = abbrev_offset; | ||
| 65 | - | ||
| 66 | - list->next = abbrev_lists; | ||
| 67 | - abbrev_lists = list; | ||
| 68 | - | ||
| 69 | - return list; | ||
| 70 | -} | ||
| 71 | - | ||
| 72 | -static abbrev_list * | ||
| 73 | find_abbrev_list_by_abbrev_offset (dwarf_vma abbrev_base, | ||
| 74 | dwarf_vma abbrev_offset) | ||
| 75 | { | ||
| 76 | @@ -966,7 +959,7 @@ find_abbrev_list_by_abbrev_offset (dwarf | ||
| 77 | /* Find the abbreviation map for the CU that includes OFFSET. | ||
| 78 | OFFSET is an absolute offset from the start of the .debug_info section. */ | ||
| 79 | /* FIXME: This function is going to slow down readelf & objdump. | ||
| 80 | - Consider using a better algorithm to mitigate this effect. */ | ||
| 81 | + Not caching abbrevs is likely the answer. */ | ||
| 82 | |||
| 83 | static abbrev_map * | ||
| 84 | find_abbrev_map_by_offset (dwarf_vma offset) | ||
| 85 | @@ -1033,40 +1026,18 @@ add_abbrev_attr (unsigned long attrib | ||
| 86 | list->last_abbrev->last_attr = attr; | ||
| 87 | } | ||
| 88 | |||
| 89 | -/* Processes the (partial) contents of a .debug_abbrev section. | ||
| 90 | - Returns NULL if the end of the section was encountered. | ||
| 91 | - Returns the address after the last byte read if the end of | ||
| 92 | - an abbreviation set was found. */ | ||
| 93 | +/* Return processed (partial) contents of a .debug_abbrev section. | ||
| 94 | + Returns NULL on errors. */ | ||
| 95 | |||
| 96 | -static unsigned char * | ||
| 97 | +static abbrev_list * | ||
| 98 | process_abbrev_set (struct dwarf_section *section, | ||
| 99 | - dwarf_vma abbrev_base, | ||
| 100 | - dwarf_vma abbrev_size, | ||
| 101 | - dwarf_vma abbrev_offset, | ||
| 102 | - abbrev_list *list) | ||
| 103 | + unsigned char *start, | ||
| 104 | + unsigned char *end) | ||
| 105 | { | ||
| 106 | - if (abbrev_base >= section->size | ||
| 107 | - || abbrev_size > section->size - abbrev_base) | ||
| 108 | - { | ||
| 109 | - /* PR 17531: file:4bcd9ce9. */ | ||
| 110 | - warn (_("Debug info is corrupted, abbrev size (%lx) is larger than " | ||
| 111 | - "abbrev section size (%lx)\n"), | ||
| 112 | - (unsigned long) (abbrev_base + abbrev_size), | ||
| 113 | - (unsigned long) section->size); | ||
| 114 | - return NULL; | ||
| 115 | - } | ||
| 116 | - if (abbrev_offset >= abbrev_size) | ||
| 117 | - { | ||
| 118 | - warn (_("Debug info is corrupted, abbrev offset (%lx) is larger than " | ||
| 119 | - "abbrev section size (%lx)\n"), | ||
| 120 | - (unsigned long) abbrev_offset, | ||
| 121 | - (unsigned long) abbrev_size); | ||
| 122 | - return NULL; | ||
| 123 | - } | ||
| 124 | + abbrev_list *list = xmalloc (sizeof (*list)); | ||
| 125 | + list->first_abbrev = NULL; | ||
| 126 | + list->last_abbrev = NULL; | ||
| 127 | |||
| 128 | - unsigned char *start = section->start + abbrev_base; | ||
| 129 | - unsigned char *end = start + abbrev_size; | ||
| 130 | - start += abbrev_offset; | ||
| 131 | while (start < end) | ||
| 132 | { | ||
| 133 | unsigned long entry; | ||
| 134 | @@ -1079,14 +1050,18 @@ process_abbrev_set (struct dwarf_section | ||
| 135 | /* A single zero is supposed to end the set according | ||
| 136 | to the standard. If there's more, then signal that to | ||
| 137 | the caller. */ | ||
| 138 | - if (start == end) | ||
| 139 | - return NULL; | ||
| 140 | - if (entry == 0) | ||
| 141 | - return start; | ||
| 142 | + if (start == end || entry == 0) | ||
| 143 | + { | ||
| 144 | + list->start_of_next_abbrevs = start != end ? start : NULL; | ||
| 145 | + return list; | ||
| 146 | + } | ||
| 147 | |||
| 148 | READ_ULEB (tag, start, end); | ||
| 149 | if (start == end) | ||
| 150 | - return NULL; | ||
| 151 | + { | ||
| 152 | + free (list); | ||
| 153 | + return NULL; | ||
| 154 | + } | ||
| 155 | |||
| 156 | children = *start++; | ||
| 157 | |||
| 158 | @@ -1121,9 +1096,67 @@ process_abbrev_set (struct dwarf_section | ||
| 159 | /* Report the missing single zero which ends the section. */ | ||
| 160 | error (_(".debug_abbrev section not zero terminated\n")); | ||
| 161 | |||
| 162 | + free (list); | ||
| 163 | return NULL; | ||
| 164 | } | ||
| 165 | |||
| 166 | +/* Return a sequence of abbrevs in SECTION starting at ABBREV_BASE | ||
| 167 | + plus ABBREV_OFFSET and finishing at ABBREV_BASE + ABBREV_SIZE. | ||
| 168 | + If FREE_LIST is non-NULL search the already decoded abbrevs on | ||
| 169 | + abbrev_lists first and if found set *FREE_LIST to NULL. If | ||
| 170 | + searching doesn't find a matching abbrev, set *FREE_LIST to the | ||
| 171 | + newly allocated list. If FREE_LIST is NULL, no search is done and | ||
| 172 | + the returned abbrev_list is always newly allocated. */ | ||
| 173 | + | ||
| 174 | +static abbrev_list * | ||
| 175 | +find_and_process_abbrev_set (struct dwarf_section *section, | ||
| 176 | + dwarf_vma abbrev_base, | ||
| 177 | + dwarf_vma abbrev_size, | ||
| 178 | + dwarf_vma abbrev_offset, | ||
| 179 | + abbrev_list **free_list) | ||
| 180 | +{ | ||
| 181 | + if (free_list) | ||
| 182 | + *free_list = NULL; | ||
| 183 | + | ||
| 184 | + if (abbrev_base >= section->size | ||
| 185 | + || abbrev_size > section->size - abbrev_base) | ||
| 186 | + { | ||
| 187 | + /* PR 17531: file:4bcd9ce9. */ | ||
| 188 | + warn (_("Debug info is corrupted, abbrev size (%lx) is larger than " | ||
| 189 | + "abbrev section size (%lx)\n"), | ||
| 190 | + (unsigned long) (abbrev_base + abbrev_size), | ||
| 191 | + (unsigned long) section->size); | ||
| 192 | + return NULL; | ||
| 193 | + } | ||
| 194 | + if (abbrev_offset >= abbrev_size) | ||
| 195 | + { | ||
| 196 | + warn (_("Debug info is corrupted, abbrev offset (%lx) is larger than " | ||
| 197 | + "abbrev section size (%lx)\n"), | ||
| 198 | + (unsigned long) abbrev_offset, | ||
| 199 | + (unsigned long) abbrev_size); | ||
| 200 | + return NULL; | ||
| 201 | + } | ||
| 202 | + | ||
| 203 | + unsigned char *start = section->start + abbrev_base + abbrev_offset; | ||
| 204 | + unsigned char *end = section->start + abbrev_base + abbrev_size; | ||
| 205 | + abbrev_list *list = NULL; | ||
| 206 | + if (free_list) | ||
| 207 | + list = find_abbrev_list_by_abbrev_offset (abbrev_base, abbrev_offset); | ||
| 208 | + if (list == NULL) | ||
| 209 | + { | ||
| 210 | + list = process_abbrev_set (section, start, end); | ||
| 211 | + if (list) | ||
| 212 | + { | ||
| 213 | + list->abbrev_base = abbrev_base; | ||
| 214 | + list->abbrev_offset = abbrev_offset; | ||
| 215 | + list->next = NULL; | ||
| 216 | + } | ||
| 217 | + if (free_list) | ||
| 218 | + *free_list = list; | ||
| 219 | + } | ||
| 220 | + return list; | ||
| 221 | +} | ||
| 222 | + | ||
| 223 | static const char * | ||
| 224 | get_TAG_name (unsigned long tag) | ||
| 225 | { | ||
| 226 | @@ -3670,7 +3703,6 @@ process_debug_info (struct dwarf_section | ||
| 227 | dwarf_vma cu_offset; | ||
| 228 | unsigned int offset_size; | ||
| 229 | struct cu_tu_set * this_set; | ||
| 230 | - abbrev_list * list; | ||
| 231 | unsigned char *end_cu; | ||
| 232 | |||
| 233 | hdrptr = start; | ||
| 234 | @@ -3726,22 +3758,18 @@ process_debug_info (struct dwarf_section | ||
| 235 | abbrev_size = this_set->section_sizes [DW_SECT_ABBREV]; | ||
| 236 | } | ||
| 237 | |||
| 238 | - list = find_abbrev_list_by_abbrev_offset (abbrev_base, | ||
| 239 | - compunit.cu_abbrev_offset); | ||
| 240 | - if (list == NULL) | ||
| 241 | - { | ||
| 242 | - unsigned char * next; | ||
| 243 | - | ||
| 244 | - list = new_abbrev_list (abbrev_base, | ||
| 245 | - compunit.cu_abbrev_offset); | ||
| 246 | - next = process_abbrev_set (&debug_displays[abbrev_sec].section, | ||
| 247 | - abbrev_base, abbrev_size, | ||
| 248 | - compunit.cu_abbrev_offset, list); | ||
| 249 | - list->start_of_next_abbrevs = next; | ||
| 250 | - } | ||
| 251 | - | ||
| 252 | + abbrev_list *list; | ||
| 253 | + abbrev_list *free_list; | ||
| 254 | + list = find_and_process_abbrev_set (&debug_displays[abbrev_sec].section, | ||
| 255 | + abbrev_base, abbrev_size, | ||
| 256 | + compunit.cu_abbrev_offset, | ||
| 257 | + &free_list); | ||
| 258 | start = end_cu; | ||
| 259 | - record_abbrev_list_for_cu (cu_offset, start - section_begin, list); | ||
| 260 | + if (list != NULL && list->first_abbrev != NULL) | ||
| 261 | + record_abbrev_list_for_cu (cu_offset, start - section_begin, | ||
| 262 | + list, free_list); | ||
| 263 | + else if (free_list != NULL) | ||
| 264 | + free_abbrev_list (free_list); | ||
| 265 | } | ||
| 266 | |||
| 267 | for (start = section_begin, unit = 0; start < end; unit++) | ||
| 268 | @@ -3757,7 +3785,6 @@ process_debug_info (struct dwarf_section | ||
| 269 | struct cu_tu_set *this_set; | ||
| 270 | dwarf_vma abbrev_base; | ||
| 271 | size_t abbrev_size; | ||
| 272 | - abbrev_list * list = NULL; | ||
| 273 | unsigned char *end_cu; | ||
| 274 | |||
| 275 | hdrptr = start; | ||
| 276 | @@ -3936,20 +3963,10 @@ process_debug_info (struct dwarf_section | ||
| 277 | } | ||
| 278 | |||
| 279 | /* Process the abbrevs used by this compilation unit. */ | ||
| 280 | - list = find_abbrev_list_by_abbrev_offset (abbrev_base, | ||
| 281 | - compunit.cu_abbrev_offset); | ||
| 282 | - if (list == NULL) | ||
| 283 | - { | ||
| 284 | - unsigned char *next; | ||
| 285 | - | ||
| 286 | - list = new_abbrev_list (abbrev_base, | ||
| 287 | - compunit.cu_abbrev_offset); | ||
| 288 | - next = process_abbrev_set (&debug_displays[abbrev_sec].section, | ||
| 289 | - abbrev_base, abbrev_size, | ||
| 290 | - compunit.cu_abbrev_offset, list); | ||
| 291 | - list->start_of_next_abbrevs = next; | ||
| 292 | - } | ||
| 293 | - | ||
| 294 | + abbrev_list *list; | ||
| 295 | + list = find_and_process_abbrev_set (&debug_displays[abbrev_sec].section, | ||
| 296 | + abbrev_base, abbrev_size, | ||
| 297 | + compunit.cu_abbrev_offset, NULL); | ||
| 298 | level = 0; | ||
| 299 | last_level = level; | ||
| 300 | saved_level = -1; | ||
| 301 | @@ -4128,6 +4145,8 @@ process_debug_info (struct dwarf_section | ||
| 302 | if (entry->children) | ||
| 303 | ++level; | ||
| 304 | } | ||
| 305 | + if (list != NULL) | ||
| 306 | + free_abbrev_list (list); | ||
| 307 | } | ||
| 308 | |||
| 309 | /* Set num_debug_info_entries here so that it can be used to check if | ||
| 310 | @@ -6353,24 +6372,15 @@ display_debug_abbrev (struct dwarf_secti | ||
| 311 | |||
| 312 | do | ||
| 313 | { | ||
| 314 | - abbrev_list * list; | ||
| 315 | - dwarf_vma offset; | ||
| 316 | - | ||
| 317 | - offset = start - section->start; | ||
| 318 | - list = find_abbrev_list_by_abbrev_offset (0, offset); | ||
| 319 | + dwarf_vma offset = start - section->start; | ||
| 320 | + abbrev_list *list = find_and_process_abbrev_set (section, 0, | ||
| 321 | + section->size, offset, | ||
| 322 | + NULL); | ||
| 323 | if (list == NULL) | ||
| 324 | - { | ||
| 325 | - list = new_abbrev_list (0, offset); | ||
| 326 | - start = process_abbrev_set (section, 0, section->size, offset, list); | ||
| 327 | - list->start_of_next_abbrevs = start; | ||
| 328 | - } | ||
| 329 | - else | ||
| 330 | - start = list->start_of_next_abbrevs; | ||
| 331 | - | ||
| 332 | - if (list->first_abbrev == NULL) | ||
| 333 | - continue; | ||
| 334 | + break; | ||
| 335 | |||
| 336 | - printf (_(" Number TAG (0x%lx)\n"), (long) offset); | ||
| 337 | + if (list->first_abbrev) | ||
| 338 | + printf (_(" Number TAG (0x%lx)\n"), (long) offset); | ||
| 339 | |||
| 340 | for (entry = list->first_abbrev; entry; entry = entry->next) | ||
| 341 | { | ||
| 342 | @@ -6391,6 +6401,8 @@ display_debug_abbrev (struct dwarf_secti | ||
| 343 | putchar ('\n'); | ||
| 344 | } | ||
| 345 | } | ||
| 346 | + start = list->start_of_next_abbrevs; | ||
| 347 | + free_abbrev_list (list); | ||
| 348 | } | ||
| 349 | while (start); | ||
| 350 | |||
diff --git a/meta/recipes-devtools/binutils/binutils/0014-CVE-2022-38128-2.patch b/meta/recipes-devtools/binutils/binutils/0014-CVE-2022-38128-2.patch new file mode 100644 index 0000000000..e30b4d86e1 --- /dev/null +++ b/meta/recipes-devtools/binutils/binutils/0014-CVE-2022-38128-2.patch | |||
| @@ -0,0 +1,536 @@ | |||
| 1 | From 175b91507b83ad42607d2f6dadaf55b7b511bdbe Mon Sep 17 00:00:00 2001 | ||
| 2 | From: Alan Modra <amodra@gmail.com> | ||
| 3 | Date: Wed, 20 Jul 2022 18:28:50 +0930 | ||
| 4 | Subject: [PATCH] miscellaneous dwarf.c tidies | ||
| 5 | |||
| 6 | * dwarf.c: Leading and trailing whitespace fixes. | ||
| 7 | (free_abbrev_list): New function. | ||
| 8 | (free_all_abbrevs): Use the above. Free cu_abbrev_map here too. | ||
| 9 | (process_abbrev_set): Print actual section name on error. | ||
| 10 | (get_type_abbrev_from_form): Add overflow check. | ||
| 11 | (free_debug_memory): Don't free cu_abbrev_map here.. | ||
| 12 | (process_debug_info): ..or here. Warn on another case of not | ||
| 13 | finding a neeeded abbrev. | ||
| 14 | |||
| 15 | Upstream-Status: Backport [https://sourceware.org/git/?p=binutils-gdb.git;a=commitdiff;h=175b91507b83ad42607d2f6dadaf55b7b511bdbe] | ||
| 16 | |||
| 17 | Signed-off-by: Pgowda <pgowda.cve@gmail.com> | ||
| 18 | --- | ||
| 19 | binutils/dwarf.c | 216 +++++++++++++++++++++++------------------------ | ||
| 20 | 1 file changed, 106 insertions(+), 110 deletions(-) | ||
| 21 | |||
| 22 | diff --git a/binutils/dwarf.c b/binutils/dwarf.c | ||
| 23 | index 2b1eec49422..267ed3bb382 100644 | ||
| 24 | --- a/binutils/dwarf.c | ||
| 25 | +++ b/binutils/dwarf.c | ||
| 26 | @@ -806,7 +806,7 @@ fetch_indexed_value (dwarf_vma idx, | ||
| 27 | pointer_size = 4; | ||
| 28 | bias = 12; | ||
| 29 | } | ||
| 30 | - | ||
| 31 | + | ||
| 32 | dwarf_vma offset = idx * pointer_size; | ||
| 33 | |||
| 34 | /* Offsets are biased by the size of the section header | ||
| 35 | @@ -908,38 +908,41 @@ record_abbrev_list_for_cu (dwarf_vma sta | ||
| 36 | next_free_abbrev_map_entry ++; | ||
| 37 | } | ||
| 38 | |||
| 39 | -static void | ||
| 40 | -free_all_abbrevs (void) | ||
| 41 | +static abbrev_list * | ||
| 42 | +free_abbrev_list (abbrev_list *list) | ||
| 43 | { | ||
| 44 | - abbrev_list * list; | ||
| 45 | + abbrev_entry *abbrv = list->first_abbrev; | ||
| 46 | |||
| 47 | - for (list = abbrev_lists; list != NULL;) | ||
| 48 | + while (abbrv) | ||
| 49 | { | ||
| 50 | - abbrev_list * next = list->next; | ||
| 51 | - abbrev_entry * abbrv; | ||
| 52 | + abbrev_attr *attr = abbrv->first_attr; | ||
| 53 | |||
| 54 | - for (abbrv = list->first_abbrev; abbrv != NULL;) | ||
| 55 | + while (attr) | ||
| 56 | { | ||
| 57 | - abbrev_entry * next_abbrev = abbrv->next; | ||
| 58 | - abbrev_attr * attr; | ||
| 59 | - | ||
| 60 | - for (attr = abbrv->first_attr; attr;) | ||
| 61 | - { | ||
| 62 | - abbrev_attr *next_attr = attr->next; | ||
| 63 | - | ||
| 64 | - free (attr); | ||
| 65 | - attr = next_attr; | ||
| 66 | - } | ||
| 67 | - | ||
| 68 | - free (abbrv); | ||
| 69 | - abbrv = next_abbrev; | ||
| 70 | + abbrev_attr *next_attr = attr->next; | ||
| 71 | + free (attr); | ||
| 72 | + attr = next_attr; | ||
| 73 | } | ||
| 74 | |||
| 75 | - free (list); | ||
| 76 | - list = next; | ||
| 77 | + abbrev_entry *next_abbrev = abbrv->next; | ||
| 78 | + free (abbrv); | ||
| 79 | + abbrv = next_abbrev; | ||
| 80 | } | ||
| 81 | |||
| 82 | - abbrev_lists = NULL; | ||
| 83 | + abbrev_list *next = list->next; | ||
| 84 | + free (list); | ||
| 85 | + return next; | ||
| 86 | +} | ||
| 87 | + | ||
| 88 | +static void | ||
| 89 | +free_all_abbrevs (void) | ||
| 90 | +{ | ||
| 91 | + while (abbrev_lists) | ||
| 92 | + abbrev_lists = free_abbrev_list (abbrev_lists); | ||
| 93 | + | ||
| 94 | + free (cu_abbrev_map); | ||
| 95 | + cu_abbrev_map = NULL; | ||
| 96 | + next_free_abbrev_map_entry = 0; | ||
| 97 | } | ||
| 98 | |||
| 99 | static abbrev_list * | ||
| 100 | @@ -971,7 +974,7 @@ find_abbrev_map_by_offset (dwarf_vma off | ||
| 101 | && cu_abbrev_map[i].end > offset) | ||
| 102 | return cu_abbrev_map + i; | ||
| 103 | |||
| 104 | - return NULL; | ||
| 105 | + return NULL; | ||
| 106 | } | ||
| 107 | |||
| 108 | static void | ||
| 109 | @@ -1094,7 +1097,7 @@ process_abbrev_set (struct dwarf_section | ||
| 110 | } | ||
| 111 | |||
| 112 | /* Report the missing single zero which ends the section. */ | ||
| 113 | - error (_(".debug_abbrev section not zero terminated\n")); | ||
| 114 | + error (_("%s section not zero terminated\n"), section->name); | ||
| 115 | |||
| 116 | free (list); | ||
| 117 | return NULL; | ||
| 118 | @@ -1875,7 +1878,7 @@ fetch_alt_indirect_string (dwarf_vma off | ||
| 119 | dwarf_vmatoa ("x", offset)); | ||
| 120 | return _("<offset is too big>"); | ||
| 121 | } | ||
| 122 | - | ||
| 123 | + | ||
| 124 | static const char * | ||
| 125 | get_AT_name (unsigned long attribute) | ||
| 126 | { | ||
| 127 | @@ -2157,7 +2160,8 @@ get_type_abbrev_from_form (unsigned long | ||
| 128 | case DW_FORM_ref4: | ||
| 129 | case DW_FORM_ref8: | ||
| 130 | case DW_FORM_ref_udata: | ||
| 131 | - if (uvalue + cu_offset > (size_t) (cu_end - section->start)) | ||
| 132 | + if (uvalue + cu_offset < uvalue | ||
| 133 | + || uvalue + cu_offset > (size_t) (cu_end - section->start)) | ||
| 134 | { | ||
| 135 | warn (_("Unable to resolve ref form: uvalue %lx + cu_offset %lx > CU size %lx\n"), | ||
| 136 | uvalue, (long) cu_offset, (long) (cu_end - section->start)); | ||
| 137 | @@ -2194,7 +2198,7 @@ get_type_abbrev_from_form (unsigned long | ||
| 138 | else | ||
| 139 | *map_return = NULL; | ||
| 140 | } | ||
| 141 | - | ||
| 142 | + | ||
| 143 | READ_ULEB (abbrev_number, data, section->start + section->size); | ||
| 144 | |||
| 145 | for (entry = map->list->first_abbrev; entry != NULL; entry = entry->next) | ||
| 146 | @@ -2783,10 +2787,10 @@ read_and_display_attr_value (unsigned lo | ||
| 147 | if (form == DW_FORM_loclistx) | ||
| 148 | { | ||
| 149 | if (dwo) | ||
| 150 | - { | ||
| 151 | - index = fetch_indexed_value (uvalue, loclists_dwo, 0); | ||
| 152 | - index += (offset_size == 8) ? 20 : 12; | ||
| 153 | - } | ||
| 154 | + { | ||
| 155 | + index = fetch_indexed_value (uvalue, loclists_dwo, 0); | ||
| 156 | + index += (offset_size == 8) ? 20 : 12; | ||
| 157 | + } | ||
| 158 | else if (debug_info_p == NULL) | ||
| 159 | { | ||
| 160 | index = fetch_indexed_value (uvalue, loclists, 0); | ||
| 161 | @@ -2804,21 +2808,21 @@ read_and_display_attr_value (unsigned lo | ||
| 162 | else if (form == DW_FORM_rnglistx) | ||
| 163 | { | ||
| 164 | if (dwo) | ||
| 165 | - { | ||
| 166 | - index = fetch_indexed_value (uvalue, rnglists_dwo, 0); | ||
| 167 | - index += (offset_size == 8) ? 20 : 12; | ||
| 168 | - } | ||
| 169 | + { | ||
| 170 | + index = fetch_indexed_value (uvalue, rnglists_dwo, 0); | ||
| 171 | + index += (offset_size == 8) ? 20 : 12; | ||
| 172 | + } | ||
| 173 | else | ||
| 174 | - { | ||
| 175 | - if (debug_info_p == NULL) | ||
| 176 | - base = 0; | ||
| 177 | - else | ||
| 178 | - base = debug_info_p->rnglists_base; | ||
| 179 | - /* We do not have a cached value this time, so we perform the | ||
| 180 | - computation manually. */ | ||
| 181 | - index = fetch_indexed_value (uvalue, rnglists, base); | ||
| 182 | - index += base; | ||
| 183 | - } | ||
| 184 | + { | ||
| 185 | + if (debug_info_p == NULL) | ||
| 186 | + base = 0; | ||
| 187 | + else | ||
| 188 | + base = debug_info_p->rnglists_base; | ||
| 189 | + /* We do not have a cached value this time, so we perform the | ||
| 190 | + computation manually. */ | ||
| 191 | + index = fetch_indexed_value (uvalue, rnglists, base); | ||
| 192 | + index += base; | ||
| 193 | + } | ||
| 194 | } | ||
| 195 | else | ||
| 196 | { | ||
| 197 | @@ -2844,7 +2848,7 @@ read_and_display_attr_value (unsigned lo | ||
| 198 | if (!do_loc) | ||
| 199 | printf ("%c<0x%s>", delimiter, dwarf_vmatoa ("x", uvalue + cu_offset)); | ||
| 200 | break; | ||
| 201 | - | ||
| 202 | + | ||
| 203 | default: | ||
| 204 | warn (_("Unrecognized form: 0x%lx\n"), form); | ||
| 205 | /* What to do? Consume a byte maybe? */ | ||
| 206 | @@ -2869,9 +2873,9 @@ read_and_display_attr_value (unsigned lo | ||
| 207 | case DW_AT_rnglists_base: | ||
| 208 | if (debug_info_p->rnglists_base) | ||
| 209 | warn (_("CU @ 0x%s has multiple rnglists_base values (0x%s and 0x%s)"), | ||
| 210 | - dwarf_vmatoa ("x", debug_info_p->cu_offset), | ||
| 211 | - dwarf_vmatoa ("x", debug_info_p->rnglists_base), | ||
| 212 | - dwarf_vmatoa ("x", uvalue)); | ||
| 213 | + dwarf_vmatoa ("x", debug_info_p->cu_offset), | ||
| 214 | + dwarf_vmatoa ("x", debug_info_p->rnglists_base), | ||
| 215 | + dwarf_vmatoa ("x", uvalue)); | ||
| 216 | debug_info_p->rnglists_base = uvalue; | ||
| 217 | break; | ||
| 218 | case DW_AT_str_offsets_base: | ||
| 219 | @@ -3021,7 +3025,7 @@ read_and_display_attr_value (unsigned lo | ||
| 220 | case DW_FORM_strx3: | ||
| 221 | case DW_FORM_strx4: | ||
| 222 | add_dwo_name (fetch_indexed_string (uvalue, this_set, offset_size, false, | ||
| 223 | - debug_info_p->str_offsets_base), | ||
| 224 | + debug_info_p->str_offsets_base), | ||
| 225 | cu_offset); | ||
| 226 | break; | ||
| 227 | case DW_FORM_string: | ||
| 228 | @@ -3055,7 +3059,7 @@ read_and_display_attr_value (unsigned lo | ||
| 229 | case DW_FORM_strx3: | ||
| 230 | case DW_FORM_strx4: | ||
| 231 | add_dwo_dir (fetch_indexed_string (uvalue, this_set, offset_size, false, | ||
| 232 | - debug_info_p->str_offsets_base), | ||
| 233 | + debug_info_p->str_offsets_base), | ||
| 234 | cu_offset); | ||
| 235 | break; | ||
| 236 | case DW_FORM_string: | ||
| 237 | @@ -3686,11 +3690,8 @@ process_debug_info (struct dwarf_section | ||
| 238 | introduce (section, false); | ||
| 239 | |||
| 240 | free_all_abbrevs (); | ||
| 241 | - free (cu_abbrev_map); | ||
| 242 | - cu_abbrev_map = NULL; | ||
| 243 | - next_free_abbrev_map_entry = 0; | ||
| 244 | |||
| 245 | - /* In order to be able to resolve DW_FORM_ref_attr forms we need | ||
| 246 | + /* In order to be able to resolve DW_FORM_ref_addr forms we need | ||
| 247 | to load *all* of the abbrevs for all CUs in this .debug_info | ||
| 248 | section. This does effectively mean that we (partially) read | ||
| 249 | every CU header twice. */ | ||
| 250 | @@ -4045,12 +4046,11 @@ process_debug_info (struct dwarf_section | ||
| 251 | |||
| 252 | /* Scan through the abbreviation list until we reach the | ||
| 253 | correct entry. */ | ||
| 254 | - if (list == NULL) | ||
| 255 | - continue; | ||
| 256 | - | ||
| 257 | - for (entry = list->first_abbrev; entry != NULL; entry = entry->next) | ||
| 258 | - if (entry->number == abbrev_number) | ||
| 259 | - break; | ||
| 260 | + entry = NULL; | ||
| 261 | + if (list != NULL) | ||
| 262 | + for (entry = list->first_abbrev; entry != NULL; entry = entry->next) | ||
| 263 | + if (entry->number == abbrev_number) | ||
| 264 | + break; | ||
| 265 | |||
| 266 | if (entry == NULL) | ||
| 267 | { | ||
| 268 | @@ -4074,7 +4074,7 @@ process_debug_info (struct dwarf_section | ||
| 269 | break; | ||
| 270 | case DW_TAG_compile_unit: | ||
| 271 | case DW_TAG_skeleton_unit: | ||
| 272 | - need_base_address = 1; | ||
| 273 | + need_base_address = 1; | ||
| 274 | need_dwo_info = do_loc; | ||
| 275 | break; | ||
| 276 | case DW_TAG_entry_point: | ||
| 277 | @@ -4459,7 +4459,7 @@ display_debug_sup (struct dwarf_section | ||
| 278 | |||
| 279 | SAFE_BYTE_GET_AND_INC (is_supplementary, start, 1, end); | ||
| 280 | if (is_supplementary != 0 && is_supplementary != 1) | ||
| 281 | - warn (_("corrupt .debug_sup section: is_supplementary not 0 or 1\n")); | ||
| 282 | + warn (_("corrupt .debug_sup section: is_supplementary not 0 or 1\n")); | ||
| 283 | |||
| 284 | sup_filename = start; | ||
| 285 | if (is_supplementary && sup_filename[0] != 0) | ||
| 286 | @@ -5638,7 +5638,7 @@ display_debug_lines_decoded (struct dwar | ||
| 287 | printf ("%s %11d %#18" DWARF_VMA_FMT "x", | ||
| 288 | newFileName, state_machine_regs.line, | ||
| 289 | state_machine_regs.address); | ||
| 290 | - } | ||
| 291 | + } | ||
| 292 | else | ||
| 293 | { | ||
| 294 | if (xop == -DW_LNE_end_sequence) | ||
| 295 | @@ -6092,7 +6092,7 @@ display_debug_macro (struct dwarf_sectio | ||
| 296 | load_debug_section_with_follow (str, file); | ||
| 297 | load_debug_section_with_follow (line, file); | ||
| 298 | load_debug_section_with_follow (str_index, file); | ||
| 299 | - | ||
| 300 | + | ||
| 301 | introduce (section, false); | ||
| 302 | |||
| 303 | while (curr < end) | ||
| 304 | @@ -6537,7 +6537,7 @@ display_loc_list (struct dwarf_section * | ||
| 305 | |||
| 306 | /* Check base address specifiers. */ | ||
| 307 | if (is_max_address (begin, pointer_size) | ||
| 308 | - && !is_max_address (end, pointer_size)) | ||
| 309 | + && !is_max_address (end, pointer_size)) | ||
| 310 | { | ||
| 311 | base_address = end; | ||
| 312 | print_dwarf_vma (begin, pointer_size); | ||
| 313 | @@ -6715,7 +6715,7 @@ display_loclists_list (struct dwarf_sect | ||
| 314 | case DW_LLE_default_location: | ||
| 315 | begin = end = 0; | ||
| 316 | break; | ||
| 317 | - | ||
| 318 | + | ||
| 319 | case DW_LLE_offset_pair: | ||
| 320 | READ_ULEB (begin, start, section_end); | ||
| 321 | begin += base_address; | ||
| 322 | @@ -7011,7 +7011,7 @@ display_offset_entry_loclists (struct dw | ||
| 323 | unsigned char * start = section->start; | ||
| 324 | unsigned char * const end = start + section->size; | ||
| 325 | |||
| 326 | - introduce (section, false); | ||
| 327 | + introduce (section, false); | ||
| 328 | |||
| 329 | do | ||
| 330 | { | ||
| 331 | @@ -7060,14 +7060,14 @@ display_offset_entry_loclists (struct dw | ||
| 332 | section->name, segment_selector_size); | ||
| 333 | return 0; | ||
| 334 | } | ||
| 335 | - | ||
| 336 | + | ||
| 337 | if (offset_entry_count == 0) | ||
| 338 | { | ||
| 339 | warn (_("The %s section contains a table without offset\n"), | ||
| 340 | section->name); | ||
| 341 | return 0; | ||
| 342 | } | ||
| 343 | - | ||
| 344 | + | ||
| 345 | printf (_("\n Offset Entries starting at 0x%lx:\n"), | ||
| 346 | (long)(start - section->start)); | ||
| 347 | |||
| 348 | @@ -8229,7 +8229,7 @@ display_debug_rnglists (struct dwarf_sec | ||
| 349 | start = display_debug_rnglists_list | ||
| 350 | (start, end, address_size, offset, 0, offset_size); | ||
| 351 | if (start >= end) | ||
| 352 | - break; | ||
| 353 | + break; | ||
| 354 | } | ||
| 355 | |||
| 356 | start = end; | ||
| 357 | @@ -8347,12 +8347,12 @@ display_debug_ranges (struct dwarf_secti | ||
| 358 | next = section_begin + offset + debug_info_p->rnglists_base; | ||
| 359 | |||
| 360 | /* If multiple DWARF entities reference the same range then we will | ||
| 361 | - have multiple entries in the `range_entries' list for the same | ||
| 362 | - offset. Thanks to the sort above these will all be consecutive in | ||
| 363 | - the `range_entries' list, so we can easily ignore duplicates | ||
| 364 | - here. */ | ||
| 365 | + have multiple entries in the `range_entries' list for the same | ||
| 366 | + offset. Thanks to the sort above these will all be consecutive in | ||
| 367 | + the `range_entries' list, so we can easily ignore duplicates | ||
| 368 | + here. */ | ||
| 369 | if (i > 0 && last_offset == offset) | ||
| 370 | - continue; | ||
| 371 | + continue; | ||
| 372 | last_offset = offset; | ||
| 373 | |||
| 374 | if (dwarf_check != 0 && i > 0) | ||
| 375 | @@ -10286,7 +10286,7 @@ display_debug_names (struct dwarf_sectio | ||
| 376 | printf (_("Out of %lu items there are %zu bucket clashes" | ||
| 377 | " (longest of %zu entries).\n"), | ||
| 378 | (unsigned long) name_count, hash_clash_count, longest_clash); | ||
| 379 | - | ||
| 380 | + | ||
| 381 | if (name_count != buckets_filled + hash_clash_count) | ||
| 382 | warn (_("The name_count (%lu) is not the same as the used bucket_count (%lu) + the hash clash count (%lu)"), | ||
| 383 | (unsigned long) name_count, | ||
| 384 | @@ -10390,7 +10390,7 @@ display_debug_names (struct dwarf_sectio | ||
| 385 | break; | ||
| 386 | if (tagno >= 0) | ||
| 387 | printf ("%s<%lu>", | ||
| 388 | - (tagno == 0 && second_abbrev_tag == 0 ? " " : "\n\t"), | ||
| 389 | + (tagno == 0 && second_abbrev_tag == 0 ? " " : "\n\t"), | ||
| 390 | (unsigned long) abbrev_tag); | ||
| 391 | |||
| 392 | for (entry = abbrev_lookup; | ||
| 393 | @@ -10919,7 +10919,7 @@ process_cu_tu_index (struct dwarf_sectio | ||
| 394 | Check for integer overflow (can occur when size_t is 32-bit) | ||
| 395 | with overlarge ncols or nused values. */ | ||
| 396 | if (nused == -1u | ||
| 397 | - || _mul_overflow ((size_t) ncols, 4, &temp) | ||
| 398 | + || _mul_overflow ((size_t) ncols, 4, &temp) | ||
| 399 | || _mul_overflow ((size_t) nused + 1, temp, &total) | ||
| 400 | || total > (size_t) (limit - ppool)) | ||
| 401 | { | ||
| 402 | @@ -10927,7 +10927,7 @@ process_cu_tu_index (struct dwarf_sectio | ||
| 403 | section->name); | ||
| 404 | return 0; | ||
| 405 | } | ||
| 406 | - | ||
| 407 | + | ||
| 408 | if (do_display) | ||
| 409 | { | ||
| 410 | printf (_(" Offset table\n")); | ||
| 411 | @@ -11431,8 +11431,8 @@ add_separate_debug_file (const char * fi | ||
| 412 | |||
| 413 | static bool | ||
| 414 | debuginfod_fetch_separate_debug_info (struct dwarf_section * section, | ||
| 415 | - char ** filename, | ||
| 416 | - void * file) | ||
| 417 | + char ** filename, | ||
| 418 | + void * file) | ||
| 419 | { | ||
| 420 | size_t build_id_len; | ||
| 421 | unsigned char * build_id; | ||
| 422 | @@ -11450,14 +11450,14 @@ debuginfod_fetch_separate_debug_info (st | ||
| 423 | |||
| 424 | filelen = strnlen ((const char *)section->start, section->size); | ||
| 425 | if (filelen == section->size) | ||
| 426 | - /* Corrupt debugaltlink. */ | ||
| 427 | - return false; | ||
| 428 | + /* Corrupt debugaltlink. */ | ||
| 429 | + return false; | ||
| 430 | |||
| 431 | build_id = section->start + filelen + 1; | ||
| 432 | build_id_len = section->size - (filelen + 1); | ||
| 433 | |||
| 434 | if (build_id_len == 0) | ||
| 435 | - return false; | ||
| 436 | + return false; | ||
| 437 | } | ||
| 438 | else | ||
| 439 | return false; | ||
| 440 | @@ -11469,25 +11469,25 @@ debuginfod_fetch_separate_debug_info (st | ||
| 441 | |||
| 442 | client = debuginfod_begin (); | ||
| 443 | if (client == NULL) | ||
| 444 | - return false; | ||
| 445 | + return false; | ||
| 446 | |||
| 447 | /* Query debuginfod servers for the target file. If found its path | ||
| 448 | - will be stored in filename. */ | ||
| 449 | + will be stored in filename. */ | ||
| 450 | fd = debuginfod_find_debuginfo (client, build_id, build_id_len, filename); | ||
| 451 | debuginfod_end (client); | ||
| 452 | |||
| 453 | /* Only free build_id if we allocated space for a hex string | ||
| 454 | - in get_build_id (). */ | ||
| 455 | + in get_build_id (). */ | ||
| 456 | if (build_id_len == 0) | ||
| 457 | - free (build_id); | ||
| 458 | + free (build_id); | ||
| 459 | |||
| 460 | if (fd >= 0) | ||
| 461 | - { | ||
| 462 | - /* File successfully retrieved. Close fd since we want to | ||
| 463 | - use open_debug_file () on filename instead. */ | ||
| 464 | - close (fd); | ||
| 465 | - return true; | ||
| 466 | - } | ||
| 467 | + { | ||
| 468 | + /* File successfully retrieved. Close fd since we want to | ||
| 469 | + use open_debug_file () on filename instead. */ | ||
| 470 | + close (fd); | ||
| 471 | + return true; | ||
| 472 | + } | ||
| 473 | } | ||
| 474 | |||
| 475 | return false; | ||
| 476 | @@ -11500,7 +11500,7 @@ load_separate_debug_info (const char * | ||
| 477 | parse_func_type parse_func, | ||
| 478 | check_func_type check_func, | ||
| 479 | void * func_data, | ||
| 480 | - void * file ATTRIBUTE_UNUSED) | ||
| 481 | + void * file ATTRIBUTE_UNUSED) | ||
| 482 | { | ||
| 483 | const char * separate_filename; | ||
| 484 | char * debug_filename; | ||
| 485 | @@ -11616,11 +11616,11 @@ load_separate_debug_info (const char * | ||
| 486 | & tmp_filename, | ||
| 487 | file)) | ||
| 488 | { | ||
| 489 | - /* File successfully downloaded from server, replace | ||
| 490 | - debug_filename with the file's path. */ | ||
| 491 | - free (debug_filename); | ||
| 492 | - debug_filename = tmp_filename; | ||
| 493 | - goto found; | ||
| 494 | + /* File successfully downloaded from server, replace | ||
| 495 | + debug_filename with the file's path. */ | ||
| 496 | + free (debug_filename); | ||
| 497 | + debug_filename = tmp_filename; | ||
| 498 | + goto found; | ||
| 499 | } | ||
| 500 | } | ||
| 501 | #endif | ||
| 502 | @@ -11787,12 +11787,12 @@ load_build_id_debug_file (const char * m | ||
| 503 | /* In theory we should extract the contents of the section into | ||
| 504 | a note structure and then check the fields. For now though | ||
| 505 | just use hard coded offsets instead: | ||
| 506 | - | ||
| 507 | + | ||
| 508 | Field Bytes Contents | ||
| 509 | NSize 0...3 4 | ||
| 510 | DSize 4...7 8+ | ||
| 511 | Type 8..11 3 (NT_GNU_BUILD_ID) | ||
| 512 | - Name 12.15 GNU\0 | ||
| 513 | + Name 12.15 GNU\0 | ||
| 514 | Data 16.... */ | ||
| 515 | |||
| 516 | /* FIXME: Check the name size, name and type fields. */ | ||
| 517 | @@ -11804,7 +11804,7 @@ load_build_id_debug_file (const char * m | ||
| 518 | warn (_(".note.gnu.build-id data size is too small\n")); | ||
| 519 | return; | ||
| 520 | } | ||
| 521 | - | ||
| 522 | + | ||
| 523 | if (build_id_size > (section->size - 16)) | ||
| 524 | { | ||
| 525 | warn (_(".note.gnu.build-id data size is too bug\n")); | ||
| 526 | @@ -12100,10 +12100,6 @@ free_debug_memory (void) | ||
| 527 | |||
| 528 | free_all_abbrevs (); | ||
| 529 | |||
| 530 | - free (cu_abbrev_map); | ||
| 531 | - cu_abbrev_map = NULL; | ||
| 532 | - next_free_abbrev_map_entry = 0; | ||
| 533 | - | ||
| 534 | free (shndx_pool); | ||
| 535 | shndx_pool = NULL; | ||
| 536 | shndx_pool_size = 0; | ||
diff --git a/meta/recipes-devtools/binutils/binutils/0014-CVE-2022-38128-3.patch b/meta/recipes-devtools/binutils/binutils/0014-CVE-2022-38128-3.patch new file mode 100644 index 0000000000..04d06ed6b6 --- /dev/null +++ b/meta/recipes-devtools/binutils/binutils/0014-CVE-2022-38128-3.patch | |||
| @@ -0,0 +1,95 @@ | |||
| 1 | From 695c6dfe7e85006b98c8b746f3fd5f913c94ebff Mon Sep 17 00:00:00 2001 | ||
| 2 | From: Alan Modra <amodra@gmail.com> | ||
| 3 | Date: Thu, 21 Jul 2022 09:56:15 +0930 | ||
| 4 | Subject: [PATCH] PR29370, infinite loop in display_debug_abbrev | ||
| 5 | |||
| 6 | The PR29370 testcase is a fuzzed object file with multiple | ||
| 7 | .trace_abbrev sections. Multiple .trace_abbrev or .debug_abbrev | ||
| 8 | sections are not a violation of the DWARF standard. The DWARF5 | ||
| 9 | standard even gives an example of multiple .debug_abbrev sections | ||
| 10 | contained in groups. Caching and lookup of processed abbrevs thus | ||
| 11 | needs to be done by section and offset rather than base and offset. | ||
| 12 | (Why base anyway?) Or, since section contents are kept, by a pointer | ||
| 13 | into the contents. | ||
| 14 | |||
| 15 | PR 29370 | ||
| 16 | * dwarf.c (struct abbrev_list): Replace abbrev_base and | ||
| 17 | abbrev_offset with raw field. | ||
| 18 | (find_abbrev_list_by_abbrev_offset): Delete. | ||
| 19 | (find_abbrev_list_by_raw_abbrev): New function. | ||
| 20 | (process_abbrev_set): Set list->raw and list->next. | ||
| 21 | (find_and_process_abbrev_set): Replace abbrev list lookup with | ||
| 22 | new function. Don't set list abbrev_base, abbrev_offset or next. | ||
| 23 | |||
| 24 | Upstream-Status: Backport [https://sourceware.org/git/?p=binutils-gdb.git;a=patch;h=695c6dfe7e85006b98c8b746f3fd5f913c94ebff] | ||
| 25 | |||
| 26 | Signed-off-by: Pgowda <pgowda.cve@gmail.com> | ||
| 27 | --- | ||
| 28 | binutils/dwarf.c | 19 ++++++------------- | ||
| 29 | 1 file changed, 6 insertions(+), 13 deletions(-) | ||
| 30 | |||
| 31 | diff --git a/binutils/dwarf.c b/binutils/dwarf.c | ||
| 32 | index 2fc352f74c5..99fb3566994 100644 | ||
| 33 | --- a/binutils/dwarf.c | ||
| 34 | +++ b/binutils/dwarf.c | ||
| 35 | @@ -856,8 +856,7 @@ typedef struct abbrev_list | ||
| 36 | { | ||
| 37 | abbrev_entry * first_abbrev; | ||
| 38 | abbrev_entry * last_abbrev; | ||
| 39 | - dwarf_vma abbrev_base; | ||
| 40 | - dwarf_vma abbrev_offset; | ||
| 41 | + unsigned char * raw; | ||
| 42 | struct abbrev_list * next; | ||
| 43 | unsigned char * start_of_next_abbrevs; | ||
| 44 | } | ||
| 45 | @@ -946,14 +945,12 @@ free_all_abbrevs (void) | ||
| 46 | } | ||
| 47 | |||
| 48 | static abbrev_list * | ||
| 49 | -find_abbrev_list_by_abbrev_offset (dwarf_vma abbrev_base, | ||
| 50 | - dwarf_vma abbrev_offset) | ||
| 51 | +find_abbrev_list_by_raw_abbrev (unsigned char *raw) | ||
| 52 | { | ||
| 53 | abbrev_list * list; | ||
| 54 | |||
| 55 | for (list = abbrev_lists; list != NULL; list = list->next) | ||
| 56 | - if (list->abbrev_base == abbrev_base | ||
| 57 | - && list->abbrev_offset == abbrev_offset) | ||
| 58 | + if (list->raw == raw) | ||
| 59 | return list; | ||
| 60 | |||
| 61 | return NULL; | ||
| 62 | @@ -1040,6 +1037,7 @@ process_abbrev_set (struct dwarf_section | ||
| 63 | abbrev_list *list = xmalloc (sizeof (*list)); | ||
| 64 | list->first_abbrev = NULL; | ||
| 65 | list->last_abbrev = NULL; | ||
| 66 | + list->raw = start; | ||
| 67 | |||
| 68 | while (start < end) | ||
| 69 | { | ||
| 70 | @@ -1055,6 +1053,7 @@ process_abbrev_set (struct dwarf_section | ||
| 71 | the caller. */ | ||
| 72 | if (start == end || entry == 0) | ||
| 73 | { | ||
| 74 | + list->next = NULL; | ||
| 75 | list->start_of_next_abbrevs = start != end ? start : NULL; | ||
| 76 | return list; | ||
| 77 | } | ||
| 78 | @@ -1144,16 +1143,10 @@ find_and_process_abbrev_set (struct dwar | ||
| 79 | unsigned char *end = section->start + abbrev_base + abbrev_size; | ||
| 80 | abbrev_list *list = NULL; | ||
| 81 | if (free_list) | ||
| 82 | - list = find_abbrev_list_by_abbrev_offset (abbrev_base, abbrev_offset); | ||
| 83 | + list = find_abbrev_list_by_raw_abbrev (start); | ||
| 84 | if (list == NULL) | ||
| 85 | { | ||
| 86 | list = process_abbrev_set (section, start, end); | ||
| 87 | - if (list) | ||
| 88 | - { | ||
| 89 | - list->abbrev_base = abbrev_base; | ||
| 90 | - list->abbrev_offset = abbrev_offset; | ||
| 91 | - list->next = NULL; | ||
| 92 | - } | ||
| 93 | if (free_list) | ||
| 94 | *free_list = list; | ||
| 95 | } | ||
