From: Aaron Merey Date: Tue, 24 Feb 2026 21:08:07 +0000 (-0500) Subject: dwarf_begin_elf.c: Fix lock resource leak X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=f07268c53598130c416b97644d8fec128ee4e208;p=thirdparty%2Felfutils.git dwarf_begin_elf.c: Fix lock resource leak dwarf_begin_elf might free memory for a struct Dwarf after its rwlock and mutex fields have been initialized without calling the corresponding destroy functions to release the lock resources. Fix this by moving lock inits to the end of the valid_p function, after the struct Dwarf being intialized has passed all error checking. Signed-off-by: Aaron Merey --- diff --git a/libdw/dwarf_begin_elf.c b/libdw/dwarf_begin_elf.c index f5cabde0..dd30f79b 100644 --- a/libdw/dwarf_begin_elf.c +++ b/libdw/dwarf_begin_elf.c @@ -358,12 +358,6 @@ valid_p (Dwarf *result) result->fake_loc_cu->offset_size = 4; 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->split_lock); - mutex_init (result->fake_loc_cu->abbrev_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); } } @@ -391,12 +385,6 @@ valid_p (Dwarf *result) result->fake_loclists_cu->offset_size = 4; 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->split_lock); - mutex_init (result->fake_loclists_cu->abbrev_lock); - mutex_init (result->fake_loclists_cu->src_lock); - mutex_init (result->fake_loclists_cu->str_off_base_lock); - mutex_init (result->fake_loclists_cu->intern_lock); } } @@ -429,19 +417,62 @@ valid_p (Dwarf *result) result->fake_addr_cu->offset_size = 4; result->fake_addr_cu->version = 5; result->fake_addr_cu->split = NULL; - eu_search_tree_init (&result->fake_addr_cu->locs_tree); - rwlock_init (result->fake_addr_cu->split_lock); - mutex_init (result->fake_addr_cu->abbrev_lock); - mutex_init (result->fake_addr_cu->src_lock); - mutex_init (result->fake_addr_cu->str_off_base_lock); - mutex_init (result->fake_addr_cu->intern_lock); } } if (result != NULL) { + if (pthread_rwlock_init(&result->mem_rwl, NULL) != 0) + { + free (result->fake_loc_cu); + free (result->fake_loclists_cu); + free (result->fake_addr_cu); + free (result); + __libdw_seterrno (DWARF_E_NOMEM); /* no memory. */ + return NULL; + } + result->elfpath = __libdw_elfpath (result->elf->fildes); __libdw_set_debugdir(result); + + /* Initialize locks and search_trees. */ + mutex_init (result->dwarf_lock); + mutex_init (result->macro_lock); + eu_search_tree_init (&result->cu_tree); + eu_search_tree_init (&result->tu_tree); + eu_search_tree_init (&result->split_tree); + eu_search_tree_init (&result->macro_ops_tree); + eu_search_tree_init (&result->files_lines_tree); + + if (result->fake_loc_cu != NULL) + { + eu_search_tree_init (&result->fake_loc_cu->locs_tree); + rwlock_init (result->fake_loc_cu->split_lock); + mutex_init (result->fake_loc_cu->abbrev_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); + } + + if (result->fake_loclists_cu != NULL) + { + eu_search_tree_init (&result->fake_loclists_cu->locs_tree); + rwlock_init (result->fake_loclists_cu->split_lock); + mutex_init (result->fake_loclists_cu->abbrev_lock); + mutex_init (result->fake_loclists_cu->src_lock); + mutex_init (result->fake_loclists_cu->str_off_base_lock); + mutex_init (result->fake_loclists_cu->intern_lock); + } + + if (result->fake_addr_cu != NULL) + { + eu_search_tree_init (&result->fake_addr_cu->locs_tree); + rwlock_init (result->fake_addr_cu->split_lock); + mutex_init (result->fake_addr_cu->abbrev_lock); + mutex_init (result->fake_addr_cu->src_lock); + mutex_init (result->fake_addr_cu->str_off_base_lock); + mutex_init (result->fake_addr_cu->intern_lock); + } } return result; @@ -588,19 +619,6 @@ dwarf_begin_elf (Elf *elf, Dwarf_Cmd cmd, Elf_Scn *scngrp) actual allocation. */ result->mem_default_size = mem_default_size; result->oom_handler = __libdw_oom; - if (pthread_rwlock_init(&result->mem_rwl, NULL) != 0) - { - free (result); - __libdw_seterrno (DWARF_E_NOMEM); /* no memory. */ - return NULL; - } - mutex_init (result->dwarf_lock); - mutex_init (result->macro_lock); - eu_search_tree_init (&result->cu_tree); - eu_search_tree_init (&result->tu_tree); - eu_search_tree_init (&result->split_tree); - eu_search_tree_init (&result->macro_ops_tree); - eu_search_tree_init (&result->files_lines_tree); result->mem_stacks = 0; result->mem_tails = NULL;