From 3fe5c3b0189f51868493bbbc6768ef3afbdfb492 Mon Sep 17 00:00:00 2001 From: Jez Ng Date: Fri, 23 Apr 2021 18:05:34 -0400 Subject: [PATCH] [lld-macho] Fix use-after-free in loadDylib() We were taking a reference to a value in `loadedDylibs`, which in turn called `make()`, 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 --- lld/MachO/DriverUtils.cpp | 9 +++++++-- lld/MachO/InputFiles.h | 2 +- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/lld/MachO/DriverUtils.cpp b/lld/MachO/DriverUtils.cpp index bbbc339c3177..e0f6a353c03e 100644 --- a/lld/MachO/DriverUtils.cpp +++ b/lld/MachO/DriverUtils.cpp @@ -188,8 +188,8 @@ static DenseMap loadedDylibs; Optional 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 macho::loadDylib(MemoryBufferRef mbref, magic == file_magic::macho_bundle); file = make(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; } diff --git a/lld/MachO/InputFiles.h b/lld/MachO/InputFiles.h index 4db93bec8611..066d4506644c 100644 --- a/lld/MachO/InputFiles.h +++ b/lld/MachO/InputFiles.h @@ -160,7 +160,7 @@ public: bool isBundleLoader; private: - template void parse(DylibFile *umbrella = nullptr); + template void parse(DylibFile *umbrella); }; // .a file