@@ -22,6 +22,7 @@ SRC_URI = "https://sourceware.org/elfutils/ftp/${PV}/${BP}.tar.bz2 \
file://0001-tests-Makefile.am-compile-test_nlist-with-standard-C.patch \
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 \
"
SRC_URI:append:libc-musl = " \
file://0003-musl-utils.patch \
new file mode 100644
@@ -0,0 +1,154 @@
+From 2636426a091bd6c6f7f02e49ab20d4cdc6bfc753 Mon Sep 17 00:00:00 2001
+From: Mark Wielaard <mark@klomp.org>
+Date: Sat, 8 Feb 2025 20:00:12 +0100
+Subject: [PATCH] libdw: Simplify __libdw_getabbrev and fix dwarf_offabbrev
+ issue
+
+__libdw_getabbrev could crash on reading a bad abbrev by trying to
+deallocate memory it didn't allocate itself. This could happen because
+dwarf_offabbrev would supply its own memory when calling
+__libdw_getabbrev. No other caller did this.
+
+Simplify the __libdw_getabbrev common code by not taking external
+memory to put the abbrev result in (this would also not work correctly
+if the abbrev was already cached). And make dwarf_offabbrev explicitly
+copy the result (if there was no error or end of abbrev).
+
+ * libdw/dwarf_getabbrev.c (__libdw_getabbrev): Don't take
+ Dwarf_Abbrev result argument. Always just allocate abb when
+ abbrev not found in cache.
+ (dwarf_getabbrev): Don't pass NULL as last argument to
+ __libdw_getabbrev.
+ * libdw/dwarf_tag.c (__libdw_findabbrev): Likewise.
+ * libdw/dwarf_offabbrev.c (dwarf_offabbrev): Likewise. And copy
+ abbrev into abbrevp on success.
+ * libdw/libdw.h (dwarf_offabbrev): Document return values.
+ * libdw/libdwP.h (__libdw_getabbrev): Don't take Dwarf_Abbrev
+ result argument.
+
+https://sourceware.org/bugzilla/show_bug.cgi?id=32650
+
+CVE: CVE-2025-1352
+
+Upstream-Status: Backport [https://sourceware.org/git/?p=elfutils.git;a=2636426a091bd6c6f7f02e49ab20d4cdc6bfc753]
+
+Signed-off-by: Mark Wielaard <mark@klomp.org>
+Signed-off-by: Soumya Sambu <soumya.sambu@windriver.com>
+---
+ libdw/dwarf_getabbrev.c | 12 ++++--------
+ libdw/dwarf_offabbrev.c | 10 +++++++---
+ libdw/dwarf_tag.c | 3 +--
+ libdw/libdw.h | 4 +++-
+ libdw/libdwP.h | 3 +--
+ 5 files changed, 16 insertions(+), 16 deletions(-)
+
+diff --git a/libdw/dwarf_getabbrev.c b/libdw/dwarf_getabbrev.c
+index 5b02333..d9a6c02 100644
+--- a/libdw/dwarf_getabbrev.c
++++ b/libdw/dwarf_getabbrev.c
+@@ -1,5 +1,6 @@
+ /* Get abbreviation at given offset.
+ Copyright (C) 2003, 2004, 2005, 2006, 2014, 2017 Red Hat, Inc.
++ Copyright (C) 2025 Mark J. Wielaard <mark@klomp.org>
+ This file is part of elfutils.
+ Written by Ulrich Drepper <drepper@redhat.com>, 2003.
+
+@@ -38,7 +39,7 @@
+ Dwarf_Abbrev *
+ internal_function
+ __libdw_getabbrev (Dwarf *dbg, struct Dwarf_CU *cu, Dwarf_Off offset,
+- size_t *lengthp, Dwarf_Abbrev *result)
++ size_t *lengthp)
+ {
+ /* Don't fail if there is not .debug_abbrev section. */
+ if (dbg->sectiondata[IDX_debug_abbrev] == NULL)
+@@ -85,12 +86,7 @@ __libdw_getabbrev (Dwarf *dbg, struct Dwarf_CU *cu, Dwarf_Off offset,
+ Dwarf_Abbrev *abb = NULL;
+ if (cu == NULL
+ || (abb = Dwarf_Abbrev_Hash_find (&cu->abbrev_hash, code)) == NULL)
+- {
+- if (result == NULL)
+- abb = libdw_typed_alloc (dbg, Dwarf_Abbrev);
+- else
+- abb = result;
+- }
++ abb = libdw_typed_alloc (dbg, Dwarf_Abbrev);
+ else
+ {
+ foundit = true;
+@@ -183,5 +179,5 @@ dwarf_getabbrev (Dwarf_Die *die, Dwarf_Off offset, size_t *lengthp)
+ return NULL;
+ }
+
+- return __libdw_getabbrev (dbg, cu, abbrev_offset + offset, lengthp, NULL);
++ return __libdw_getabbrev (dbg, cu, abbrev_offset + offset, lengthp);
+ }
+diff --git a/libdw/dwarf_offabbrev.c b/libdw/dwarf_offabbrev.c
+index 27cdad6..41df69b 100644
+--- a/libdw/dwarf_offabbrev.c
++++ b/libdw/dwarf_offabbrev.c
+@@ -41,11 +41,15 @@ dwarf_offabbrev (Dwarf *dbg, Dwarf_Off offset, size_t *lengthp,
+ if (dbg == NULL)
+ return -1;
+
+- Dwarf_Abbrev *abbrev = __libdw_getabbrev (dbg, NULL, offset, lengthp,
+- abbrevp);
++ Dwarf_Abbrev *abbrev = __libdw_getabbrev (dbg, NULL, offset, lengthp);
+
+ if (abbrev == NULL)
+ return -1;
+
+- return abbrev == DWARF_END_ABBREV ? 1 : 0;
++ if (abbrev == DWARF_END_ABBREV)
++ return 1;
++
++ *abbrevp = *abbrev;
++
++ return 0;
+ }
+diff --git a/libdw/dwarf_tag.c b/libdw/dwarf_tag.c
+index d784970..218382a 100644
+--- a/libdw/dwarf_tag.c
++++ b/libdw/dwarf_tag.c
+@@ -53,8 +53,7 @@ __libdw_findabbrev (struct Dwarf_CU *cu, unsigned int code)
+
+ /* Find the next entry. It gets automatically added to the
+ hash table. */
+- abb = __libdw_getabbrev (cu->dbg, cu, cu->last_abbrev_offset, &length,
+- NULL);
++ abb = __libdw_getabbrev (cu->dbg, cu, cu->last_abbrev_offset, &length);
+ if (abb == NULL || abb == DWARF_END_ABBREV)
+ {
+ /* Make sure we do not try to search for it again. */
+diff --git a/libdw/libdw.h b/libdw/libdw.h
+index d53dc78..ec4713a 100644
+--- a/libdw/libdw.h
++++ b/libdw/libdw.h
+@@ -587,7 +587,9 @@ extern int dwarf_srclang (Dwarf_Die *die);
+ extern Dwarf_Abbrev *dwarf_getabbrev (Dwarf_Die *die, Dwarf_Off offset,
+ size_t *lengthp);
+
+-/* Get abbreviation at given offset in .debug_abbrev section. */
++/* Get abbreviation at given offset in .debug_abbrev section. On
++ success return zero and fills in ABBREVP. When there is no (more)
++ abbrev at offset returns one. On error returns a negative value. */
+ extern int dwarf_offabbrev (Dwarf *dbg, Dwarf_Off offset, size_t *lengthp,
+ Dwarf_Abbrev *abbrevp)
+ __nonnull_attribute__ (4);
+diff --git a/libdw/libdwP.h b/libdw/libdwP.h
+index d6bab60..0cff5c2 100644
+--- a/libdw/libdwP.h
++++ b/libdw/libdwP.h
+@@ -795,8 +795,7 @@ extern Dwarf_Abbrev *__libdw_findabbrev (struct Dwarf_CU *cu,
+
+ /* Get abbreviation at given offset. */
+ extern Dwarf_Abbrev *__libdw_getabbrev (Dwarf *dbg, struct Dwarf_CU *cu,
+- Dwarf_Off offset, size_t *lengthp,
+- Dwarf_Abbrev *result)
++ Dwarf_Off offset, size_t *lengthp)
+ __nonnull_attribute__ (1) internal_function;
+
+ /* Get abbreviation of given DIE, and optionally set *READP to the DIE memory
+--
+2.43.2
+