[lld-macho] Fix use-after-free in loadDylib()

We were taking a reference to a value in `loadedDylibs`, which in turn
called `make<DylibFile>()`, which could then recursively call
`loadDylibs`, which would then potentially resize `loadedDylibs` and
invalidate that reference.

Fixes PR50101.

Reviewed By: #lld-macho, oontvoo

Differential Revision: https://reviews.llvm.org/D101175
This commit is contained in:
Jez Ng 2021-04-23 18:05:34 -04:00
parent 035eb6d154
commit 3fe5c3b018
2 changed files with 8 additions and 3 deletions

View File

@ -188,8 +188,8 @@ static DenseMap<CachedHashStringRef, DylibFile *> loadedDylibs;
Optional<DylibFile *> macho::loadDylib(MemoryBufferRef mbref,
DylibFile *umbrella,
bool isBundleLoader) {
StringRef path = mbref.getBufferIdentifier();
DylibFile *&file = loadedDylibs[CachedHashStringRef(path)];
CachedHashStringRef path(mbref.getBufferIdentifier());
DylibFile *file = loadedDylibs[path];
if (file)
return file;
@ -209,6 +209,11 @@ Optional<DylibFile *> macho::loadDylib(MemoryBufferRef mbref,
magic == file_magic::macho_bundle);
file = make<DylibFile>(mbref, umbrella, isBundleLoader);
}
// Note that DylibFile's ctor may recursively invoke loadDylib(), which can
// cause loadedDylibs to get resized and its iterators invalidated. As such,
// we redo the key lookup here instead of caching an iterator from our earlier
// lookup at the start of the function.
loadedDylibs[path] = file;
return file;
}

View File

@ -160,7 +160,7 @@ public:
bool isBundleLoader;
private:
template <class LP> void parse(DylibFile *umbrella = nullptr);
template <class LP> void parse(DylibFile *umbrella);
};
// .a file