* [PATCH 1/2] libdwfl: handle duplicate ELFs when reporting archives
@ 2023-11-17 22:35 vvvvvv
2023-11-17 22:35 ` [PATCH 2/2] tests: Add test for duplicate entries in archive vvvvvv
2023-11-18 22:47 ` [PATCH 1/2] libdwfl: handle duplicate ELFs when reporting archives Mark Wielaard
0 siblings, 2 replies; 6+ messages in thread
From: vvvvvv @ 2023-11-17 22:35 UTC (permalink / raw)
To: elfutils-devel; +Cc: kernel-team, maennich, vvvvvv
From: Aleksei Vetrov <vvvvvv@google.com>
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 overlapping or duplicate modules to
prolong its lifetime for subsequent processing.
Signed-off-by: Aleksei Vetrov <vvvvvv@google.com>
---
libdwfl/dwfl_report_elf.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/libdwfl/dwfl_report_elf.c b/libdwfl/dwfl_report_elf.c
index 581f4079..58b06aea 100644
--- a/libdwfl/dwfl_report_elf.c
+++ b/libdwfl/dwfl_report_elf.c
@@ -276,7 +276,8 @@ __libdwfl_report_elf (Dwfl *dwfl, const char *name, const char *file_name,
}
else
{
- elf_end (elf);
+ elf_end (m->main.elf);
+ m->main.elf = elf;
if (m->main_bias != bias
|| m->main.vaddr != vaddr || m->main.address_sync != address_sync)
goto overlap;
--
2.43.0.rc1.413.gea7ed67945-goog
^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH 2/2] tests: Add test for duplicate entries in archive
2023-11-17 22:35 [PATCH 1/2] libdwfl: handle duplicate ELFs when reporting archives vvvvvv
@ 2023-11-17 22:35 ` vvvvvv
2023-11-18 22:50 ` Mark Wielaard
2023-11-18 22:47 ` [PATCH 1/2] libdwfl: handle duplicate ELFs when reporting archives Mark Wielaard
1 sibling, 1 reply; 6+ messages in thread
From: vvvvvv @ 2023-11-17 22:35 UTC (permalink / raw)
To: elfutils-devel; +Cc: kernel-team, maennich, vvvvvv
From: Aleksei Vetrov <vvvvvv@google.com>
Test dwfl-report-offline-memory against an archive that contains
non-relocatable ELFs with the same name and contents.
Signed-off-by: Aleksei Vetrov <vvvvvv@google.com>
---
tests/run-dwfl-report-offline-memory.sh | 7 +++++++
tests/test-ar-duplicates.a.bz2 | Bin 0 -> 783 bytes
2 files changed, 7 insertions(+)
create mode 100644 tests/test-ar-duplicates.a.bz2
diff --git a/tests/run-dwfl-report-offline-memory.sh b/tests/run-dwfl-report-offline-memory.sh
index 644a45dc..85f43f53 100755
--- a/tests/run-dwfl-report-offline-memory.sh
+++ b/tests/run-dwfl-report-offline-memory.sh
@@ -20,7 +20,14 @@
testfiles testfile-dwfl-report-elf-align-shlib.so
testfiles testarchive64.a
+# echo "int _start(void) { return 0; }" > test.c
+# gcc test.c -nostdlib -static -o test.o
+# ar -r test-ar-duplicates.a test.o test.o test.o
+# bzip2 -zf test-ar-duplicates.a
+testfiles test-ar-duplicates.a
+
testrun ${abs_builddir}/dwfl-report-offline-memory ./testfile-dwfl-report-elf-align-shlib.so 1
testrun ${abs_builddir}/dwfl-report-offline-memory ./testarchive64.a 3
+testrun ${abs_builddir}/dwfl-report-offline-memory ./test-ar-duplicates.a 1
exit 0
diff --git a/tests/test-ar-duplicates.a.bz2 b/tests/test-ar-duplicates.a.bz2
new file mode 100644
index 0000000000000000000000000000000000000000..e8168c6bb813bb05292372d6b856e2ca1163a835
GIT binary patch
literal 783
zcmV+q1MvJpT4*^jL0KkKS*O-t`~U>U|NsC0^v!1T{dI5Uazg*-o^**RKmrI*1V9J?
z0RUpbpefJ;J^%m!H~;_|001&HG5`Po00EJZ00u$8007Vc0g<7Q0000042*yPG7bO$
z27mwzjSPSQ0001FWB>t>Z~y=_003lYWB>pF00Sc+01Sb>Qb4DoG|(YN(+YV{O*J>F
zZ891m=`tHrY3VgR0F2UlO|*o0s(PNL3ovPT-FWk=B;Jux%~F)fXQs4SQOt9gyiE>j
zn6Ga(89!@GYHl-L-dxbs$}&@+(DyVdX=!IB!kuQ))6nI$Da(vh*7{bCREV6#KNqm!
zdu&Mb+M`10By`;OIdVe?-cr&jN>kKstt5_(4hBpYI!%S0RYq!zoTdw-r};8m5SuEI
zu&BS|S>97Ll_Ks%qWX~|eNFX2+)(wDko6K&h@AyU+*7EjB0KJbX(i2-NWr+XprTIu
zB%S!mUnj<+n4}YmKId7>S^5_w!Fy?EWo4tTvdK6U;gV9C5?V$|i8mD;#X<L~F;qz<
z>sVDVQ%g0=kvP>JW-B*XEa@sbQG}Le!OvXnKQ+tOr1|<*S=e&p2DS+rYDV*_vs1e6
zu1U>irf%B#9wjbP_72;9ds3ZsFn8O_*f5OUXClse^_%iUp6rvfsXM*Jq^>8z@U|Q6
z*J1OxE^e`H$%>n8wk=MZHxzfH?{*p^+fvGr{$BN;1J#puO|@+L>>t^ZP1xPOJkJDd
zG&~LmIfeUCo0!>Vz3RBGUhvbk7`3dlX0%-$MeRv3e^oYHE+>J;`q?pM6W?@SQ#QEc
ze~0GQ%}g2{wdp?SsT`$F_Z(%Ds5sw)!*Wg-`sD8<;cAYoXHLwT6*G9*M;hmeoNOvD
zUXsh63|o(x!uDHDwwJQ<E@v84@+{eIJd9#%jkv|P8OF4plK9Q=xDsqeh_q{5laaXh
zUc~3=V;Wm-i(2)goXz8Q9B(USi{5!(`RI9Ax87BbN14d~uU*-b&dJEAg!8=*3()`K
N?ntK!5)}H&|9~F>bnE~C
literal 0
HcmV?d00001
--
2.43.0.rc1.413.gea7ed67945-goog
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH 1/2] libdwfl: handle duplicate ELFs when reporting archives
2023-11-17 22:35 [PATCH 1/2] libdwfl: handle duplicate ELFs when reporting archives vvvvvv
2023-11-17 22:35 ` [PATCH 2/2] tests: Add test for duplicate entries in archive vvvvvv
@ 2023-11-18 22:47 ` Mark Wielaard
2023-11-20 17:39 ` Aleksei Vetrov
1 sibling, 1 reply; 6+ messages in thread
From: Mark Wielaard @ 2023-11-18 22:47 UTC (permalink / raw)
To: vvvvvv; +Cc: elfutils-devel, kernel-team, maennich
Hi Aleksei,
On Fri, Nov 17, 2023 at 10:35:40PM +0000, vvvvvv@google.com wrote:
> 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 overlapping or duplicate modules to
> prolong its lifetime for subsequent processing.
Thanks for that analysis and proposed solution. The ownership
reasoning makes sense. But I do have one question.
> diff --git a/libdwfl/dwfl_report_elf.c b/libdwfl/dwfl_report_elf.c
> index 581f4079..58b06aea 100644
> --- a/libdwfl/dwfl_report_elf.c
> +++ b/libdwfl/dwfl_report_elf.c
> @@ -276,7 +276,8 @@ __libdwfl_report_elf (Dwfl *dwfl, const char *name, const char *file_name,
> }
> else
> {
> - elf_end (elf);
> + elf_end (m->main.elf);
> + m->main.elf = elf;
> if (m->main_bias != bias
> || m->main.vaddr != vaddr || m->main.address_sync != address_sync)
> goto overlap;
If we goto overlap here don't we still have a problem? overlap will
set m->gc = true; and return NULL. So the caller will think they
still owns the elf handle and will probably close it. But then when
the module is GCed in dwfl_report_end it will close the elf handle
again.
Should we instead move the elf_end and reassignment of main.elf to
after this if statement?
Thanks,
Mark
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH 2/2] tests: Add test for duplicate entries in archive
2023-11-17 22:35 ` [PATCH 2/2] tests: Add test for duplicate entries in archive vvvvvv
@ 2023-11-18 22:50 ` Mark Wielaard
2023-11-20 17:36 ` Aleksei Vetrov
0 siblings, 1 reply; 6+ messages in thread
From: Mark Wielaard @ 2023-11-18 22:50 UTC (permalink / raw)
To: vvvvvv; +Cc: elfutils-devel, kernel-team, maennich
Hi Aleksei,
On Fri, Nov 17, 2023 at 10:35:41PM +0000, vvvvvv@google.com wrote:
> Test dwfl-report-offline-memory against an archive that contains
> non-relocatable ELFs with the same name and contents.
Nice testcase. Do note that you also have to add the new test file to
EXTRA_DIST so it actually gets into the dist.
* tests/test-ar-duplicates.a.bz2: New test file.
* tests/run-dwfl-report-offline-memory.sh: Test new
test-ar-duplicates.a.bz2.
* tests/Makefile.am (EXTRA_DIST): Add test-ar-duplicates.a.bz2.
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 7fb8efb1..80f6cb59 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -632,7 +632,8 @@ EXTRA_DIST = run-arextract.sh run-arsymtest.sh run-ar.sh \
run-nvidia-extended-linemap-libdw.sh run-nvidia-extended-linemap-readelf.sh \
testfile_nvidia_linemap.bz2 \
testfile-largealign.o.bz2 run-strip-largealign.sh \
- run-funcretval++11.sh
+ run-funcretval++11.sh \
+ test-ar-duplicates.a.bz2
make distcheck catches these things by creating a dist and doing a
build and run various tests and make check.
Cheers,
Mark
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH 2/2] tests: Add test for duplicate entries in archive
2023-11-18 22:50 ` Mark Wielaard
@ 2023-11-20 17:36 ` Aleksei Vetrov
0 siblings, 0 replies; 6+ messages in thread
From: Aleksei Vetrov @ 2023-11-20 17:36 UTC (permalink / raw)
To: Mark Wielaard; +Cc: elfutils-devel, kernel-team, maennich
[-- Attachment #1: Type: text/plain, Size: 230 bytes --]
Hello Mark,
On Sat, Nov 18, 2023 at 10:50 PM Mark Wielaard <mark@klomp.org> wrote:
> Do note that you also have to add the new test file to
> EXTRA_DIST so it actually gets into the dist.
Thanks, will do in [PATCH v2].
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH 1/2] libdwfl: handle duplicate ELFs when reporting archives
2023-11-18 22:47 ` [PATCH 1/2] libdwfl: handle duplicate ELFs when reporting archives Mark Wielaard
@ 2023-11-20 17:39 ` Aleksei Vetrov
0 siblings, 0 replies; 6+ messages in thread
From: Aleksei Vetrov @ 2023-11-20 17:39 UTC (permalink / raw)
To: Mark Wielaard; +Cc: elfutils-devel, kernel-team, maennich
[-- Attachment #1: Type: text/plain, Size: 588 bytes --]
Hello Mark,
On Sat, Nov 18, 2023 at 10:47 PM Mark Wielaard <mark@klomp.org> wrote:
> If we goto overlap here don't we still have a problem? overlap will
> set m->gc = true; and return NULL. So the caller will think they
> still owns the elf handle and will probably close it. But then when
> the module is GCed in dwfl_report_end it will close the elf handle
> again.
Thank you for noticing! Yes, this is oversight from my side.
> Should we instead move the elf_end and reassignment of main.elf to
> after this if statement?
Will fix exactly like this in [PATCH v2].
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2023-11-20 17:40 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-11-17 22:35 [PATCH 1/2] libdwfl: handle duplicate ELFs when reporting archives vvvvvv
2023-11-17 22:35 ` [PATCH 2/2] tests: Add test for duplicate entries in archive vvvvvv
2023-11-18 22:50 ` Mark Wielaard
2023-11-20 17:36 ` Aleksei Vetrov
2023-11-18 22:47 ` [PATCH 1/2] libdwfl: handle duplicate ELFs when reporting archives Mark Wielaard
2023-11-20 17:39 ` Aleksei Vetrov
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).