165 lines
5.5 KiB
Diff
165 lines
5.5 KiB
Diff
|
|
From 404e6b1b14f60c81388d50b4239f81d461b3c3ad Mon Sep 17 00:00:00 2001
|
||
|
|
From: David Anderson <davea42@linuxmail.org>
|
||
|
|
Date: Sat, 17 Feb 2024 13:33:39 -0800
|
||
|
|
Subject: [PATCH] Fixing DW202402-002, corrupt object caused various libdwarf
|
||
|
|
crashes with some tailored/fuzzed object files. modified:
|
||
|
|
src/lib/libdwarf/dwarf_alloc.c modified:
|
||
|
|
src/lib/libdwarf/dwarf_error.c
|
||
|
|
|
||
|
|
Origin: https://github.com/davea42/libdwarf-code/commit/404e6b1b14f60c81388d50b4239f81d461b3c3ad
|
||
|
|
|
||
|
|
---
|
||
|
|
src/lib/libdwarf/dwarf_alloc.c | 56 ++++++++++++++++++++++++++++++++--
|
||
|
|
src/lib/libdwarf/dwarf_error.c | 5 +--
|
||
|
|
2 files changed, 57 insertions(+), 4 deletions(-)
|
||
|
|
|
||
|
|
diff --git a/src/lib/libdwarf/dwarf_alloc.c b/src/lib/libdwarf/dwarf_alloc.c
|
||
|
|
index 9ef9b16f4..a73b8abf9 100644
|
||
|
|
--- a/src/lib/libdwarf/dwarf_alloc.c
|
||
|
|
+++ b/src/lib/libdwarf/dwarf_alloc.c
|
||
|
|
@@ -143,6 +143,7 @@ _dwarf_error_destructor(void *m)
|
||
|
|
#if DEBUG_ALLOC
|
||
|
|
printf("libdwarfdetector DEALLOC Now destruct error "
|
||
|
|
"string %s\n",dwarfstring_string(erm));
|
||
|
|
+ fflush(stdout);
|
||
|
|
#endif /* DEBUG_ALLOC */
|
||
|
|
dwarfstring_destructor(erm);
|
||
|
|
free(erm);
|
||
|
|
@@ -182,6 +183,8 @@ struct reserve_data_s {
|
||
|
|
|
||
|
|
#define STATIC_ALLOWED 10 /* arbitrary, must be > 2, see below*/
|
||
|
|
static unsigned static_used = 0;
|
||
|
|
+/* entries in this list point to allocations of
|
||
|
|
+ type DW_DLA_ERROR. */
|
||
|
|
static Dwarf_Error staticerrlist[STATIC_ALLOWED];
|
||
|
|
|
||
|
|
/* Clean this out if found */
|
||
|
|
@@ -215,7 +218,7 @@ dw_empty_errlist_item(Dwarf_Error e_in)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
-/* If the userr calls dwarf_dealloc on an error
|
||
|
|
+/* If the user calls dwarf_dealloc on an error
|
||
|
|
out of a dwarf_init*() call, this will find
|
||
|
|
it in the static err list. Here dbg is NULL
|
||
|
|
so not mentioned. */
|
||
|
|
@@ -226,11 +229,21 @@ _dwarf_add_to_static_err_list(Dwarf_Error error)
|
||
|
|
if (!error) {
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
+#ifdef DEBUG_ALLOC
|
||
|
|
+ printf("\nlibdwarfdetector add to static err list "
|
||
|
|
+ " 0x%lx\n",(unsigned long)(uintptr_t)error);
|
||
|
|
+ fflush(stdout);
|
||
|
|
+#endif /* DEBUG_ALLOC */
|
||
|
|
for ( ; i <static_used; ++i) {
|
||
|
|
Dwarf_Error e = staticerrlist[i];
|
||
|
|
if (e) {
|
||
|
|
continue;
|
||
|
|
}
|
||
|
|
+#ifdef DEBUG_ALLOC
|
||
|
|
+ printf("libdwarfdetector add to static err list at %u\n",
|
||
|
|
+ i);
|
||
|
|
+ fflush(stdout);
|
||
|
|
+#endif /* DEBUG_ALLOC */
|
||
|
|
staticerrlist[i] = error;
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
@@ -239,6 +252,38 @@ _dwarf_add_to_static_err_list(Dwarf_Error error)
|
||
|
|
++static_used;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
+/* See libdwarf vulnerability DW202402-002
|
||
|
|
+ for the motivation.
|
||
|
|
+*/
|
||
|
|
+static void
|
||
|
|
+_dwarf_remove_from_staticerrlist(Dwarf_Ptr *space)
|
||
|
|
+{
|
||
|
|
+ unsigned i = 0;
|
||
|
|
+ if (!space) {
|
||
|
|
+ return;
|
||
|
|
+ }
|
||
|
|
+#ifdef DEBUG_ALLOC
|
||
|
|
+ printf("\nlibdwarfdetector remove from static err list "
|
||
|
|
+ " 0x%lx\n",(unsigned long)(uintptr_t)space);
|
||
|
|
+ fflush(stdout);
|
||
|
|
+#endif /* DEBUG_ALLOC */
|
||
|
|
+ for ( ; i <static_used; ++i) {
|
||
|
|
+ Dwarf_Error e = staticerrlist[i];
|
||
|
|
+ if (!e) {
|
||
|
|
+ continue;
|
||
|
|
+ }
|
||
|
|
+ if ((void *)e == space) {
|
||
|
|
+#ifdef DEBUG_ALLOC
|
||
|
|
+ printf("libdwarfdetector rm from static err list at %u\n",
|
||
|
|
+ i);
|
||
|
|
+ fflush(stdout);
|
||
|
|
+#endif /* DEBUG_ALLOC */
|
||
|
|
+ staticerrlist[i] = 0;
|
||
|
|
+ return;
|
||
|
|
+ }
|
||
|
|
+ }
|
||
|
|
+}
|
||
|
|
+
|
||
|
|
/* This will free everything in the staticerrlist,
|
||
|
|
but that is ok */
|
||
|
|
void
|
||
|
|
@@ -671,7 +716,7 @@ _dwarf_get_alloc(Dwarf_Debug dbg,
|
||
|
|
}
|
||
|
|
}
|
||
|
|
#if DEBUG_ALLOC
|
||
|
|
- printf("libdwarfdetector ALLOC ret 0x%lx type 0x%x "
|
||
|
|
+ printf("\nlibdwarfdetector ALLOC ret 0x%lx type 0x%x "
|
||
|
|
"size %lu line %d %s\n",
|
||
|
|
(unsigned long)ret_mem,(unsigned)alloc_type,
|
||
|
|
(unsigned long)size,__LINE__,__FILE__);
|
||
|
|
@@ -804,6 +849,9 @@ dwarf_dealloc(Dwarf_Debug dbg,
|
||
|
|
unsigned int type = 0;
|
||
|
|
char * malloc_addr = 0;
|
||
|
|
struct reserve_data_s * r = 0;
|
||
|
|
+#if 0
|
||
|
|
+ Dwarf_Bool check_errmsg_list = FALSE;
|
||
|
|
+#endif
|
||
|
|
|
||
|
|
if (!space) {
|
||
|
|
#ifdef DEBUG_ALLOC
|
||
|
|
@@ -921,11 +969,15 @@ dwarf_dealloc(Dwarf_Debug dbg,
|
||
|
|
if (ep->er_static_alloc == DE_MALLOC) {
|
||
|
|
/* This is special, we had no arena
|
||
|
|
but have a full special area as normal. */
|
||
|
|
+#if 0
|
||
|
|
+ check_errmsg_list = TRUE;
|
||
|
|
+#endif
|
||
|
|
#ifdef DEBUG_ALLOC
|
||
|
|
printf("DEALLOC does free, DE_MALLOC line %d %s\n",
|
||
|
|
__LINE__,__FILE__);
|
||
|
|
fflush(stdout);
|
||
|
|
#endif /* DEBUG_ALLOC*/
|
||
|
|
+ _dwarf_remove_from_staticerrlist(space);
|
||
|
|
}
|
||
|
|
/* Was normal alloc, use normal dealloc. */
|
||
|
|
/* DW_DLA_ERROR has a specialdestructor */
|
||
|
|
diff --git a/src/lib/libdwarf/dwarf_error.c b/src/lib/libdwarf/dwarf_error.c
|
||
|
|
index e49706693..73f60f2b3 100644
|
||
|
|
--- a/src/lib/libdwarf/dwarf_error.c
|
||
|
|
+++ b/src/lib/libdwarf/dwarf_error.c
|
||
|
|
@@ -140,7 +140,8 @@ _dwarf_error_string(Dwarf_Debug dbg, Dwarf_Error * error,
|
||
|
|
errptr = &_dwarf_failsafe_error;
|
||
|
|
errptr->er_static_alloc = DE_STATIC;
|
||
|
|
#ifdef DEBUG
|
||
|
|
- printf("libdwarf no dbg, fullystatic, "
|
||
|
|
+ printf("libdwarf no dbg to dwarf_error_string,"
|
||
|
|
+ " fullystatic, "
|
||
|
|
"using DE_STATIC alloc, addr"
|
||
|
|
" 0x%lx line %d %s\n",
|
||
|
|
(unsigned long)errptr,
|
||
|
|
@@ -150,7 +151,7 @@ _dwarf_error_string(Dwarf_Debug dbg, Dwarf_Error * error,
|
||
|
|
errptr->er_static_alloc = DE_MALLOC;
|
||
|
|
|
||
|
|
#ifdef DEBUG
|
||
|
|
- printf("libdwarf no dbg,leaks, "
|
||
|
|
+ printf("libdwarf no dbg, add to static_err_list "
|
||
|
|
"static DE_MALLOC alloc, addr"
|
||
|
|
" 0x%lx line %d %s\n",
|
||
|
|
(unsigned long)errptr,
|