[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
This commit is contained in:
Frederic Riss 2016-05-09 14:44:14 +00:00
parent ee2078606f
commit 856a0143b0
4 changed files with 15 additions and 2 deletions

View File

@ -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"

View File

@ -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) {

View File

@ -42,6 +42,7 @@ class BinaryHolder {
std::unique_ptr<MemoryBuffer> CurrentMemoryBuffer;
std::vector<std::unique_ptr<object::ObjectFile>> CurrentObjectFiles;
std::unique_ptr<object::MachOUniversalBinary> CurrentFatBinary;
std::string CurrentFatBinaryName;
bool Verbose;
/// Get the MemoryBufferRefs for the file specification in \p