aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2023-11-24 00:05:28 +0000
committerAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2023-11-24 00:05:28 +0000
commitdd8372c4eb2738e142d708d32f932f8647a3a9bd (patch)
treee75e54eada4a721a2dab5cb7ded84d134925138c
parent5e5627ab165aac8c2b7fa02f792d2db98f7c7120 (diff)
parentf464f82784c943ca49fe21efda622886bdf018a5 (diff)
downloadelfutils-dd8372c4eb2738e142d708d32f932f8647a3a9bd.tar.gz
Snap for 11139387 from f464f82784c943ca49fe21efda622886bdf018a5 to 24Q1-release
Change-Id: I8e1007f4009fa0ad9558d4c2719a9c142c4d39bb
-rw-r--r--libdw/dwarf_formstring.c6
-rw-r--r--libdwfl/dwfl_report_elf.c3
-rw-r--r--patches/libdw-check-offset-dwarf_formstring-in-all-cases.patch36
-rw-r--r--patches/libdwfl-handle-duplicate-ELFs-when-reporting-archive.patch56
4 files changed, 97 insertions, 4 deletions
diff --git a/libdw/dwarf_formstring.c b/libdw/dwarf_formstring.c
index 0ee42411..65f03a5e 100644
--- a/libdw/dwarf_formstring.c
+++ b/libdw/dwarf_formstring.c
@@ -173,11 +173,11 @@ dwarf_formstring (Dwarf_Attribute *attrp)
off = read_4ubyte_unaligned (dbg, datap);
else
off = read_8ubyte_unaligned (dbg, datap);
-
- if (off >= data_size)
- goto invalid_offset;
}
+ if (off >= data_size)
+ goto invalid_offset;
+
return (const char *) data->d_buf + off;
}
INTDEF(dwarf_formstring)
diff --git a/libdwfl/dwfl_report_elf.c b/libdwfl/dwfl_report_elf.c
index 581f4079..a76d3681 100644
--- a/libdwfl/dwfl_report_elf.c
+++ b/libdwfl/dwfl_report_elf.c
@@ -276,10 +276,11 @@ __libdwfl_report_elf (Dwfl *dwfl, const char *name, const char *file_name,
}
else
{
- elf_end (elf);
if (m->main_bias != bias
|| m->main.vaddr != vaddr || m->main.address_sync != address_sync)
goto overlap;
+ elf_end (m->main.elf);
+ m->main.elf = elf;
}
}
return m;
diff --git a/patches/libdw-check-offset-dwarf_formstring-in-all-cases.patch b/patches/libdw-check-offset-dwarf_formstring-in-all-cases.patch
new file mode 100644
index 00000000..7e30d2a3
--- /dev/null
+++ b/patches/libdw-check-offset-dwarf_formstring-in-all-cases.patch
@@ -0,0 +1,36 @@
+From 1bd9deb9aa19ac2e2fa9665009e0d5924adcf4d3 Mon Sep 17 00:00:00 2001
+From: Aleksei Vetrov <vvvvvv@google.com>
+Date: Thu, 16 Nov 2023 21:29:22 +0000
+Subject: [PATCH] libdw: check offset dwarf_formstring in all cases
+
+This check was initially added to test if offset overflows the safe
+prefix where any string will be null-terminated. However the check
+was placed in a wrong place and didn't cover all `attrp->form` cases.
+
+ * libdw/dwarf_formstring.c (dwarf_formstring): Move offset check
+ right before returning the result.
+
+Signed-off-by: Aleksei Vetrov <vvvvvv@google.com>
+
+diff --git a/libdw/dwarf_formstring.c b/libdw/dwarf_formstring.c
+index 0ee42411..65f03a5e 100644
+--- a/libdw/dwarf_formstring.c
++++ b/libdw/dwarf_formstring.c
+@@ -173,11 +173,11 @@ dwarf_formstring (Dwarf_Attribute *attrp)
+ off = read_4ubyte_unaligned (dbg, datap);
+ else
+ off = read_8ubyte_unaligned (dbg, datap);
+-
+- if (off >= data_size)
+- goto invalid_offset;
+ }
+
++ if (off >= data_size)
++ goto invalid_offset;
++
+ return (const char *) data->d_buf + off;
+ }
+ INTDEF(dwarf_formstring)
+--
+2.43.0.rc1.413.gea7ed67945-goog
+
diff --git a/patches/libdwfl-handle-duplicate-ELFs-when-reporting-archive.patch b/patches/libdwfl-handle-duplicate-ELFs-when-reporting-archive.patch
new file mode 100644
index 00000000..021ecdcf
--- /dev/null
+++ b/patches/libdwfl-handle-duplicate-ELFs-when-reporting-archive.patch
@@ -0,0 +1,56 @@
+From 0ab5a3eb4122f36cbaff259e7a0a3f9d014cb6f7 Mon Sep 17 00:00:00 2001
+From: Aleksei Vetrov <vvvvvv@google.com>
+Date: Mon, 20 Nov 2023 17:44:47 +0000
+Subject: [PATCH] libdwfl: handle duplicate ELFs when reporting archives
+
+When archive is processed in process_archive (libdwfl/offline.c), it
+creates an Elf object for each archive member. Then in
+process_archive_member it calls process_file to create a Dwfl_Module
+through __libdwfl_report_elf.
+
+The ownership of the Elf object is expected to be:
+
+* either transfered to the Dwfl_Module, if __libdwfl_report_elf returns
+ not NULL;
+
+* or handled at the end of process_archive_member by calling elf_end.
+
+Moreover, Elf object is expected to be alive, if __libdwfl_report_elf
+returns not NULL, because at the end of process_archive_member it
+advances to the next member through the elf_next call.
+
+The problem happens when __libdwfl_report_elf encounters Elf with the
+same name and content as it seen before. In that case dwfl_report_module
+will reuse existing Dwfl_Module object. This leads to a codepath that
+calls elf_end on the Elf object, while returning not NULL, breaking the
+elf_next call to the next member.
+
+The fix is to destroy m->main.elf instead and put the new Elf object in
+the already existing Dwfl_Module.
+
+ * libdwfl/dwfl_report_elf.c (__libdwfl_report_elf): Replace Elf in
+ the Dwfl_Module in case of duplicate modules to prolong its
+ lifetime for subsequent processing.
+
+Signed-off-by: Aleksei Vetrov <vvvvvv@google.com>
+
+diff --git a/libdwfl/dwfl_report_elf.c b/libdwfl/dwfl_report_elf.c
+index 581f4079..a76d3681 100644
+--- a/libdwfl/dwfl_report_elf.c
++++ b/libdwfl/dwfl_report_elf.c
+@@ -276,10 +276,11 @@ __libdwfl_report_elf (Dwfl *dwfl, const char *name, const char *file_name,
+ }
+ else
+ {
+- elf_end (elf);
+ if (m->main_bias != bias
+ || m->main.vaddr != vaddr || m->main.address_sync != address_sync)
+ goto overlap;
++ elf_end (m->main.elf);
++ m->main.elf = elf;
+ }
+ }
+ return m;
+--
+2.43.0.rc1.413.gea7ed67945-goog
+