Skip to content

Runtime: Only demangle symbolic references in constant memory. #17405

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jun 25, 2018
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 31 additions & 2 deletions stdlib/public/runtime/MetadataLookup.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,29 @@ using namespace reflection;
#include <objc/objc.h>
#endif

#if __has_include(<mach-o/dyld_priv.h>)
#include <mach-o/dyld_priv.h>
#define SWIFT_HAS_DYLD_IS_MEMORY_IMMUTABLE
#endif

/// If the target platform has an API for asking whether an address is mapped
/// from immutable pages of an executable image, this returns true if the
/// given address is *not* from an executable image. Otherwise, this always
/// returns false. The intent is to check that this returns false as a defense
/// for APIs that expect to operate on immutable memory to prevent them from
/// being fed untrusted data by an attacker, when the platform makes that
/// possible.
static bool isKnownToBeInMutableMemory(const void *base, size_t size) {
#if defined(SWIFT_HAS_DYLD_IS_MEMORY_IMMUTABLE)
if (__builtin_available(macOS 10.12, iOS 10.0, tvOS 10.0, watchOS 3.0, *))
return !_dyld_is_memory_immutable(base, size);
else
return false;
#else
return false;
#endif
}

/// Produce a Demangler value suitable for resolving runtime type metadata
/// strings.
static Demangler getDemanglerForRuntimeTypeResolution() {
Expand All @@ -55,8 +78,14 @@ static Demangler getDemanglerForRuntimeTypeResolution() {
// mangled name we can immediately find the associated metadata.
dem.setSymbolicReferenceResolver([&](int32_t offset,
const void *base) -> NodePointer {
auto absolute_addr = (uintptr_t)detail::applyRelativeOffset(base, offset);
auto reference = dem.createNode(Node::Kind::SymbolicReference, absolute_addr);
// Only read symbolic references out of constant memory.
if (isKnownToBeInMutableMemory(base, sizeof(int)))
return nullptr;

auto absolute_addr = detail::applyRelativeOffset(base, offset);

auto reference = dem.createNode(Node::Kind::SymbolicReference,
(uintptr_t)absolute_addr);
auto type = dem.createNode(Node::Kind::Type);
type->addChild(reference, dem);
return type;
Expand Down