@@ -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 \
new file mode 100644
@@ -0,0 +1,152 @@
+From 5e5c0394d82c53e97750fe7b18023e6f84157b81 Mon Sep 17 00:00:00 2001
+From: Mark Wielaard <mark@klomp.org>
+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 <mark@klomp.org>
+Signed-off-by: Soumya Sambu <soumya.sambu@windriver.com>
+---
+ 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 <config.h>
+
+ #include <errno.h>
++#include <stdbool.h>
+ #include <stddef.h>
+ #include <stdint.h>
+ #include <string.h>
+@@ -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
+