diff options
author | Hitendra Prajapati <hprajapati@mvista.com> | 2025-02-26 12:28:26 +0530 |
---|---|---|
committer | Steve Sakoman <steve@sakoman.com> | 2025-03-05 06:03:47 -0800 |
commit | 84492696d2b9385c72496cd9fd26e47759f35d61 (patch) | |
tree | e23bf5968cb8832556b6180bf804a0374c5dc5f8 | |
parent | f93188cb87bebd6bf8b6cf0f18ba4e078feaf12b (diff) | |
download | poky-84492696d2b9385c72496cd9fd26e47759f35d61.tar.gz |
elfutils: Fix multiple CVEs
Backport fixes for:
* CVE-2025-1352 - Upstream-Status: Backport from https://sourceware.org/git/?p=elfutils.git;a=commit;h=2636426a091bd6c6f7f02e49ab20d4cdc6bfc753
* CVE-2025-1365 - Upstream-Status: Backport from https://sourceware.org/git/?p=elfutils.git;a=commit;h=5e5c0394d82c53e97750fe7b18023e6f84157b81
* CVE-2025-1372 - Upstream-Status: Backport from https://sourceware.org/git/?p=elfutils.git;a=commit;h=73db9d2021cab9e23fd734b0a76a612d52a6f1db
(From OE-Core rev: 938676089fb5da383b7daf6c5e6348079ecf5674)
Signed-off-by: Hitendra Prajapati <hprajapati@mvista.com>
Signed-off-by: Steve Sakoman <steve@sakoman.com>
4 files changed, 357 insertions, 0 deletions
diff --git a/meta/recipes-devtools/elfutils/elfutils_0.191.bb b/meta/recipes-devtools/elfutils/elfutils_0.191.bb index c4d872430b..85e024179b 100644 --- a/meta/recipes-devtools/elfutils/elfutils_0.191.bb +++ b/meta/recipes-devtools/elfutils/elfutils_0.191.bb | |||
@@ -23,6 +23,9 @@ SRC_URI = "https://sourceware.org/elfutils/ftp/${PV}/${BP}.tar.bz2 \ | |||
23 | file://0001-tests-Makefile.am-compile-test_nlist-with-standard-C.patch \ | 23 | file://0001-tests-Makefile.am-compile-test_nlist-with-standard-C.patch \ |
24 | file://0001-debuginfod-Remove-unused-variable.patch \ | 24 | file://0001-debuginfod-Remove-unused-variable.patch \ |
25 | file://0001-srcfiles-fix-unused-variable-BUFFER_SIZE.patch \ | 25 | file://0001-srcfiles-fix-unused-variable-BUFFER_SIZE.patch \ |
26 | file://CVE-2025-1352.patch \ | ||
27 | file://CVE-2025-1365.patch \ | ||
28 | file://CVE-2025-1372.patch \ | ||
26 | " | 29 | " |
27 | SRC_URI:append:libc-musl = " \ | 30 | SRC_URI:append:libc-musl = " \ |
28 | file://0003-musl-utils.patch \ | 31 | file://0003-musl-utils.patch \ |
diff --git a/meta/recipes-devtools/elfutils/files/CVE-2025-1352.patch b/meta/recipes-devtools/elfutils/files/CVE-2025-1352.patch new file mode 100644 index 0000000000..5710905449 --- /dev/null +++ b/meta/recipes-devtools/elfutils/files/CVE-2025-1352.patch | |||
@@ -0,0 +1,153 @@ | |||
1 | From 2636426a091bd6c6f7f02e49ab20d4cdc6bfc753 Mon Sep 17 00:00:00 2001 | ||
2 | From: Mark Wielaard <mark@klomp.org> | ||
3 | Date: Sat, 8 Feb 2025 20:00:12 +0100 | ||
4 | Subject: [PATCH] libdw: Simplify __libdw_getabbrev and fix dwarf_offabbrev | ||
5 | issue | ||
6 | |||
7 | __libdw_getabbrev could crash on reading a bad abbrev by trying to | ||
8 | deallocate memory it didn't allocate itself. This could happen because | ||
9 | dwarf_offabbrev would supply its own memory when calling | ||
10 | __libdw_getabbrev. No other caller did this. | ||
11 | |||
12 | Simplify the __libdw_getabbrev common code by not taking external | ||
13 | memory to put the abbrev result in (this would also not work correctly | ||
14 | if the abbrev was already cached). And make dwarf_offabbrev explicitly | ||
15 | copy the result (if there was no error or end of abbrev). | ||
16 | |||
17 | * libdw/dwarf_getabbrev.c (__libdw_getabbrev): Don't take | ||
18 | Dwarf_Abbrev result argument. Always just allocate abb when | ||
19 | abbrev not found in cache. | ||
20 | (dwarf_getabbrev): Don't pass NULL as last argument to | ||
21 | __libdw_getabbrev. | ||
22 | * libdw/dwarf_tag.c (__libdw_findabbrev): Likewise. | ||
23 | * libdw/dwarf_offabbrev.c (dwarf_offabbrev): Likewise. And copy | ||
24 | abbrev into abbrevp on success. | ||
25 | * libdw/libdw.h (dwarf_offabbrev): Document return values. | ||
26 | * libdw/libdwP.h (__libdw_getabbrev): Don't take Dwarf_Abbrev | ||
27 | result argument. | ||
28 | |||
29 | https://sourceware.org/bugzilla/show_bug.cgi?id=32650 | ||
30 | |||
31 | Signed-off-by: Mark Wielaard <mark@klomp.org> | ||
32 | |||
33 | Upstream-Status: Backport [https://sourceware.org/git/?p=elfutils.git;a=commit;h=2636426a091bd6c6f7f02e49ab20d4cdc6bfc753] | ||
34 | CVE: CVE-2025-1352 | ||
35 | Signed-off-by: Hitendra Prajapati <hprajapati@mvista.com> | ||
36 | --- | ||
37 | libdw/dwarf_getabbrev.c | 12 ++++-------- | ||
38 | libdw/dwarf_offabbrev.c | 10 +++++++--- | ||
39 | libdw/dwarf_tag.c | 3 +-- | ||
40 | libdw/libdw.h | 4 +++- | ||
41 | libdw/libdwP.h | 3 +-- | ||
42 | 5 files changed, 16 insertions(+), 16 deletions(-) | ||
43 | |||
44 | diff --git a/libdw/dwarf_getabbrev.c b/libdw/dwarf_getabbrev.c | ||
45 | index 5b02333..d9a6c02 100644 | ||
46 | --- a/libdw/dwarf_getabbrev.c | ||
47 | +++ b/libdw/dwarf_getabbrev.c | ||
48 | @@ -1,5 +1,6 @@ | ||
49 | /* Get abbreviation at given offset. | ||
50 | Copyright (C) 2003, 2004, 2005, 2006, 2014, 2017 Red Hat, Inc. | ||
51 | + Copyright (C) 2025 Mark J. Wielaard <mark@klomp.org> | ||
52 | This file is part of elfutils. | ||
53 | Written by Ulrich Drepper <drepper@redhat.com>, 2003. | ||
54 | |||
55 | @@ -38,7 +39,7 @@ | ||
56 | Dwarf_Abbrev * | ||
57 | internal_function | ||
58 | __libdw_getabbrev (Dwarf *dbg, struct Dwarf_CU *cu, Dwarf_Off offset, | ||
59 | - size_t *lengthp, Dwarf_Abbrev *result) | ||
60 | + size_t *lengthp) | ||
61 | { | ||
62 | /* Don't fail if there is not .debug_abbrev section. */ | ||
63 | if (dbg->sectiondata[IDX_debug_abbrev] == NULL) | ||
64 | @@ -85,12 +86,7 @@ __libdw_getabbrev (Dwarf *dbg, struct Dwarf_CU *cu, Dwarf_Off offset, | ||
65 | Dwarf_Abbrev *abb = NULL; | ||
66 | if (cu == NULL | ||
67 | || (abb = Dwarf_Abbrev_Hash_find (&cu->abbrev_hash, code)) == NULL) | ||
68 | - { | ||
69 | - if (result == NULL) | ||
70 | - abb = libdw_typed_alloc (dbg, Dwarf_Abbrev); | ||
71 | - else | ||
72 | - abb = result; | ||
73 | - } | ||
74 | + abb = libdw_typed_alloc (dbg, Dwarf_Abbrev); | ||
75 | else | ||
76 | { | ||
77 | foundit = true; | ||
78 | @@ -183,5 +179,5 @@ dwarf_getabbrev (Dwarf_Die *die, Dwarf_Off offset, size_t *lengthp) | ||
79 | return NULL; | ||
80 | } | ||
81 | |||
82 | - return __libdw_getabbrev (dbg, cu, abbrev_offset + offset, lengthp, NULL); | ||
83 | + return __libdw_getabbrev (dbg, cu, abbrev_offset + offset, lengthp); | ||
84 | } | ||
85 | diff --git a/libdw/dwarf_offabbrev.c b/libdw/dwarf_offabbrev.c | ||
86 | index 27cdad6..41df69b 100644 | ||
87 | --- a/libdw/dwarf_offabbrev.c | ||
88 | +++ b/libdw/dwarf_offabbrev.c | ||
89 | @@ -41,11 +41,15 @@ dwarf_offabbrev (Dwarf *dbg, Dwarf_Off offset, size_t *lengthp, | ||
90 | if (dbg == NULL) | ||
91 | return -1; | ||
92 | |||
93 | - Dwarf_Abbrev *abbrev = __libdw_getabbrev (dbg, NULL, offset, lengthp, | ||
94 | - abbrevp); | ||
95 | + Dwarf_Abbrev *abbrev = __libdw_getabbrev (dbg, NULL, offset, lengthp); | ||
96 | |||
97 | if (abbrev == NULL) | ||
98 | return -1; | ||
99 | |||
100 | - return abbrev == DWARF_END_ABBREV ? 1 : 0; | ||
101 | + if (abbrev == DWARF_END_ABBREV) | ||
102 | + return 1; | ||
103 | + | ||
104 | + *abbrevp = *abbrev; | ||
105 | + | ||
106 | + return 0; | ||
107 | } | ||
108 | diff --git a/libdw/dwarf_tag.c b/libdw/dwarf_tag.c | ||
109 | index d784970..218382a 100644 | ||
110 | --- a/libdw/dwarf_tag.c | ||
111 | +++ b/libdw/dwarf_tag.c | ||
112 | @@ -53,8 +53,7 @@ __libdw_findabbrev (struct Dwarf_CU *cu, unsigned int code) | ||
113 | |||
114 | /* Find the next entry. It gets automatically added to the | ||
115 | hash table. */ | ||
116 | - abb = __libdw_getabbrev (cu->dbg, cu, cu->last_abbrev_offset, &length, | ||
117 | - NULL); | ||
118 | + abb = __libdw_getabbrev (cu->dbg, cu, cu->last_abbrev_offset, &length); | ||
119 | if (abb == NULL || abb == DWARF_END_ABBREV) | ||
120 | { | ||
121 | /* Make sure we do not try to search for it again. */ | ||
122 | diff --git a/libdw/libdw.h b/libdw/libdw.h | ||
123 | index d53dc78..ec4713a 100644 | ||
124 | --- a/libdw/libdw.h | ||
125 | +++ b/libdw/libdw.h | ||
126 | @@ -587,7 +587,9 @@ extern int dwarf_srclang (Dwarf_Die *die); | ||
127 | extern Dwarf_Abbrev *dwarf_getabbrev (Dwarf_Die *die, Dwarf_Off offset, | ||
128 | size_t *lengthp); | ||
129 | |||
130 | -/* Get abbreviation at given offset in .debug_abbrev section. */ | ||
131 | +/* Get abbreviation at given offset in .debug_abbrev section. On | ||
132 | + success return zero and fills in ABBREVP. When there is no (more) | ||
133 | + abbrev at offset returns one. On error returns a negative value. */ | ||
134 | extern int dwarf_offabbrev (Dwarf *dbg, Dwarf_Off offset, size_t *lengthp, | ||
135 | Dwarf_Abbrev *abbrevp) | ||
136 | __nonnull_attribute__ (4); | ||
137 | diff --git a/libdw/libdwP.h b/libdw/libdwP.h | ||
138 | index 8b2f06f..f0f4b78 100644 | ||
139 | --- a/libdw/libdwP.h | ||
140 | +++ b/libdw/libdwP.h | ||
141 | @@ -783,8 +783,7 @@ extern Dwarf_Abbrev *__libdw_findabbrev (struct Dwarf_CU *cu, | ||
142 | |||
143 | /* Get abbreviation at given offset. */ | ||
144 | extern Dwarf_Abbrev *__libdw_getabbrev (Dwarf *dbg, struct Dwarf_CU *cu, | ||
145 | - Dwarf_Off offset, size_t *lengthp, | ||
146 | - Dwarf_Abbrev *result) | ||
147 | + Dwarf_Off offset, size_t *lengthp) | ||
148 | __nonnull_attribute__ (1) internal_function; | ||
149 | |||
150 | /* Get abbreviation of given DIE, and optionally set *READP to the DIE memory | ||
151 | -- | ||
152 | 2.25.1 | ||
153 | |||
diff --git a/meta/recipes-devtools/elfutils/files/CVE-2025-1365.patch b/meta/recipes-devtools/elfutils/files/CVE-2025-1365.patch new file mode 100644 index 0000000000..002ce334a3 --- /dev/null +++ b/meta/recipes-devtools/elfutils/files/CVE-2025-1365.patch | |||
@@ -0,0 +1,151 @@ | |||
1 | From 5e5c0394d82c53e97750fe7b18023e6f84157b81 Mon Sep 17 00:00:00 2001 | ||
2 | From: Mark Wielaard <mark@klomp.org> | ||
3 | Date: Sat, 8 Feb 2025 21:44:56 +0100 | ||
4 | Subject: [PATCH] libelf, readelf: Use validate_str also to check dynamic | ||
5 | symstr data | ||
6 | |||
7 | When dynsym/str was read through eu-readelf --dynamic by readelf | ||
8 | process_symtab the string data was not validated, possibly printing | ||
9 | unallocated memory past the end of the symstr data. Fix this by | ||
10 | turning the elf_strptr validate_str function into a generic | ||
11 | lib/system.h helper function and use it in readelf to validate the | ||
12 | strings before use. | ||
13 | |||
14 | * libelf/elf_strptr.c (validate_str): Remove to... | ||
15 | * lib/system.h (validate_str): ... here. Make inline, simplify | ||
16 | check and document. | ||
17 | * src/readelf.c (process_symtab): Use validate_str on symstr_data. | ||
18 | |||
19 | https://sourceware.org/bugzilla/show_bug.cgi?id=32654 | ||
20 | |||
21 | Signed-off-by: Mark Wielaard <mark@klomp.org> | ||
22 | |||
23 | Upstream-Status: Backport [https://sourceware.org/git/?p=elfutils.git;a=commit;h=5e5c0394d82c53e97750fe7b18023e6f84157b81] | ||
24 | CVE: CVE-2025-1365 | ||
25 | Signed-off-by: Hitendra Prajapati <hprajapati@mvista.com> | ||
26 | --- | ||
27 | lib/system.h | 27 +++++++++++++++++++++++++++ | ||
28 | libelf/elf_strptr.c | 18 ------------------ | ||
29 | src/readelf.c | 18 +++++++++++++++--- | ||
30 | 3 files changed, 42 insertions(+), 21 deletions(-) | ||
31 | |||
32 | diff --git a/lib/system.h b/lib/system.h | ||
33 | index 0db12d9..0698e5f 100644 | ||
34 | --- a/lib/system.h | ||
35 | +++ b/lib/system.h | ||
36 | @@ -34,6 +34,7 @@ | ||
37 | #include <config.h> | ||
38 | |||
39 | #include <errno.h> | ||
40 | +#include <stdbool.h> | ||
41 | #include <stddef.h> | ||
42 | #include <stdint.h> | ||
43 | #include <string.h> | ||
44 | @@ -117,6 +118,32 @@ startswith (const char *str, const char *prefix) | ||
45 | return strncmp (str, prefix, strlen (prefix)) == 0; | ||
46 | } | ||
47 | |||
48 | +/* Return TRUE if STR[FROM] is a valid string with a zero terminator | ||
49 | + at or before STR[TO - 1]. Note FROM is an index into the STR | ||
50 | + array, while TO is the maximum size of the STR array. This | ||
51 | + function returns FALSE when TO is zero or FROM >= TO. */ | ||
52 | +static inline bool | ||
53 | +validate_str (const char *str, size_t from, size_t to) | ||
54 | +{ | ||
55 | +#if HAVE_DECL_MEMRCHR | ||
56 | + // Check end first, which is likely a zero terminator, | ||
57 | + // to prevent function call | ||
58 | + return (to > 0 | ||
59 | + && (str[to - 1] == '\0' | ||
60 | + || (to > from | ||
61 | + && memrchr (&str[from], '\0', to - from - 1) != NULL))); | ||
62 | +#else | ||
63 | + do { | ||
64 | + if (to <= from) | ||
65 | + return false; | ||
66 | + | ||
67 | + to--; | ||
68 | + } while (str[to]); | ||
69 | + | ||
70 | + return true; | ||
71 | +#endif | ||
72 | +} | ||
73 | + | ||
74 | /* A special gettext function we use if the strings are too short. */ | ||
75 | #define sgettext(Str) \ | ||
76 | ({ const char *__res = strrchr (_(Str), '|'); \ | ||
77 | diff --git a/libelf/elf_strptr.c b/libelf/elf_strptr.c | ||
78 | index 79a24d2..c5a94f8 100644 | ||
79 | --- a/libelf/elf_strptr.c | ||
80 | +++ b/libelf/elf_strptr.c | ||
81 | @@ -53,24 +53,6 @@ get_zdata (Elf_Scn *strscn) | ||
82 | return zdata; | ||
83 | } | ||
84 | |||
85 | -static bool validate_str (const char *str, size_t from, size_t to) | ||
86 | -{ | ||
87 | -#if HAVE_DECL_MEMRCHR | ||
88 | - // Check end first, which is likely a zero terminator, to prevent function call | ||
89 | - return ((to > 0 && str[to - 1] == '\0') | ||
90 | - || (to - from > 0 && memrchr (&str[from], '\0', to - from - 1) != NULL)); | ||
91 | -#else | ||
92 | - do { | ||
93 | - if (to <= from) | ||
94 | - return false; | ||
95 | - | ||
96 | - to--; | ||
97 | - } while (str[to]); | ||
98 | - | ||
99 | - return true; | ||
100 | -#endif | ||
101 | -} | ||
102 | - | ||
103 | char * | ||
104 | elf_strptr (Elf *elf, size_t idx, size_t offset) | ||
105 | { | ||
106 | diff --git a/src/readelf.c b/src/readelf.c | ||
107 | index 0e93118..63eb548 100644 | ||
108 | --- a/src/readelf.c | ||
109 | +++ b/src/readelf.c | ||
110 | @@ -2639,6 +2639,7 @@ process_symtab (Ebl *ebl, unsigned int nsyms, Elf64_Word idx, | ||
111 | char typebuf[64]; | ||
112 | char bindbuf[64]; | ||
113 | char scnbuf[64]; | ||
114 | + const char *sym_name; | ||
115 | Elf32_Word xndx; | ||
116 | GElf_Sym sym_mem; | ||
117 | GElf_Sym *sym | ||
118 | @@ -2650,6 +2651,19 @@ process_symtab (Ebl *ebl, unsigned int nsyms, Elf64_Word idx, | ||
119 | /* Determine the real section index. */ | ||
120 | if (likely (sym->st_shndx != SHN_XINDEX)) | ||
121 | xndx = sym->st_shndx; | ||
122 | + if (use_dynamic_segment == true) | ||
123 | + { | ||
124 | + if (validate_str (symstr_data->d_buf, sym->st_name, | ||
125 | + symstr_data->d_size)) | ||
126 | + sym_name = (char *)symstr_data->d_buf + sym->st_name; | ||
127 | + else | ||
128 | + sym_name = NULL; | ||
129 | + } | ||
130 | + else | ||
131 | + sym_name = elf_strptr (ebl->elf, idx, sym->st_name); | ||
132 | + | ||
133 | + if (sym_name == NULL) | ||
134 | + sym_name = "???"; | ||
135 | |||
136 | printf (_ ("\ | ||
137 | %5u: %0*" PRIx64 " %6" PRId64 " %-7s %-6s %-9s %6s %s"), | ||
138 | @@ -2662,9 +2676,7 @@ process_symtab (Ebl *ebl, unsigned int nsyms, Elf64_Word idx, | ||
139 | get_visibility_type (GELF_ST_VISIBILITY (sym->st_other)), | ||
140 | ebl_section_name (ebl, sym->st_shndx, xndx, scnbuf, | ||
141 | sizeof (scnbuf), NULL, shnum), | ||
142 | - use_dynamic_segment == true | ||
143 | - ? (char *)symstr_data->d_buf + sym->st_name | ||
144 | - : elf_strptr (ebl->elf, idx, sym->st_name)); | ||
145 | + sym_name); | ||
146 | |||
147 | if (versym_data != NULL) | ||
148 | { | ||
149 | -- | ||
150 | 2.25.1 | ||
151 | |||
diff --git a/meta/recipes-devtools/elfutils/files/CVE-2025-1372.patch b/meta/recipes-devtools/elfutils/files/CVE-2025-1372.patch new file mode 100644 index 0000000000..812a098447 --- /dev/null +++ b/meta/recipes-devtools/elfutils/files/CVE-2025-1372.patch | |||
@@ -0,0 +1,50 @@ | |||
1 | From 73db9d2021cab9e23fd734b0a76a612d52a6f1db Mon Sep 17 00:00:00 2001 | ||
2 | From: Mark Wielaard <mark@klomp.org> | ||
3 | Date: Sun, 9 Feb 2025 00:07:39 +0100 | ||
4 | Subject: [PATCH] readelf: Skip trying to uncompress sections without a name | ||
5 | |||
6 | When combining eu-readelf -z with -x or -p to dump the data or strings | ||
7 | in an (corrupted ELF) unnamed numbered section eu-readelf could crash | ||
8 | trying to check whether the section name starts with .zdebug. Fix this | ||
9 | by skipping sections without a name. | ||
10 | |||
11 | * src/readelf.c (dump_data_section): Don't try to gnu decompress a | ||
12 | section without a name. | ||
13 | (print_string_section): Likewise. | ||
14 | |||
15 | https://sourceware.org/bugzilla/show_bug.cgi?id=32656 | ||
16 | |||
17 | Signed-off-by: Mark Wielaard <mark@klomp.org> | ||
18 | |||
19 | Upstream-Status: Backport [https://sourceware.org/git/?p=elfutils.git;a=commit;h=73db9d2021cab9e23fd734b0a76a612d52a6f1db] | ||
20 | CVE: CVE-2025-1372 | ||
21 | Signed-off-by: Hitendra Prajapati <hprajapati@mvista.com> | ||
22 | --- | ||
23 | src/readelf.c | 4 ++-- | ||
24 | 1 file changed, 2 insertions(+), 2 deletions(-) | ||
25 | |||
26 | diff --git a/src/readelf.c b/src/readelf.c | ||
27 | index 63eb548..fc04556 100644 | ||
28 | --- a/src/readelf.c | ||
29 | +++ b/src/readelf.c | ||
30 | @@ -13327,7 +13327,7 @@ dump_data_section (Elf_Scn *scn, const GElf_Shdr *shdr, const char *name) | ||
31 | _("Couldn't uncompress section"), | ||
32 | elf_ndxscn (scn)); | ||
33 | } | ||
34 | - else if (startswith (name, ".zdebug")) | ||
35 | + else if (name && startswith (name, ".zdebug")) | ||
36 | { | ||
37 | if (elf_compress_gnu (scn, 0, 0) < 0) | ||
38 | printf ("WARNING: %s [%zd]\n", | ||
39 | @@ -13378,7 +13378,7 @@ print_string_section (Elf_Scn *scn, const GElf_Shdr *shdr, const char *name) | ||
40 | _("Couldn't uncompress section"), | ||
41 | elf_ndxscn (scn)); | ||
42 | } | ||
43 | - else if (startswith (name, ".zdebug")) | ||
44 | + else if (name && startswith (name, ".zdebug")) | ||
45 | { | ||
46 | if (elf_compress_gnu (scn, 0, 0) < 0) | ||
47 | printf ("WARNING: %s [%zd]\n", | ||
48 | -- | ||
49 | 2.25.1 | ||
50 | |||