diff options
| author | Ben Langmuir <blangmuir@apple.com> | 2014-09-08 16:15:54 +0000 |
|---|---|---|
| committer | Ben Langmuir <blangmuir@apple.com> | 2014-09-08 16:15:54 +0000 |
| commit | ab86fbe4250bf81f46025f9d1b50dfa1c07da9c5 (patch) | |
| tree | ee3aeedce154c896f466f936fbe405b550ba736d | |
| parent | dfa274eb58a6fed420e98a652b1e72a88aed85a6 (diff) | |
| download | bcm5719-llvm-ab86fbe4250bf81f46025f9d1b50dfa1c07da9c5.tar.gz bcm5719-llvm-ab86fbe4250bf81f46025f9d1b50dfa1c07da9c5.zip | |
Make FileEntry::getName() valid across calls to FileManager::getFile()
Because we may change the name of a FileEntry inside getFile, the name
returned by FileEntry::getName() could be destroyed. This was causing a
use-after-free when searching the HeaderFileInfo on-disk hashtable for a
module or pch.
llvm-svn: 217385
| -rw-r--r-- | clang/include/clang/Basic/FileManager.h | 4 | ||||
| -rw-r--r-- | clang/lib/Basic/FileManager.cpp | 17 |
2 files changed, 17 insertions, 4 deletions
diff --git a/clang/include/clang/Basic/FileManager.h b/clang/include/clang/Basic/FileManager.h index dc9d329ab7d..5b2b022f6a3 100644 --- a/clang/include/clang/Basic/FileManager.h +++ b/clang/include/clang/Basic/FileManager.h @@ -59,7 +59,7 @@ public: /// If the 'File' member is valid, then this FileEntry has an open file /// descriptor for the file. class FileEntry { - std::string Name; // Name of the file. + const char *Name; // Name of the file. off_t Size; // File size in bytes. time_t ModTime; // Modification time of file. const DirectoryEntry *Dir; // Directory file lives in. @@ -93,7 +93,7 @@ public: assert(!isValid() && "Cannot copy an initialized FileEntry"); } - const char *getName() const { return Name.c_str(); } + const char *getName() const { return Name; } bool isValid() const { return IsValid; } off_t getSize() const { return Size; } unsigned getUID() const { return UID; } diff --git a/clang/lib/Basic/FileManager.cpp b/clang/lib/Basic/FileManager.cpp index c0522966e38..87844864a85 100644 --- a/clang/lib/Basic/FileManager.cpp +++ b/clang/lib/Basic/FileManager.cpp @@ -270,6 +270,19 @@ const FileEntry *FileManager::getFile(StringRef Filename, bool openFile, FileEntry &UFE = UniqueRealFiles[Data.UniqueID]; NamedFileEnt.setValue(&UFE); + + // If the name returned by getStatValue is different than Filename, re-intern + // the name. + if (Data.Name != Filename) { + auto &NamedFileEnt = SeenFileEntries.GetOrCreateValue(Data.Name); + if (!NamedFileEnt.getValue()) + NamedFileEnt.setValue(&UFE); + else + assert(NamedFileEnt.getValue() == &UFE && + "filename from getStatValue() refers to wrong file"); + InterndFileName = NamedFileEnt.getKeyData(); + } + if (UFE.isValid()) { // Already have an entry with this inode, return it. // FIXME: this hack ensures that if we look up a file by a virtual path in @@ -286,13 +299,13 @@ const FileEntry *FileManager::getFile(StringRef Filename, bool openFile, // to switch towards a design where we return a FileName object that // encapsulates both the name by which the file was accessed and the // corresponding FileEntry. - UFE.Name = Data.Name; + UFE.Name = InterndFileName; return &UFE; } // Otherwise, we don't have this file yet, add it. - UFE.Name = Data.Name; + UFE.Name = InterndFileName; UFE.Size = Data.Size; UFE.ModTime = Data.ModTime; UFE.Dir = DirInfo; |

