forked from OSchip/llvm-project
[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:
parent
035eb6d154
commit
3fe5c3b018
|
@ -188,8 +188,8 @@ static DenseMap<CachedHashStringRef, DylibFile *> loadedDylibs;
|
||||||
Optional<DylibFile *> macho::loadDylib(MemoryBufferRef mbref,
|
Optional<DylibFile *> macho::loadDylib(MemoryBufferRef mbref,
|
||||||
DylibFile *umbrella,
|
DylibFile *umbrella,
|
||||||
bool isBundleLoader) {
|
bool isBundleLoader) {
|
||||||
StringRef path = mbref.getBufferIdentifier();
|
CachedHashStringRef path(mbref.getBufferIdentifier());
|
||||||
DylibFile *&file = loadedDylibs[CachedHashStringRef(path)];
|
DylibFile *file = loadedDylibs[path];
|
||||||
if (file)
|
if (file)
|
||||||
return file;
|
return file;
|
||||||
|
|
||||||
|
@ -209,6 +209,11 @@ Optional<DylibFile *> macho::loadDylib(MemoryBufferRef mbref,
|
||||||
magic == file_magic::macho_bundle);
|
magic == file_magic::macho_bundle);
|
||||||
file = make<DylibFile>(mbref, umbrella, isBundleLoader);
|
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;
|
return file;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -160,7 +160,7 @@ public:
|
||||||
bool isBundleLoader;
|
bool isBundleLoader;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
template <class LP> void parse(DylibFile *umbrella = nullptr);
|
template <class LP> void parse(DylibFile *umbrella);
|
||||||
};
|
};
|
||||||
|
|
||||||
// .a file
|
// .a file
|
||||||
|
|
Loading…
Reference in New Issue