Re: [PATCH] libdw: Fix eu_search_tree TOCTOU bugs

2025-05-02 Thread Mark Wielaard
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

2025-05-02 Thread serhei at serhei dot io
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

2025-05-02 Thread slyich at gmail dot com
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

2025-05-02 Thread mark at klomp dot org
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

2025-05-02 Thread slyich at gmail dot com
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

2025-05-02 Thread mark at klomp dot org
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

2025-05-02 Thread sam at gentoo dot org
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

2025-05-02 Thread sam at gentoo dot org
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

2025-05-02 Thread Mark Wielaard
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

2025-05-02 Thread mark at klomp dot org
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.