From f1d984df1d5442db50064e3f9a9a583075ff6f04 Mon Sep 17 00:00:00 2001 From: Matt Wozniski Date: Thu, 27 Jun 2024 17:44:38 -0400 Subject: [PATCH] Avoid stack overflow in native symbolification If looking up debug info by build id returns a file with MiniDebugInfo (the `.gnu_debugdata` section), libbacktrace will infinitely recurse, leading to a stack overflow unless the limit on the maximum number of open file descriptors is reached before the stack can overflow. Work around this by ignoring the MiniDebugInfo if we've already successfully loaded the debug info by its build id. Signed-off-by: Matt Wozniski --- news/639.bugfix.rst | 1 + src/vendor/libbacktrace/elf.c | 3 ++- ...1ca0bd44170ff8352d4c514_debuginfod_patch.diff | 16 +++++++++++++--- 3 files changed, 16 insertions(+), 4 deletions(-) create mode 100644 news/639.bugfix.rst diff --git a/news/639.bugfix.rst b/news/639.bugfix.rst new file mode 100644 index 0000000000..0738f06766 --- /dev/null +++ b/news/639.bugfix.rst @@ -0,0 +1 @@ +Fix a bug that could in rare circumstances result in a stack overflow while processing native mode stacks. diff --git a/src/vendor/libbacktrace/elf.c b/src/vendor/libbacktrace/elf.c index 3d2b75f629..e62668b073 100644 --- a/src/vendor/libbacktrace/elf.c +++ b/src/vendor/libbacktrace/elf.c @@ -6876,7 +6876,8 @@ elf_add (struct backtrace_state *state, const char *filename, int descriptor, } } - if (!gnu_debugdata_view_valid + if (!debuginfo + && !gnu_debugdata_view_valid && strcmp (name, ".gnu_debugdata") == 0) { if (!elf_get_view (state, descriptor, memory, memory_size, diff --git a/src/vendor/libbacktrace_4ead348bb45f753121ca0bd44170ff8352d4c514_debuginfod_patch.diff b/src/vendor/libbacktrace_4ead348bb45f753121ca0bd44170ff8352d4c514_debuginfod_patch.diff index 10bb492fd1..1860f92de3 100644 --- a/src/vendor/libbacktrace_4ead348bb45f753121ca0bd44170ff8352d4c514_debuginfod_patch.diff +++ b/src/vendor/libbacktrace_4ead348bb45f753121ca0bd44170ff8352d4c514_debuginfod_patch.diff @@ -180,7 +180,7 @@ index 0000000..78f4d8d + +#endif /* _DEBUGINFOD_CLIENT_H */ diff --git a/elf.c b/elf.c -index 107e26c..3d2b75f 100644 +index 107e26c..e62668b 100644 --- a/elf.c +++ b/elf.c @@ -38,6 +38,7 @@ POSSIBILITY OF SUCH DAMAGE. */ @@ -239,7 +239,17 @@ index 107e26c..3d2b75f 100644 /* Open a separate debug info file, using the build ID to find it. Returns an open file descriptor, or -1. -@@ -6946,6 +6981,14 @@ elf_add (struct backtrace_state *state, const char *filename, int descriptor, +@@ -6841,7 +6876,8 @@ elf_add (struct backtrace_state *state, const char *filename, int descriptor, + } + } + +- if (!gnu_debugdata_view_valid ++ if (!debuginfo ++ && !gnu_debugdata_view_valid + && strcmp (name, ".gnu_debugdata") == 0) + { + if (!elf_get_view (state, descriptor, memory, memory_size, +@@ -6946,6 +6982,14 @@ elf_add (struct backtrace_state *state, const char *filename, int descriptor, d = elf_open_debugfile_by_buildid (state, buildid_data, buildid_size, error_callback, data); @@ -254,7 +264,7 @@ index 107e26c..3d2b75f 100644 if (d >= 0) { int ret; -@@ -7421,7 +7464,28 @@ backtrace_initialize (struct backtrace_state *state, const char *filename, +@@ -7421,7 +7465,28 @@ backtrace_initialize (struct backtrace_state *state, const char *filename, pd.exe_filename = filename; pd.exe_descriptor = ret < 0 ? descriptor : -1;