diff options
author | Lancelot SIX <lancelot.six@amd.com> | 2023-05-31 11:35:32 +0100 |
---|---|---|
committer | Lancelot SIX <lancelot.six@amd.com> | 2023-06-08 14:18:09 +0100 |
commit | 9b3a1001c8405965b3142d7361c13049714e543f (patch) | |
tree | da3e2f9e5998e6d1f0d14c79363fd6b71e24493a | |
parent | 12f7174bf069f407d5b6f12e926ceabe45e450e1 (diff) | |
download | gdb-9b3a1001c8405965b3142d7361c13049714e543f.zip gdb-9b3a1001c8405965b3142d7361c13049714e543f.tar.gz gdb-9b3a1001c8405965b3142d7361c13049714e543f.tar.bz2 |
gdb/corelow.c: fix use-after-free in build_file_mappings
In core_target::build_file_mappings, GDB tries to open files referenced
in the core dump.
The process goes like this:
struct bfd *bfd = bfd_map[filename];
if (bfd == nullptr)
{
bfd = bfd_map[filename]
= bfd_openr (expanded_fname.get (), "binary");
if (bfd == nullptr || !bfd_check_format (bfd, bfd_object))
{
if (bfd != nullptr)
bfd_close (bfd);
return;
}
}
asection *sec = bfd_make_section_anyway (bfd, "load");
...
The problem is that if bfd_check_format fails, we close the bfd but keep
a reference to it in the bfd_map.
If the same filename appears another time in the NT_FILE note, we enter
this code again. The second time, bfd_map[filename] is not nullptr and
we try to call bfd_make_section_anyway on an already closed BFD, which
is a use-after-free error.
This patch makes sure that the bfd is only saved in the bfd_map if it
got opened successfully.
This error got exposed by a recent change in BFD (014a602b86f "Don't
optimise bfd_seek to same position"). Since this change, opening a
coredump which contains mapping to some special files such as a DRI
render node (/dev/dri/renderD$NUM) exposes the issue. This happens for
example for processes using AMDGPU devices to offload compute tasks.
Reviewed-By: John Baldwin <jhb@FreeBSD.org>
Approved-By: Andrew Burgess <aburgess@redhat.com>
-rw-r--r-- | gdb/corelow.c | 4 |
1 files changed, 2 insertions, 2 deletions
diff --git a/gdb/corelow.c b/gdb/corelow.c index db489b4..54def41 100644 --- a/gdb/corelow.c +++ b/gdb/corelow.c @@ -258,8 +258,7 @@ core_target::build_file_mappings () return; } - bfd = bfd_map[filename] = bfd_openr (expanded_fname.get (), - "binary"); + bfd = bfd_openr (expanded_fname.get (), "binary"); if (bfd == nullptr || !bfd_check_format (bfd, bfd_object)) { @@ -284,6 +283,7 @@ core_target::build_file_mappings () This can be checked before/after a core file detach via "maint info bfds". */ gdb_bfd_record_inclusion (core_bfd, bfd); + bfd_map[filename] = bfd; } /* Make new BFD section. All sections have the same name, |