From 576d4b8a5ea643ad2ac8f9ed2753488b249896f3 Mon Sep 17 00:00:00 2001 From: pelijah Date: Tue, 26 Mar 2024 17:11:08 +0300 Subject: [PATCH] Fix several memleaks in DWARF related code (#4391) --- librz/arch/dwarf_process.c | 3 +++ librz/bin/dwarf/dwarf.c | 1 + librz/bin/dwarf/line.c | 20 ++++++++------------ test/integration/test_dwarf.c | 7 +++++++ 4 files changed, 19 insertions(+), 12 deletions(-) diff --git a/librz/arch/dwarf_process.c b/librz/arch/dwarf_process.c index 40f389bc21..f31cffdc9b 100644 --- a/librz/arch/dwarf_process.c +++ b/librz/arch/dwarf_process.c @@ -1672,13 +1672,16 @@ static bool variable_from_die( RZ_BORROW RZ_IN RZ_NONNULL const RzBinDwarfDie *die) { RzAnalysisDwarfVariable v = { 0 }; if (!function_var_parse(ctx, NULL, NULL, &v, die, NULL)) { + variable_fini(&v); return false; } if (!(v.type && v.location->kind == RzBinDwarfLocationKind_ADDRESS)) { + variable_fini(&v); return false; } if (variable_exist_global(ctx->analysis, &v)) { + variable_fini(&v); return false; } diff --git a/librz/bin/dwarf/dwarf.c b/librz/bin/dwarf/dwarf.c index 09c8eae32a..60811dfd2a 100644 --- a/librz/bin/dwarf/dwarf.c +++ b/librz/bin/dwarf/dwarf.c @@ -331,6 +331,7 @@ RZ_API void rz_bin_dwarf_free(RZ_OWN RZ_NULLABLE RzBinDWARF *dw) { RngLists_free(dw->rnglists); rz_bin_dwarf_addr_free(dw->addr); rz_bin_dwarf_str_free(dw->str); + rz_bin_dwarf_line_str_free(dw->line_str); rz_bin_dwarf_str_offsets_free(dw->str_offsets); rz_bin_dwarf_abbrev_free(dw->abbrev); diff --git a/librz/bin/dwarf/line.c b/librz/bin/dwarf/line.c index f516b45c49..d83c313c61 100644 --- a/librz/bin/dwarf/line.c +++ b/librz/bin/dwarf/line.c @@ -106,12 +106,9 @@ static const char *directory_parse_v5(DWLineContext *ctx, RzBinDwarfLineUnitHdr return path_name; } -static RzBinDwarfFileEntry *FileEntry_parse_v5( - DWLineContext *ctx) { +static bool FileEntry_parse_v5(DWLineContext *ctx, RzBinDwarfFileEntry *entry) { RzBinEndianReader *R = ctx->line->R; RzBinDwarfLineUnitHdr *hdr = ctx->hdr; - RzBinDwarfFileEntry *entry = RZ_NEW0(RzBinDwarfFileEntry); - RET_FALSE_IF_FAIL(entry); RzBinDwarfFileEntryFormat *format = NULL; rz_vector_foreach(&hdr->file_name_entry_formats, format) { RzBinDwarfAttr attr = { 0 }; @@ -119,7 +116,9 @@ static RzBinDwarfFileEntry *FileEntry_parse_v5( .form = format->form, .encoding = &hdr->encoding, }; - ERR_IF_FAIL(RzBinDwarfAttr_parse(R, &attr, &opt)); + if (!RzBinDwarfAttr_parse(R, &attr, &opt)) { + return false; + } switch (format->content_type) { case DW_LNCT_path: entry->path_name = rz_bin_dwarf_attr_string(&attr, ctx->dw, UT64_MAX); @@ -143,10 +142,7 @@ static RzBinDwarfFileEntry *FileEntry_parse_v5( } } - return entry; -err: - free(entry); - return NULL; + return true; } static bool FileEntry_parse_v4(RzBinEndianReader *R, RzBinDwarfFileEntry *entry) { @@ -181,11 +177,11 @@ static bool LineHdr_parse_v5(DWLineContext *ctx) { RET_FALSE_IF_FAIL(FileEntryFormat_parse(R, &hdr->file_name_entry_formats, hdr)); ULE128_OR_RET_FALSE(count); for (ut64 i = 0; i < count; ++i) { - RzBinDwarfFileEntry *entry = FileEntry_parse_v5(ctx); - if (!entry) { + RzBinDwarfFileEntry entry = { 0 }; + if (!FileEntry_parse_v5(ctx, &entry)) { break; } - rz_vector_push(&hdr->file_names, entry); + rz_vector_push(&hdr->file_names, &entry); } return true; } diff --git a/test/integration/test_dwarf.c b/test/integration/test_dwarf.c index 2b1765a2b0..21aa4e4da9 100644 --- a/test/integration/test_dwarf.c +++ b/test/integration/test_dwarf.c @@ -788,6 +788,7 @@ bool test_dwarf4_multidir_comp_units(void) { }; assert_line_samples_eq(li->lines, RZ_ARRAY_SIZE(test_line_samples), test_line_samples); + rz_bin_dwarf_abbrev_free(da); rz_bin_dwarf_free(dw); rz_bin_free(bin); rz_io_free(io); @@ -1379,6 +1380,7 @@ bool test_dwarf5_loclists(void) { mu_assert_notnull(loc, "location"); mu_assert_eq(loc->kind, RzBinDwarfLocationKind_REGISTER, "piece kind"); mu_assert_eq(loc->register_number, 0, "piece reg"); + rz_bin_dwarf_location_free(loc); } { @@ -1392,6 +1394,7 @@ bool test_dwarf5_loclists(void) { mu_assert_eq(loc->kind, RzBinDwarfLocationKind_REGISTER_OFFSET, "piece kind"); mu_assert_eq(loc->register_number, 2, "piece reg"); mu_assert_eq(loc->offset, -4, "piece reg"); + rz_bin_dwarf_location_free(loc); } { @@ -1404,6 +1407,7 @@ bool test_dwarf5_loclists(void) { mu_assert_notnull(loc, "location"); mu_assert_eq(loc->kind, RzBinDwarfLocationKind_EVALUATION_WAITING, "piece kind"); mu_assert("eval waiting", loc->eval_waiting.eval && loc->eval_waiting.result); + rz_bin_dwarf_location_free(loc); } rz_bin_dwarf_free(dw); @@ -1442,6 +1446,7 @@ bool test_dwarf4_loclists(void) { mu_assert_eq(loc->kind, RzBinDwarfLocationKind_REGISTER_OFFSET, "piece kind"); mu_assert_eq(loc->register_number, 4, "piece reg"); mu_assert_eq(loc->offset, 4, "piece reg offset"); + rz_bin_dwarf_location_free(loc); } { @@ -1454,6 +1459,7 @@ bool test_dwarf4_loclists(void) { mu_assert_notnull(loc, "location"); mu_assert_eq(loc->kind, RzBinDwarfLocationKind_REGISTER, "piece kind"); mu_assert_eq(loc->register_number, 1, "piece reg"); + rz_bin_dwarf_location_free(loc); } { @@ -1466,6 +1472,7 @@ bool test_dwarf4_loclists(void) { mu_assert_notnull(loc, "location"); mu_assert_eq(loc->kind, RzBinDwarfLocationKind_EVALUATION_WAITING, "piece kind"); mu_assert("eval waiting", loc->eval_waiting.eval && loc->eval_waiting.result); + rz_bin_dwarf_location_free(loc); } rz_bin_dwarf_free(dw);