summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorZachary Turner <zturner@google.com>2018-02-28 18:09:18 +0000
committerZachary Turner <zturner@google.com>2018-02-28 18:09:18 +0000
commit3868cfd503de8ad2fb676f50d150d512a1b505de (patch)
treedb150c7aa945f530f0a5d41acb5e2c71e1c1422e
parent367bfce6117cd5126adffb037946e7aa229348a7 (diff)
downloadbcm5719-llvm-3868cfd503de8ad2fb676f50d150d512a1b505de.tar.gz
bcm5719-llvm-3868cfd503de8ad2fb676f50d150d512a1b505de.zip
Fix use after free in PDB linker.
When merging in types from a type server PDB, we would use a pointer into the type server PDB's mapped file buffer directly to avoid copying data. However, we would close the type server PDB after we finished merging in its types, which would unmap all of its memory. This would lead to a use after free. We fix this by making a strong reference in the PDBLinker class to all referenced type server PDBs, thereby making it safe to hold pointers into its memory mapped contents. This fixes llvm.org/pr36455 Differential Revision: https://reviews.llvm.org/D43834 llvm-svn: 326345
-rw-r--r--lld/COFF/PDB.cpp15
1 files changed, 13 insertions, 2 deletions
diff --git a/lld/COFF/PDB.cpp b/lld/COFF/PDB.cpp
index 0ca2587cb27..60e69c1153b 100644
--- a/lld/COFF/PDB.cpp
+++ b/lld/COFF/PDB.cpp
@@ -148,6 +148,11 @@ private:
llvm::SmallString<128> NativePath;
+ /// A list of other PDBs which are loaded during the linking process and which
+ /// we need to keep around since the linking operation may reference pointers
+ /// inside of these PDBs.
+ llvm::SmallVector<std::unique_ptr<pdb::NativeSession>, 2> LoadedPDBs;
+
std::vector<pdb::SecMapEntry> SectionMap;
/// Type index mappings of type server PDBs that we've loaded so far.
@@ -361,10 +366,16 @@ Expected<const CVIndexMap&> PDBLinker::maybeMergeTypeServerPDB(ObjFile *File,
return std::move(E);
}
- auto ExpectedTpi = (*ExpectedSession)->getPDBFile().getPDBTpiStream();
+ pdb::NativeSession *Session = ExpectedSession->get();
+
+ // Keep a strong reference to this PDB, so that it's safe to hold pointers
+ // into the file.
+ LoadedPDBs.push_back(std::move(*ExpectedSession));
+
+ auto ExpectedTpi = Session->getPDBFile().getPDBTpiStream();
if (auto E = ExpectedTpi.takeError())
fatal("Type server does not have TPI stream: " + toString(std::move(E)));
- auto ExpectedIpi = (*ExpectedSession)->getPDBFile().getPDBIpiStream();
+ auto ExpectedIpi = Session->getPDBFile().getPDBIpiStream();
if (auto E = ExpectedIpi.takeError())
fatal("Type server does not have TPI stream: " + toString(std::move(E)));
OpenPOWER on IntegriCloud