diff --git a/meta/recipes-devtools/elfutils/elfutils_0.192.bb b/meta/recipes-devtools/elfutils/elfutils_0.192.bb index 829d9bf94f..ff40ba64ec 100644 --- a/meta/recipes-devtools/elfutils/elfutils_0.192.bb +++ b/meta/recipes-devtools/elfutils/elfutils_0.192.bb @@ -23,6 +23,7 @@ SRC_URI = "https://sourceware.org/elfutils/ftp/${PV}/${BP}.tar.bz2 \ file://0001-config-eu.am-do-not-force-Werror.patch \ file://0001-libelf-Add-libeu-objects-to-libelf.a-static-archive.patch \ file://CVE-2025-1352.patch \ + file://CVE-2025-1365.patch \ " SRC_URI:append:libc-musl = " \ file://0003-musl-utils.patch \ 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..b779685efd --- /dev/null +++ b/meta/recipes-devtools/elfutils/files/CVE-2025-1365.patch @@ -0,0 +1,152 @@ +From 5e5c0394d82c53e97750fe7b18023e6f84157b81 Mon Sep 17 00:00:00 2001 +From: Mark Wielaard +Date: Sat, 8 Feb 2025 21:44:56 +0100 +Subject: [PATCH] libelf, readelf: Use validate_str also to check dynamic + symstr data + +When dynsym/str was read through eu-readelf --dynamic by readelf +process_symtab the string data was not validated, possibly printing +unallocated memory past the end of the symstr data. Fix this by +turning the elf_strptr validate_str function into a generic +lib/system.h helper function and use it in readelf to validate the +strings before use. + + * libelf/elf_strptr.c (validate_str): Remove to... + * lib/system.h (validate_str): ... here. Make inline, simplify + check and document. + * src/readelf.c (process_symtab): Use validate_str on symstr_data. + +https://sourceware.org/bugzilla/show_bug.cgi?id=32654 + +CVE: CVE-2025-1365 + +Upstream-Status: Backport [https://sourceware.org/git/?p=elfutils.git;a=commit;h=5e5c0394d82c53e97750fe7b18023e6f84157b81] + +Signed-off-by: Mark Wielaard +Signed-off-by: Soumya Sambu +--- + lib/system.h | 27 +++++++++++++++++++++++++++ + libelf/elf_strptr.c | 18 ------------------ + src/readelf.c | 18 +++++++++++++++--- + 3 files changed, 42 insertions(+), 21 deletions(-) + +diff --git a/lib/system.h b/lib/system.h +index 0db12d9..0698e5f 100644 +--- a/lib/system.h ++++ b/lib/system.h +@@ -34,6 +34,7 @@ + #include + + #include ++#include + #include + #include + #include +@@ -117,6 +118,32 @@ startswith (const char *str, const char *prefix) + return strncmp (str, prefix, strlen (prefix)) == 0; + } + ++/* Return TRUE if STR[FROM] is a valid string with a zero terminator ++ at or before STR[TO - 1]. Note FROM is an index into the STR ++ array, while TO is the maximum size of the STR array. This ++ function returns FALSE when TO is zero or FROM >= TO. */ ++static inline bool ++validate_str (const char *str, size_t from, size_t to) ++{ ++#if HAVE_DECL_MEMRCHR ++ // Check end first, which is likely a zero terminator, ++ // to prevent function call ++ return (to > 0 ++ && (str[to - 1] == '\0' ++ || (to > from ++ && memrchr (&str[from], '\0', to - from - 1) != NULL))); ++#else ++ do { ++ if (to <= from) ++ return false; ++ ++ to--; ++ } while (str[to]); ++ ++ return true; ++#endif ++} ++ + /* A special gettext function we use if the strings are too short. */ + #define sgettext(Str) \ + ({ const char *__res = strrchr (_(Str), '|'); \ +diff --git a/libelf/elf_strptr.c b/libelf/elf_strptr.c +index 79a24d2..c5a94f8 100644 +--- a/libelf/elf_strptr.c ++++ b/libelf/elf_strptr.c +@@ -53,24 +53,6 @@ get_zdata (Elf_Scn *strscn) + return zdata; + } + +-static bool validate_str (const char *str, size_t from, size_t to) +-{ +-#if HAVE_DECL_MEMRCHR +- // Check end first, which is likely a zero terminator, to prevent function call +- return ((to > 0 && str[to - 1] == '\0') +- || (to - from > 0 && memrchr (&str[from], '\0', to - from - 1) != NULL)); +-#else +- do { +- if (to <= from) +- return false; +- +- to--; +- } while (str[to]); +- +- return true; +-#endif +-} +- + char * + elf_strptr (Elf *elf, size_t idx, size_t offset) + { +diff --git a/src/readelf.c b/src/readelf.c +index 3e97b64..105cddf 100644 +--- a/src/readelf.c ++++ b/src/readelf.c +@@ -2639,6 +2639,7 @@ process_symtab (Ebl *ebl, unsigned int nsyms, Elf64_Word idx, + char typebuf[64]; + char bindbuf[64]; + char scnbuf[64]; ++ const char *sym_name; + Elf32_Word xndx; + GElf_Sym sym_mem; + GElf_Sym *sym +@@ -2650,6 +2651,19 @@ process_symtab (Ebl *ebl, unsigned int nsyms, Elf64_Word idx, + /* Determine the real section index. */ + if (likely (sym->st_shndx != SHN_XINDEX)) + xndx = sym->st_shndx; ++ if (use_dynamic_segment == true) ++ { ++ if (validate_str (symstr_data->d_buf, sym->st_name, ++ symstr_data->d_size)) ++ sym_name = (char *)symstr_data->d_buf + sym->st_name; ++ else ++ sym_name = NULL; ++ } ++ else ++ sym_name = elf_strptr (ebl->elf, idx, sym->st_name); ++ ++ if (sym_name == NULL) ++ sym_name = "???"; + + printf (_ ("\ + %5u: %0*" PRIx64 " %6" PRId64 " %-7s %-6s %-9s %6s %s"), +@@ -2662,9 +2676,7 @@ process_symtab (Ebl *ebl, unsigned int nsyms, Elf64_Word idx, + get_visibility_type (GELF_ST_VISIBILITY (sym->st_other)), + ebl_section_name (ebl, sym->st_shndx, xndx, scnbuf, + sizeof (scnbuf), NULL, shnum), +- use_dynamic_segment == true +- ? (char *)symstr_data->d_buf + sym->st_name +- : elf_strptr (ebl->elf, idx, sym->st_name)); ++ sym_name); + + if (versym_data != NULL) + { +-- +2.43.2 +