Re: [PATCH] libdw: Fix eu_search_tree TOCTOU bugs
Hi Aaron, On Tue, 2025-04-15 at 17:04 -0400, Aaron Merey wrote: > eu_tfind is used to facilitate lazy loading throughout libdw. > If a result is not found via eu_tfind, work is done to load > the result and cache it in an eu_search_tree. > > Some calls to eu_tfind allow for TOCTOU bugs. Multiple threads > might race to call eu_tfind on some result that hasn't yet been > cached. Multiple threads may then attempt to load the result > which may cause an unnecessary amount of memory may be allocated. > Additionally this memory may not get released when the associated > libdw data structure is freed. > > Fix this by adding additional locking to ensure that only one > thread performs lazy loading. > > One approach used in this patch is to preserve calls to eu_tfind > without additional locking, but when the result isn't found then > a lock is then used to synchronize access to the lazy loading code. > An extra eu_tfind call has been added at the start of these critical > section to synchronize verification that lazy loading should proceed. > > Another approach used is to simply synchronize entire calls to > functions where lazy loading via eu_tfind might occur (__libdw_find_fde > and __libdw_intern_expression). > > libdw/ > * cfi.h (struct Dwarf_CFI_s): Declare new mutex. > * dwarf_begin_elf.c (valid_p): Initialize all locks for fake CUs. > * dwarf_cfi_addrframe.c (dwarf_cfi_addrframe): Place lock around > __libdw_find_fde. > * dwarf_end.c (cu_free): Deallocate all locks unconditionally, > whether or not the CU is fake. > * dwarf_frame_cfa.c (dwarf_frame_cfa): Place lock around > __libdw_intern_expression. > * dwarf_frame_register.c (dwarf_frame_register): Ditto. > * dwarf_getcfi.c (dwarf_getcfi): Initialize cfi lock. > * dwarf_getlocation.c (is_constant_offset): Synchronize access > to lazy loading section. > (getlocation): Place lock around __libdw_intern_expression. > * dwarf_getmacros.c (cache_op_table): Synchronize access to lazy > loading section. > * frame-cache.c (__libdw_destroy_frame_cache): Free Dwarf_CFI > mutex. > * libdwP.h (struct Dwarf): Update macro_lock comment. > (struct Dwarf_CU): Declare new mutex. > libdw_findcu.c (__libdw_intern_next_unit): Initialize > intern_lock. > (__libdw_findcu): Adjust locking so that the first eu_tfind > can be done without extra lock overhead. > > Signed-off-by: Aaron Merey > --- > libdw/cfi.h | 4 +++ > libdw/dwarf_begin_elf.c | 15 + > libdw/dwarf_cfi_addrframe.c | 3 ++ > libdw/dwarf_end.c| 10 +++--- > libdw/dwarf_frame_cfa.c | 2 ++ > libdw/dwarf_frame_register.c | 16 + > libdw/dwarf_getcfi.c | 1 + > libdw/dwarf_getlocation.c| 63 ++-- > libdw/dwarf_getmacros.c | 16 - > libdw/frame-cache.c | 1 + > libdw/libdwP.h | 6 +++- > libdw/libdw_findcu.c | 9 -- > 12 files changed, 108 insertions(+), 38 deletions(-) > > diff --git a/libdw/cfi.h b/libdw/cfi.h > index d0134243..48e42a41 100644 > --- a/libdw/cfi.h > +++ b/libdw/cfi.h > @@ -98,6 +98,10 @@ struct Dwarf_CFI_s >/* Search tree for parsed DWARF expressions, indexed by raw pointer. */ >search_tree expr_tree; > > + /* Should be held when calling __libdw_find_fde and when > __libdw_intern_expression > + is called with Dwarf_CFI members. */ > + mutex_define(, lock); > + >/* Backend hook. */ >struct ebl *ebl; > OK, used in dwarf_cfi_addrframe, dwarf_frame_cfa, dwarf_frame_register. I needed to double check the use of __libdw_intern_expression in libdw/dwarf_getlocation.c (getlocation) though. That one is also properly "locked", but using the cu intern_lock instead. Which makes sense. But maybe we can document that somewhere? > diff --git a/libdw/dwarf_begin_elf.c b/libdw/dwarf_begin_elf.c > index 58a309e9..63e2805d 100644 > --- a/libdw/dwarf_begin_elf.c > +++ b/libdw/dwarf_begin_elf.c > @@ -359,6 +359,11 @@ valid_p (Dwarf *result) > result->fake_loc_cu->version = 4; > result->fake_loc_cu->split = NULL; > eu_search_tree_init (&result->fake_loc_cu->locs_tree); > + rwlock_init (result->fake_loc_cu->abbrev_lock); > + rwlock_init (result->fake_loc_cu->split_lock); > + mutex_init (result->fake_loc_cu->src_lock); > + mutex_init (result->fake_loc_cu->str_off_base_lock); > + mutex_init (result->fake_loc_cu->intern_lock); > } > } > > @@ -387,6 +392,11 @@ valid_p (Dwarf *result) > result->fake_loclists_cu->version = 5; > result->fake_loclists_cu->split = NULL; > eu_search_tree_init (&result->fake_loclists_cu->locs_tree); > + rwlock_init (result->fake_loclists_cu->abbrev_lock); > + rwlock_init (result->fake_loclists_cu->split_lock); > + mutex_init (result->fake_loclists_cu->src_lock); >
[Bug general/32930] compile failure in i386_init.c asm/perf_regs.h: No such file or directory
https://sourceware.org/bugzilla/show_bug.cgi?id=32930 Serhei Makarov changed: What|Removed |Added CC||serhei at serhei dot io --- Comment #2 from Serhei Makarov --- Should be fixable like this: diff --git a/backends/libebl_PERF_FLAGS.h b/backends/libebl_PERF_FLAGS.h index 2ed45f0f..73bf2d45 100644 --- a/backends/libebl_PERF_FLAGS.h +++ b/backends/libebl_PERF_FLAGS.h @@ -32,8 +32,12 @@ #define _LIBEBL_PERF_FLAGS_H 1 #if defined(__linux__) +/* XXX Need to exclude __linux__ arches without perf_regs.h. */ +#if defined(_ASM_X86_PERF_REGS_H) +/* || defined(other_architecture)... */ # include #endif +#endif #if defined(_ASM_X86_PERF_REGS_H) /* See the code in x86_initreg_sample.c for list of required regs and Going to check if any other places include a perf header without guarding by architecture and submit a full patch. -- You are receiving this mail because: You are on the CC list for the bug.
[Bug libdw/32929] 0.193 regression: dwarf_srclang_check: error while loading shared libraries: libelf.so.1: cannot open shared object file: No such file or directory
https://sourceware.org/bugzilla/show_bug.cgi?id=32929 --- Comment #2 from Sergei Trofimovich --- Yes, the change fixes the test failure and all tests pass now locally. Thank you! -- You are receiving this mail because: You are on the CC list for the bug.
[Bug general/32930] New: compile failure in i386_init.c asm/perf_regs.h: No such file or directory
https://sourceware.org/bugzilla/show_bug.cgi?id=32930 Bug ID: 32930 Summary: compile failure in i386_init.c asm/perf_regs.h: No such file or directory Product: elfutils Version: unspecified Status: NEW Severity: normal Priority: P2 Component: general Assignee: unassigned at sourceware dot org Reporter: mark at klomp dot org CC: elfutils-devel at sourceware dot org Target Milestone: --- elfutils 0.193 fails to build on debian hppa and m68k https://buildd.debian.org/status/fetch.php?pkg=elfutils&arch=hppa&ver=0.193-1&stamp=1746190911&raw=0 https://buildd.debian.org/status/fetch.php?pkg=elfutils&arch=m68k&ver=0.193-1&stamp=1746194309&raw=0 In file included from i386_init.c:37: libebl_PERF_FLAGS.h:35:11: fatal error: asm/perf_regs.h: No such file or directory 35 | # include | ^ -- You are receiving this mail because: You are on the CC list for the bug.
[Bug libdw/32929] New: 0.193 regression: dwarf_srclang_check: error while loading shared libraries: libelf.so.1: cannot open shared object file: No such file or directory
https://sourceware.org/bugzilla/show_bug.cgi?id=32929 Bug ID: 32929 Summary: 0.193 regression: dwarf_srclang_check: error while loading shared libraries: libelf.so.1: cannot open shared object file: No such file or directory Product: elfutils Version: unspecified Status: UNCONFIRMED Severity: normal Priority: P2 Component: libdw Assignee: unassigned at sourceware dot org Reporter: slyich at gmail dot com CC: elfutils-devel at sourceware dot org Target Milestone: --- When attempted to package new elfutils-0.193 I got one new test failure on the system without elfutils installed yet as: make check-TESTS FAIL: dwarf_srclang_check == elfutils 0.193: libdw/test-suite.log == # TOTAL: 1 # PASS: 0 # SKIP: 0 # XFAIL: 0 # FAIL: 1 # XPASS: 0 # ERROR: 0 System information (uname -a): Linux 6.14.4 #1-NixOS SMP PREEMPT_DYNAMIC Fri Apr 25 08:51:21 UTC 2025 x86_64 .. contents:: :depth: 2 FAIL: dwarf_srclang_check = ./dwarf_srclang_check: error while loading shared libraries: libelf.so.1: cannot open shared object file: No such file or directory FAIL dwarf_srclang_check (exit status: 127) Should dwarf_srclang_check add an RPATH to the locally built library? Bisect points at: commit 4d50c9e68808cbdd22dd70c26482ec010aefcbbf Author: Mark Wielaard Date: Wed Apr 2 13:35:31 2025 +0200 libdw: Add Nim language and dwarf_srclang tests -- You are receiving this mail because: You are on the CC list for the bug.
[Bug libdw/32929] 0.193 regression: dwarf_srclang_check: error while loading shared libraries: libelf.so.1: cannot open shared object file: No such file or directory
https://sourceware.org/bugzilla/show_bug.cgi?id=32929 Mark Wielaard changed: What|Removed |Added CC||mark at klomp dot org --- Comment #1 from Mark Wielaard --- That is interesting. The test is linked against the system libelf. But it really should be linked against the just build libelf. I assume nobody else saw this because libelf is always installed. But you see this because in your (NixOS) environment you have a totally clean "buildroot". I think you are right, for these test binaries we'll need to add an RPATH. Does the following work for you? diff --git a/libdw/Makefile.am b/libdw/Makefile.am index f024d6524095..298b0c65b972 100644 --- a/libdw/Makefile.am +++ b/libdw/Makefile.am @@ -168,7 +168,8 @@ MAINTAINERCLEANFILES = $(srcdir)/known-dwarf.h check_PROGRAMS = dwarf_srclang_check TESTS = $(check_PROGRAMS) -CHECK_DEF_FLAGS = $(DEFS) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -DMAIN_CHECK=1 +CHECK_DEF_FLAGS = $(DEFS) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) \ + -Wl,-rpath,../libelf -DMAIN_CHECK=1 .SECONDEXPANSION: dwarf_srclang_check$(EXEEXT): $$(filter-out $$(subst _check,,$$@).o,$(libdw_a_OBJECTS)) $$(subst _check,,$$@).c -- You are receiving this mail because: You are on the CC list for the bug.
[Bug general/32930] compile failure in i386_init.c asm/perf_regs.h: No such file or directory
https://sourceware.org/bugzilla/show_bug.cgi?id=32930 Sam James changed: What|Removed |Added CC||matoro_bugzilla_glibc@mator ||o.tk, sam at gentoo dot org See Also||https://bugs.gentoo.org/sho ||w_bug.cgi?id=955065 -- You are receiving this mail because: You are on the CC list for the bug.
[Bug general/32930] compile failure in i386_init.c asm/perf_regs.h: No such file or directory
https://sourceware.org/bugzilla/show_bug.cgi?id=32930 --- Comment #1 from Sam James --- Ditto alpha: https://bugs.gentoo.org/955065. -- You are receiving this mail because: You are on the CC list for the bug.
[COMMITTED] libdw: Add RPATH to MAIN_CHECK programs
We want to test the program against the just build libelf.so not the system installed one. So add an RPATH to ../libelf. * libdw/Makefile.am (CHECK_DEF_FLAGS): Add -Wl,-rpath,../libelf. https://sourceware.org/bugzilla/show_bug.cgi?id=32929 Signed-off-by: Mark Wielaard --- libdw/Makefile.am | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libdw/Makefile.am b/libdw/Makefile.am index f024d6524095..229fec62671b 100644 --- a/libdw/Makefile.am +++ b/libdw/Makefile.am @@ -168,7 +168,8 @@ MAINTAINERCLEANFILES = $(srcdir)/known-dwarf.h check_PROGRAMS = dwarf_srclang_check TESTS = $(check_PROGRAMS) -CHECK_DEF_FLAGS = $(DEFS) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -DMAIN_CHECK=1 +CHECK_DEF_FLAGS = $(DEFS) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) \ + -Wl,-rpath,../libelf -DMAIN_CHECK=1 .SECONDEXPANSION: dwarf_srclang_check$(EXEEXT): $$(filter-out $$(subst _check,,$$@).o,$(libdw_a_OBJECTS)) $$(subst _check,,$$@).c -- 2.49.0
[Bug libdw/32929] 0.193 regression: dwarf_srclang_check: error while loading shared libraries: libelf.so.1: cannot open shared object file: No such file or directory
https://sourceware.org/bugzilla/show_bug.cgi?id=32929 Mark Wielaard changed: What|Removed |Added Status|UNCONFIRMED |RESOLVED Resolution|--- |FIXED --- Comment #3 from Mark Wielaard --- commit c96c4fcd54c64678dbcf9e43b9a991362aa83106 Author: Mark Wielaard Date: Sat May 3 02:46:40 2025 +0200 libdw: Add RPATH to MAIN_CHECK programs We want to test the program against the just build libelf.so not the system installed one. So add an RPATH to ../libelf. * libdw/Makefile.am (CHECK_DEF_FLAGS): Add -Wl,-rpath,../libelf. https://sourceware.org/bugzilla/show_bug.cgi?id=32929 Signed-off-by: Mark Wielaard -- You are receiving this mail because: You are on the CC list for the bug.