forked from bminor/binutils-gdb
-
Notifications
You must be signed in to change notification settings - Fork 8
elf: Workaround for segment first section address check in phdr rewrite #12
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
stephanosio
merged 1 commit into
zephyr-binutils-2_38
from
elf_phdr_rewrite_lma_neq_vma
Jan 25, 2024
Merged
elf: Workaround for segment first section address check in phdr rewrite #12
stephanosio
merged 1 commit into
zephyr-binutils-2_38
from
elf_phdr_rewrite_lma_neq_vma
Jan 25, 2024
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
rewrite_elf_program_header() currently makes a questionable assumption that the LMA of a segment will be aligned at the alignment of the first section in the segment, and attempts to align the address of the segment LMA to the alignment of the first section using align_power() before comparing it to the actual LMA of the first section for the purpose of verifying that the first section starts at the beginning of the segment. This is not a problem when the LMA is equal to the VMA and both are aligned at the section alignment; but, for the sections that have different VMA and LMA, only the VMA is guaranteed to be aligned at the section alignment, and the LMA may or may not be aligned at the same boundary, leading to rewrite_elf_program_header() returning false even for valid ELF files that do not contain any segments whose first section does not start at the beginning of the segment. This patch adds an alternate check directly comparing the segment and section LMAs for the segments that do not contain any headers; in case a segment contains a file or program header, the function may still erroneously return false. A more fundamental fix should re-implement the function such that it uses VMA for verifying that the first section in a segment starts at the beginning of the segment. Signed-off-by: Stephanos Ioannidis <root@stephanos.io>
stephanosio
commented
Jan 25, 2024
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
duynguyenxa
pushed a commit
to renesas/binutils-gdb
that referenced
this pull request
Oct 29, 2025
On Windows gcore is not implemented, and if you try it, you get an
heap-use-after-free error:
(gdb) gcore C:/gdb/build64/gdb-git-python3/gdb/testsuite/outputs/gdb.base/gcore-buffer-overflow/gcore-buffer-overflow.test
warning: cannot close "=================================================================
==10108==ERROR: AddressSanitizer: heap-use-after-free on address 0x1259ea503110 at pc 0x7ff6806e3936 bp 0x0062e01ed990 sp 0x0062e01ed140
READ of size 111 at 0x1259ea503110 thread T0
#0 0x7ff6806e3935 in strlen C:/gcc/src/gcc-14.2.0/libsanitizer/sanitizer_common/sanitizer_common_interceptors.inc:391
zephyrproject-rtos#1 0x7ff6807169c4 in __pformat_puts C:/gcc/src/mingw-w64-v12.0.0/mingw-w64-crt/stdio/mingw_pformat.c:558
zephyrproject-rtos#2 0x7ff6807186c1 in __mingw_pformat C:/gcc/src/mingw-w64-v12.0.0/mingw-w64-crt/stdio/mingw_pformat.c:2514
zephyrproject-rtos#3 0x7ff680713614 in __mingw_vsnprintf C:/gcc/src/mingw-w64-v12.0.0/mingw-w64-crt/stdio/mingw_vsnprintf.c:41
zephyrproject-rtos#4 0x7ff67f34419f in vsnprintf(char*, unsigned long long, char const*, char*) C:/msys64/mingw64/x86_64-w64-mingw32/include/stdio.h:484
zephyrproject-rtos#5 0x7ff67f34419f in string_vprintf[abi:cxx11](char const*, char*) C:/gdb/src/gdb.git/gdbsupport/common-utils.cc:106
zephyrproject-rtos#6 0x7ff67b37b739 in cli_ui_out::do_message(ui_file_style const&, char const*, char*) C:/gdb/src/gdb.git/gdb/cli-out.c:227
zephyrproject-rtos#7 0x7ff67ce3d030 in ui_out::call_do_message(ui_file_style const&, char const*, ...) C:/gdb/src/gdb.git/gdb/ui-out.c:571
zephyrproject-rtos#8 0x7ff67ce4255a in ui_out::vmessage(ui_file_style const&, char const*, char*) C:/gdb/src/gdb.git/gdb/ui-out.c:740
zephyrproject-rtos#9 0x7ff67ce2c873 in ui_file::vprintf(char const*, char*) C:/gdb/src/gdb.git/gdb/ui-file.c:73
zephyrproject-rtos#10 0x7ff67ce7f83d in gdb_vprintf(ui_file*, char const*, char*) C:/gdb/src/gdb.git/gdb/utils.c:1881
zephyrproject-rtos#11 0x7ff67ce7f83d in vwarning(char const*, char*) C:/gdb/src/gdb.git/gdb/utils.c:181
zephyrproject-rtos#12 0x7ff67f3530eb in warning(char const*, ...) C:/gdb/src/gdb.git/gdbsupport/errors.cc:33
zephyrproject-rtos#13 0x7ff67baed27f in gdb_bfd_close_warning C:/gdb/src/gdb.git/gdb/gdb_bfd.c:437
zephyrproject-rtos#14 0x7ff67baed27f in gdb_bfd_close_or_warn C:/gdb/src/gdb.git/gdb/gdb_bfd.c:646
zephyrproject-rtos#15 0x7ff67baed27f in gdb_bfd_unref(bfd*) C:/gdb/src/gdb.git/gdb/gdb_bfd.c:739
zephyrproject-rtos#16 0x7ff68094b6f2 in gdb_bfd_ref_policy::decref(bfd*) C:/gdb/src/gdb.git/gdb/gdb_bfd.h:82
zephyrproject-rtos#17 0x7ff68094b6f2 in gdb::ref_ptr<bfd, gdb_bfd_ref_policy>::~ref_ptr() C:/gdb/src/gdb.git/gdbsupport/gdb_ref_ptr.h:91
zephyrproject-rtos#18 0x7ff67badf4d2 in gcore_command C:/gdb/src/gdb.git/gdb/gcore.c:176
0x1259ea503110 is located 16 bytes inside of 4064-byte region [0x1259ea503100,0x1259ea5040e0)
freed by thread T0 here:
#0 0x7ff6806b1687 in free C:/gcc/src/gcc-14.2.0/libsanitizer/asan/asan_malloc_win.cpp:90
zephyrproject-rtos#1 0x7ff67f2ae807 in objalloc_free C:/gdb/src/gdb.git/libiberty/objalloc.c:187
zephyrproject-rtos#2 0x7ff67d7f56e3 in _bfd_free_cached_info C:/gdb/src/gdb.git/bfd/opncls.c:247
zephyrproject-rtos#3 0x7ff67d7f2782 in _bfd_delete_bfd C:/gdb/src/gdb.git/bfd/opncls.c:180
zephyrproject-rtos#4 0x7ff67d7f5df9 in bfd_close_all_done C:/gdb/src/gdb.git/bfd/opncls.c:960
zephyrproject-rtos#5 0x7ff67d7f62ec in bfd_close C:/gdb/src/gdb.git/bfd/opncls.c:925
zephyrproject-rtos#6 0x7ff67baecd27 in gdb_bfd_close_or_warn C:/gdb/src/gdb.git/gdb/gdb_bfd.c:643
zephyrproject-rtos#7 0x7ff67baecd27 in gdb_bfd_unref(bfd*) C:/gdb/src/gdb.git/gdb/gdb_bfd.c:739
zephyrproject-rtos#8 0x7ff68094b6f2 in gdb_bfd_ref_policy::decref(bfd*) C:/gdb/src/gdb.git/gdb/gdb_bfd.h:82
zephyrproject-rtos#9 0x7ff68094b6f2 in gdb::ref_ptr<bfd, gdb_bfd_ref_policy>::~ref_ptr() C:/gdb/src/gdb.git/gdbsupport/gdb_ref_ptr.h:91
zephyrproject-rtos#10 0x7ff67badf4d2 in gcore_command C:/gdb/src/gdb.git/gdb/gcore.c:176
It happens because gdb_bfd_close_or_warn uses a bfd-internal name for
the failing-close warning, after the close is finished, and the name
already freed:
static int
gdb_bfd_close_or_warn (struct bfd *abfd)
{
int ret;
const char *name = bfd_get_filename (abfd);
for (asection *sect : gdb_bfd_sections (abfd))
free_one_bfd_section (sect);
ret = bfd_close (abfd);
if (!ret)
gdb_bfd_close_warning (name,
bfd_errmsg (bfd_get_error ()));
return ret;
}
Fixed by making a copy of the name for the warning.
Approved-By: Andrew Burgess <aburgess@redhat.com>
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
rewrite_elf_program_header() currently makes a questionable assumption that the LMA of a segment will be aligned at the alignment of the first section in the segment, and attempts to align the address of the segment LMA to the alignment of the first section using align_power() before comparing it to the actual LMA of the first section for the purpose of verifying that the first section starts at the beginning of the segment.
This is not a problem when the LMA is equal to the VMA and both are aligned at the section alignment; but, for the sections that have different VMA and LMA, only the VMA is guaranteed to be aligned at the section alignment, and the LMA may or may not be aligned at the same boundary, leading to rewrite_elf_program_header() returning false even for valid ELF files that do not contain any segments whose first section does not start at the beginning of the segment.
This patch adds an alternate check directly comparing the segment and section LMAs for the segments that do not contain any headers; in case a segment contains a file or program header, the function may still erroneously return false.
A more fundamental fix should re-implement the function such that it uses VMA for verifying that the first section in a segment starts at the beginning of the segment.
Fixes zephyrproject-rtos/zephyr#58080