diff options
author | Mark Wielaard <mark@klomp.org> | 2021-12-21 00:55:27 +0100 |
---|---|---|
committer | Mark Wielaard <mark@klomp.org> | 2021-12-21 11:41:01 +0100 |
commit | 4fdd85881c8acd06db737c45ea6aabc60aef3d4d (patch) | |
tree | ac6334831bc8acb641a56f6ad80f8daf15126313 /libdwfl | |
parent | libdwfl: Handle unaligned Nhdr in dwfl_segment_report_module (diff) | |
download | elfutils-4fdd85881c8acd06db737c45ea6aabc60aef3d4d.tar.gz elfutils-4fdd85881c8acd06db737c45ea6aabc60aef3d4d.tar.bz2 elfutils-4fdd85881c8acd06db737c45ea6aabc60aef3d4d.tar.xz |
libdwfl: Always clean up build_id.memory
There was a small memory leak if an error was detected in some places
in dwfl_segment_report_module after the build_id.memory was alredy
allocated. Fix this by moving initialization of struct elf_build_id
early and always free the memory, if not NULL, at exit.
https://sourceware.org/bugzilla/show_bug.cgi?id=28685
Signed-off-by: Mark Wielaard <mark@klomp.org>
Diffstat (limited to 'libdwfl')
-rw-r--r-- | libdwfl/ChangeLog | 6 | ||||
-rw-r--r-- | libdwfl/dwfl_segment_report_module.c | 26 |
2 files changed, 18 insertions, 14 deletions
diff --git a/libdwfl/ChangeLog b/libdwfl/ChangeLog index 6015f6b7..abd5c34a 100644 --- a/libdwfl/ChangeLog +++ b/libdwfl/ChangeLog | |||
@@ -1,3 +1,9 @@ | |||
1 | 2021-12-20 Mark Wielaard <mark@klomp.org> | ||
2 | |||
3 | * dwfl_segment_report_module.c (dwfl_segment_report_module): Move | ||
4 | and initialize struct elf_build_id build_id early. Only free memory | ||
5 | early when no longer needed. Free memory if not NULL at out. | ||
6 | |||
1 | 2021-12-19 Mark Wielaard <mark@klomp.org> | 7 | 2021-12-19 Mark Wielaard <mark@klomp.org> |
2 | 8 | ||
3 | * dwfl_segment_report_module.c (dwfl_segment_report_module): Copy | 9 | * dwfl_segment_report_module.c (dwfl_segment_report_module): Copy |
diff --git a/libdwfl/dwfl_segment_report_module.c b/libdwfl/dwfl_segment_report_module.c index 72c85070..5bef249e 100644 --- a/libdwfl/dwfl_segment_report_module.c +++ b/libdwfl/dwfl_segment_report_module.c | |||
@@ -1,5 +1,6 @@ | |||
1 | /* Sniff out modules from ELF headers visible in memory segments. | 1 | /* Sniff out modules from ELF headers visible in memory segments. |
2 | Copyright (C) 2008-2012, 2014, 2015, 2018 Red Hat, Inc. | 2 | Copyright (C) 2008-2012, 2014, 2015, 2018 Red Hat, Inc. |
3 | Copyright (C) 2021 Mark J. Wielaard <mark@klomp.org> | ||
3 | This file is part of elfutils. | 4 | This file is part of elfutils. |
4 | 5 | ||
5 | This file is free software; you can redistribute it and/or modify | 6 | This file is free software; you can redistribute it and/or modify |
@@ -332,6 +333,12 @@ dwfl_segment_report_module (Dwfl *dwfl, int ndx, const char *name, | |||
332 | here so we can always safely free it. */ | 333 | here so we can always safely free it. */ |
333 | void *phdrsp = NULL; | 334 | void *phdrsp = NULL; |
334 | 335 | ||
336 | /* Collect the build ID bits here. */ | ||
337 | struct elf_build_id build_id; | ||
338 | build_id.memory = NULL; | ||
339 | build_id.len = 0; | ||
340 | build_id.vaddr = 0; | ||
341 | |||
335 | if (! (*memory_callback) (dwfl, ndx, &buffer, &buffer_available, | 342 | if (! (*memory_callback) (dwfl, ndx, &buffer, &buffer_available, |
336 | start, sizeof (Elf64_Ehdr), memory_callback_arg) | 343 | start, sizeof (Elf64_Ehdr), memory_callback_arg) |
337 | || memcmp (buffer, ELFMAG, SELFMAG) != 0) | 344 | || memcmp (buffer, ELFMAG, SELFMAG) != 0) |
@@ -492,12 +499,6 @@ dwfl_segment_report_module (Dwfl *dwfl, int ndx, const char *name, | |||
492 | GElf_Addr dyn_vaddr = 0; | 499 | GElf_Addr dyn_vaddr = 0; |
493 | GElf_Xword dyn_filesz = 0; | 500 | GElf_Xword dyn_filesz = 0; |
494 | 501 | ||
495 | /* Collect the build ID bits here. */ | ||
496 | struct elf_build_id build_id; | ||
497 | build_id.memory = NULL; | ||
498 | build_id.len = 0; | ||
499 | build_id.vaddr =0; | ||
500 | |||
501 | Elf32_Phdr *p32 = phdrsp; | 502 | Elf32_Phdr *p32 = phdrsp; |
502 | Elf64_Phdr *p64 = phdrsp; | 503 | Elf64_Phdr *p64 = phdrsp; |
503 | if ((ei_class == ELFCLASS32 | 504 | if ((ei_class == ELFCLASS32 |
@@ -701,10 +702,7 @@ dwfl_segment_report_module (Dwfl *dwfl, int ndx, const char *name, | |||
701 | /* We must have seen the segment covering offset 0, or else the ELF | 702 | /* We must have seen the segment covering offset 0, or else the ELF |
702 | header we read at START was not produced by these program headers. */ | 703 | header we read at START was not produced by these program headers. */ |
703 | if (unlikely (!found_bias)) | 704 | if (unlikely (!found_bias)) |
704 | { | 705 | goto out; |
705 | free (build_id.memory); | ||
706 | goto out; | ||
707 | } | ||
708 | 706 | ||
709 | /* Now we know enough to report a module for sure: its bounds. */ | 707 | /* Now we know enough to report a module for sure: its bounds. */ |
710 | module_start += bias; | 708 | module_start += bias; |
@@ -772,10 +770,7 @@ dwfl_segment_report_module (Dwfl *dwfl, int ndx, const char *name, | |||
772 | } | 770 | } |
773 | } | 771 | } |
774 | if (skip_this_module) | 772 | if (skip_this_module) |
775 | { | 773 | goto out; |
776 | free (build_id.memory); | ||
777 | goto out; | ||
778 | } | ||
779 | } | 774 | } |
780 | 775 | ||
781 | const char *file_note_name = handle_file_note (module_start, module_end, | 776 | const char *file_note_name = handle_file_note (module_start, module_end, |
@@ -940,6 +935,7 @@ dwfl_segment_report_module (Dwfl *dwfl, int ndx, const char *name, | |||
940 | /* At this point we do not need BUILD_ID or NAME any more. | 935 | /* At this point we do not need BUILD_ID or NAME any more. |
941 | They have been copied. */ | 936 | They have been copied. */ |
942 | free (build_id.memory); | 937 | free (build_id.memory); |
938 | build_id.memory = NULL; | ||
943 | finish_portion (&read_state, &soname, &soname_size); | 939 | finish_portion (&read_state, &soname, &soname_size); |
944 | 940 | ||
945 | if (unlikely (mod == NULL)) | 941 | if (unlikely (mod == NULL)) |
@@ -1042,6 +1038,8 @@ dwfl_segment_report_module (Dwfl *dwfl, int ndx, const char *name, | |||
1042 | } | 1038 | } |
1043 | 1039 | ||
1044 | out: | 1040 | out: |
1041 | if (build_id.memory != NULL) | ||
1042 | free (build_id.memory); | ||
1045 | free (phdrsp); | 1043 | free (phdrsp); |
1046 | if (buffer != NULL) | 1044 | if (buffer != NULL) |
1047 | (*memory_callback) (dwfl, -1, &buffer, &buffer_available, 0, 0, | 1045 | (*memory_callback) (dwfl, -1, &buffer, &buffer_available, 0, 0, |