aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2023-11-29 00:04:10 +0000
committerAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2023-11-29 00:04:10 +0000
commit60d9c6b48bb8fbaeba791ee15b003f90b3ec1d64 (patch)
tree9e0f058a7450c9e97fc745899e6ee4fcd714dc63
parent85643939a9161d14cfa1eb7fc1a03aa924372013 (diff)
parentd6bbe48d7ec724c092979583fb9ae0879ac5b3aa (diff)
downloadelfutils-60d9c6b48bb8fbaeba791ee15b003f90b3ec1d64.tar.gz
Snap for 11152489 from d6bbe48d7ec724c092979583fb9ae0879ac5b3aa to sdk-release
Change-Id: I6608598da65170bee81f85e8efd58c858edac7b4
-rw-r--r--libdw/dwarf_formstring.c6
-rw-r--r--libdwfl/dwfl_report_elf.c3
-rw-r--r--libelf/elf_compress.c2
-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
-rw-r--r--patches/libelf-check-decompressed-ZSTD-size.patch33
6 files changed, 131 insertions, 5 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/libelf/elf_compress.c b/libelf/elf_compress.c
index f13b41ba..e3ecab32 100644
--- a/libelf/elf_compress.c
+++ b/libelf/elf_compress.c
@@ -421,7 +421,7 @@ __libelf_decompress_zstd (void *buf_in, size_t size_in, size_t size_out)
}
size_t ret = ZSTD_decompress (buf_out, size_out, buf_in, size_in);
- if (ZSTD_isError (ret))
+ if (unlikely (ZSTD_isError (ret)) || unlikely (ret != size_out))
{
free (buf_out);
__libelf_seterrno (ELF_E_DECOMPRESS_ERROR);
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
+
diff --git a/patches/libelf-check-decompressed-ZSTD-size.patch b/patches/libelf-check-decompressed-ZSTD-size.patch
new file mode 100644
index 00000000..6c76fac1
--- /dev/null
+++ b/patches/libelf-check-decompressed-ZSTD-size.patch
@@ -0,0 +1,33 @@
+From 03c171947cc538b04957ac2222ce86e7c0170bd1 Mon Sep 17 00:00:00 2001
+From: Aleksei Vetrov <vvvvvv@google.com>
+Date: Thu, 23 Nov 2023 15:31:47 +0000
+Subject: [PATCH] libelf: check decompressed ZSTD size
+
+Decompression functions like __libelf_decompress_zlib check that
+decompressed data has the same size as it was declared in the header
+(size_out argument). The same check is now added to
+__libelf_decompress_zstd to make sure that the whole allocated buffer is
+initialized.
+
+ * libelf/elf_compress.c (__libelf_decompress_zstd): Use return value
+ of ZSTD_decompress to check that decompressed data size is the
+ same as size_out of the buffer that was allocated.
+
+Signed-off-by: Aleksei Vetrov <vvvvvv@google.com>
+
+diff --git a/libelf/elf_compress.c b/libelf/elf_compress.c
+index c7283c6a..0ad6a32a 100644
+--- a/libelf/elf_compress.c
++++ b/libelf/elf_compress.c
+@@ -422,7 +422,7 @@ __libelf_decompress_zstd (void *buf_in, size_t size_in, size_t size_out)
+ }
+
+ size_t ret = ZSTD_decompress (buf_out, size_out, buf_in, size_in);
+- if (ZSTD_isError (ret))
++ if (unlikely (ZSTD_isError (ret)) || unlikely (ret != size_out))
+ {
+ free (buf_out);
+ __libelf_seterrno (ELF_E_DECOMPRESS_ERROR);
+--
+2.43.0.rc1.413.gea7ed67945-goog
+