From 856a0143b0b25c58f726d66f222cec00b4185c61 Mon Sep 17 00:00:00 2001 From: Frederic Riss Date: Mon, 9 May 2016 14:44:14 +0000 Subject: [PATCH] [dsymutil] Prevent use-after-free The BinaryHolder would query the archive member MemoryBuffer name to check if the current open archive also contains the next requested objectfile. This comparison was using a StringRef to a temporary buffer. It only happened with fat archives. This commit adds long-lived storage along with the MemoryBuffers for the fat archive filename. The added test would fail during an ASAN build without the fix. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@268924 91177308-0d34-0410-b5e6-96231b3b80d8 --- .../dsymutil/Inputs/basic-with-libfat-test.macho.x86_64 | Bin 0 -> 9472 bytes test/tools/dsymutil/X86/basic-with-libfat-test.test | 10 ++++++++++ tools/dsymutil/BinaryHolder.cpp | 6 ++++-- tools/dsymutil/BinaryHolder.h | 1 + 4 files changed, 15 insertions(+), 2 deletions(-) create mode 100755 test/tools/dsymutil/Inputs/basic-with-libfat-test.macho.x86_64 create mode 100644 test/tools/dsymutil/X86/basic-with-libfat-test.test diff --git a/test/tools/dsymutil/Inputs/basic-with-libfat-test.macho.x86_64 b/test/tools/dsymutil/Inputs/basic-with-libfat-test.macho.x86_64 new file mode 100755 index 0000000000000000000000000000000000000000..7160e2827725c2d80bc2c72b6f4f57c021cfb756 GIT binary patch literal 9472 zcmeHNU1%It6h7PRwxPx(BKU*088p};Bf zfrR?EtUnP!6hwUWEkb=aR7|a4g5Yc3gcTHh@L>tT_6ASAQEa5S==WgUC{2Z$QxpzC-N{f4pnMmgfsg&*5 z?0NEU@#?i9-d=erl_(Z-RDFF=7}n3>XFs1BL;^fMLKeU>NwX8MqiP{~W*mYj^zJ$T)t7 zmlw7x_-hZXSI;Ara;#S6FXYO2EwoyR^l--7(i$2mKYJgV&}#Ws{Q5WDmv46UEMim` zuM*ipFXGOM{EqJBo6B1CdgX=M(n5`~yWYDO$0{Ed%CYTV9zcs^zD84NZyT?b*Q=Ly zc6MN@#J0VqGMP-YtLJsh@Ycih58UZXtL~cZp%0jKW4^h2% zbb6FlNU-Jad_M1bM;gjm* z2{nh2b945zO!9q0o2(qd;q${dEcf8>wuQqxmS%0`(1bMs#JPH}lQ!6z3=WM(>02N{yyL;aBl$9-V4=x zzQkv72x9v40|_>-LFunCyYzn$N+G7d#!J9Q_!0)2tF*mI9LBc^KIYh7^?gV?RLiI6 z>{g%U=l3n_%ui#+znl7IeE;u#e~q<2_vtCbtWV<&U<;~+_Py%)iFQ31?Ix7<+&*^v zB@WY{d~;u${cR}g(U@bbhe{!4K0(~HK5U(w1!*(>~VM*C`+Cd`}bOn}rVle4p{L{!Zcou=nRKA(jk`P*^Q4n5 zI?-f(4BPefQM<3+E%b{D{Ff%|Vm3M0?B)@)^hXr X{JCO~4t{N+icTq^68PW;cR0%5>U(R? literal 0 HcmV?d00001 diff --git a/test/tools/dsymutil/X86/basic-with-libfat-test.test b/test/tools/dsymutil/X86/basic-with-libfat-test.test new file mode 100644 index 00000000000..0ec2d537f42 --- /dev/null +++ b/test/tools/dsymutil/X86/basic-with-libfat-test.test @@ -0,0 +1,10 @@ +RUN: llvm-dsymutil -f -o - -oso-prepend-path=%p/.. %p/../Inputs/basic-with-libfat-test.macho.x86_64 | llvm-dwarfdump - | FileCheck %s + +The test binary was created by force-linking the libfat-test.a fat archive +with the basic linking test archive, like so: +$ clang -all_load libfat-test.a libbasic.a basic1.macho.x86_64.o -Wl,-dead_strip -u _x86_64_var + +CHECK: DW_AT_name{{.*}}"x86_64_var" +CHECK: DW_AT_name{{.*}}"basic2.c" +CHECK: DW_AT_name{{.*}}"basic3.c" +CHECK: DW_AT_name{{.*}}"basic1.c" diff --git a/tools/dsymutil/BinaryHolder.cpp b/tools/dsymutil/BinaryHolder.cpp index 7644f01952f..32d176645bf 100644 --- a/tools/dsymutil/BinaryHolder.cpp +++ b/tools/dsymutil/BinaryHolder.cpp @@ -79,7 +79,8 @@ BinaryHolder::GetMemoryBuffersForFile(StringRef Filename, } CurrentFatBinary = std::move(*ErrOrFat); - return getMachOFatMemoryBuffers(Filename, *CurrentMemoryBuffer, + CurrentFatBinaryName = Filename; + return getMachOFatMemoryBuffers(CurrentFatBinaryName, *CurrentMemoryBuffer, *CurrentFatBinary); } @@ -149,8 +150,9 @@ BinaryHolder::MapArchiveAndGetMemberBuffers(StringRef Filename, ArchiveBuffers.push_back(CurrentMemoryBuffer->getMemBufferRef()); } else { CurrentFatBinary = std::move(*ErrOrFat); + CurrentFatBinaryName = ArchiveFilename; ArchiveBuffers = getMachOFatMemoryBuffers( - ArchiveFilename, *CurrentMemoryBuffer, *CurrentFatBinary); + CurrentFatBinaryName, *CurrentMemoryBuffer, *CurrentFatBinary); } for (auto MemRef : ArchiveBuffers) { diff --git a/tools/dsymutil/BinaryHolder.h b/tools/dsymutil/BinaryHolder.h index d56a39597c2..97508b9fb09 100644 --- a/tools/dsymutil/BinaryHolder.h +++ b/tools/dsymutil/BinaryHolder.h @@ -42,6 +42,7 @@ class BinaryHolder { std::unique_ptr CurrentMemoryBuffer; std::vector> CurrentObjectFiles; std::unique_ptr CurrentFatBinary; + std::string CurrentFatBinaryName; bool Verbose; /// Get the MemoryBufferRefs for the file specification in \p -- 2.11.0