]> granicus.if.org Git - llvm/commitdiff
[dsymutil] Prevent use-after-free
authorFrederic Riss <friss@apple.com>
Mon, 9 May 2016 14:44:14 +0000 (14:44 +0000)
committerFrederic Riss <friss@apple.com>
Mon, 9 May 2016 14:44:14 +0000 (14:44 +0000)
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

test/tools/dsymutil/Inputs/basic-with-libfat-test.macho.x86_64 [new file with mode: 0755]
test/tools/dsymutil/X86/basic-with-libfat-test.test [new file with mode: 0644]
tools/dsymutil/BinaryHolder.cpp
tools/dsymutil/BinaryHolder.h

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 (executable)
index 0000000..7160e28
Binary files /dev/null and b/test/tools/dsymutil/Inputs/basic-with-libfat-test.macho.x86_64 differ
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 (file)
index 0000000..0ec2d53
--- /dev/null
@@ -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"
index 7644f01952ff0229fc819c1335032e4732b903b4..32d176645bf94e2f33e02b09abd5fe5f4f87aff4 100644 (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) {
index d56a39597c2e0063b3f30a28f7854afb69a4224c..97508b9fb09da831531bf102be66e604e0446207 100644 (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