From c5fc40e8407a791b6ab37d8096983dda222ff4b2 Mon Sep 17 00:00:00 2001 From: Mike Ash Date: Wed, 25 May 2022 20:21:09 -0400 Subject: [PATCH] [Runtime] Don't try to demangle unprefixed untrusted names. Remove operator new/delete hackery. The operator new/delete overrides aren't working out due to inconsistent inlining of std::string creation/deletion. We can end up creating one with the global new but destroying it with our local delete. If they aren't compatible, this crashes. Instead, avoid problematic new/delete activity coming from lookup of ObjC class names. Names passed to getObjCClassByMangledName must either have a standard mangled name prefix, start with a digit (for unprefixed mangled names) or use the convenience dot syntax. Check for those up front and immediately reject anything else. This has the added bonus of failing more quickly for non-Swift names. rdar://93863030 (cherry picked from commit 8f072d1c2919c82d839425135f26e842e1ac976b) --- stdlib/public/runtime/Heap.cpp | 27 ------------------------ stdlib/public/runtime/MetadataLookup.cpp | 24 ++++++++++++++++++--- 2 files changed, 21 insertions(+), 30 deletions(-) diff --git a/stdlib/public/runtime/Heap.cpp b/stdlib/public/runtime/Heap.cpp index 9ce3647517d3e..57a4a79aee072 100644 --- a/stdlib/public/runtime/Heap.cpp +++ b/stdlib/public/runtime/Heap.cpp @@ -134,30 +134,3 @@ static void swift_slowDeallocImpl(void *ptr, size_t alignMask) { void swift::swift_slowDealloc(void *ptr, size_t bytes, size_t alignMask) { swift_slowDeallocImpl(ptr, alignMask); } - -#if defined(__APPLE__) && defined(__MACH__) && SWIFT_STDLIB_HAS_DARWIN_LIBMALLOC -// On Darwin, define our own, hidden operator new/delete implementations. We -// don't want to pick up any overrides that come from other code, but we also -// don't want to expose our overrides to any other code. We can't do this -// directly in C++, as the compiler has an implicit prototype with default -// visibility. However, if we implement them as C functions using the C++ -// mangled names, the compiler accepts them without complaint, and the linker -// still links all internal uses with these overrides. - -__attribute__((visibility(("hidden")))) extern "C" void *_Znwm(size_t size) { - return swift_slowAlloc(size, MALLOC_ALIGN_MASK); -} - -__attribute__((visibility(("hidden")))) extern "C" void _ZdlPv(void *ptr) { - swift_slowDeallocImpl(ptr, MALLOC_ALIGN_MASK); -} - -__attribute__((visibility(("hidden")))) extern "C" void *_Znam(size_t size) { - return swift_slowAlloc(size, MALLOC_ALIGN_MASK); -} - -__attribute__((visibility(("hidden")))) extern "C" void _ZdaPv(void *ptr) { - swift_slowDeallocImpl(ptr, MALLOC_ALIGN_MASK); -} - -#endif diff --git a/stdlib/public/runtime/MetadataLookup.cpp b/stdlib/public/runtime/MetadataLookup.cpp index fd8557e7e1692..1a853004e4a17 100644 --- a/stdlib/public/runtime/MetadataLookup.cpp +++ b/stdlib/public/runtime/MetadataLookup.cpp @@ -1919,7 +1919,7 @@ swift_stdlib_getTypeByMangledNameUntrusted(const char *typeNameStart, if (c >= '\x01' && c <= '\x1F') return nullptr; } - + return swift_getTypeByMangledName(MetadataState::Complete, typeName, nullptr, {}, {}).getType().getMetadata(); } @@ -2186,6 +2186,23 @@ swift_getOpaqueTypeConformance(const void * const *arguments, // Return the ObjC class for the given type name. // This gets installed as a callback from libobjc. +static bool validateObjCMangledName(const char *_Nonnull typeName) { + // Accept names with a mangling prefix. + if (getManglingPrefixLength(typeName)) + return true; + + // Accept names that start with a digit (unprefixed mangled names). + if (isdigit(typeName[0])) + return true; + + // Accept names that contain a dot. + if (strchr(typeName, '.')) + return true; + + // Reject anything else. + return false; +} + // FIXME: delete this #if and dlsym once we don't // need to build with older libobjc headers #if !OBJC_GETCLASSHOOK_DEFINED @@ -2221,8 +2238,9 @@ getObjCClassByMangledName(const char * _Nonnull typeName, [&](const Metadata *type, unsigned index) { return nullptr; } ).getType().getMetadata(); } else { - metadata = swift_stdlib_getTypeByMangledNameUntrusted(typeStr.data(), - typeStr.size()); + if (validateObjCMangledName(typeName)) + metadata = swift_stdlib_getTypeByMangledNameUntrusted(typeStr.data(), + typeStr.size()); } if (metadata) { auto objcClass =