Skip to content

Commit 3659ea7

Browse files
authored
Merge pull request #71076 from kubamracek/embedded-isa-signing
[embedded] Resolve ptrauth crashes by signing HeapObjects's isa pointers in embedded Swift
2 parents b4dbd97 + 2c30b0a commit 3659ea7

File tree

2 files changed

+24
-8
lines changed

2 files changed

+24
-8
lines changed

stdlib/public/SwiftShims/swift/shims/EmbeddedShims.h

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -43,16 +43,29 @@ extern "C" {
4343

4444
typedef void SWIFT_CC_swift (*HeapObjectDestroyer)(SWIFT_CONTEXT void *object);
4545

46-
static inline void _swift_embedded_invoke_heap_object_destroy(void *object) {
47-
void *metadata = *(void **)object;
46+
typedef struct EmbeddedHeapObject {
47+
#if __has_feature(ptrauth_calls)
48+
void * __ptrauth(2, 1, 0x6ae1) metadata;
49+
#else
50+
void *metadata;
51+
#endif
52+
} EmbeddedHeapObject;
53+
54+
static inline void
55+
_swift_embedded_invoke_heap_object_destroy(void *object) {
56+
void *metadata = ((EmbeddedHeapObject *)object)->metadata;
4857
void **destroy_location = &((void **)metadata)[1];
4958
#if __has_feature(ptrauth_calls)
50-
(*(HeapObjectDestroyer __ptrauth(0,1,0xbbbf) *)destroy_location)(object);
59+
(*(HeapObjectDestroyer __ptrauth(0, 1, 0xbbbf) *)destroy_location)(object);
5160
#else
5261
(*(HeapObjectDestroyer *)destroy_location)(object);
5362
#endif
5463
}
5564

65+
static inline void _swift_embedded_set_heap_object_metadata_pointer(void *object, void *metadata) {
66+
((EmbeddedHeapObject *)object)->metadata = metadata;
67+
}
68+
5669
#ifdef __cplusplus
5770
} // extern "C"
5871
#endif

stdlib/public/core/EmbeddedRuntime.swift

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,15 @@ public struct ClassMetadata {
1919

2020
// There is no way to express the actual calling convention on the heap desroy
2121
// function (swiftcc with 'self') currently, so let's use UnsafeRawPointer
22-
// and a helper function in C (_swift_runtime_invoke_heap_object_destroy).
22+
// and a helper function in C (_swift_embedded_invoke_heap_object_destroy).
2323
var destroy: UnsafeRawPointer
2424
}
2525

2626
public struct HeapObject {
27-
var metadata: UnsafeMutablePointer<ClassMetadata>
27+
// There is no way to express the custom ptrauth signature on the metadata
28+
// field, so let's use UnsafeRawPointer and a helper function in C instead
29+
// (_swift_embedded_set_heap_object_metadata_pointer).
30+
var metadata: UnsafeRawPointer
2831

2932
// TODO: This is just an initial support for strong refcounting only. We need
3033
// to think about supporting (or banning) weak and/or unowned references.
@@ -82,7 +85,7 @@ public func swift_slowDealloc(_ ptr: UnsafeMutableRawPointer, _ size: Int, _ ali
8285
public func swift_allocObject(metadata: UnsafeMutablePointer<ClassMetadata>, requiredSize: Int, requiredAlignmentMask: Int) -> UnsafeMutablePointer<HeapObject> {
8386
let p = swift_slowAlloc(requiredSize, requiredAlignmentMask)!
8487
let object = p.assumingMemoryBound(to: HeapObject.self)
85-
object.pointee.metadata = metadata
88+
_swift_embedded_set_heap_object_metadata_pointer(object, metadata)
8689
object.pointee.refcount = 1
8790
return object
8891
}
@@ -103,14 +106,14 @@ public func swift_deallocClassInstance(object: UnsafeMutablePointer<HeapObject>,
103106

104107
@_silgen_name("swift_initStaticObject")
105108
public func swift_initStaticObject(metadata: UnsafeMutablePointer<ClassMetadata>, object: UnsafeMutablePointer<HeapObject>) -> UnsafeMutablePointer<HeapObject> {
106-
object.pointee.metadata = metadata
109+
_swift_embedded_set_heap_object_metadata_pointer(object, metadata)
107110
object.pointee.refcount = HeapObject.immortalRefCount
108111
return object
109112
}
110113

111114
@_silgen_name("swift_initStackObject")
112115
public func swift_initStackObject(metadata: UnsafeMutablePointer<ClassMetadata>, object: UnsafeMutablePointer<HeapObject>) -> UnsafeMutablePointer<HeapObject> {
113-
object.pointee.metadata = metadata
116+
_swift_embedded_set_heap_object_metadata_pointer(object, metadata)
114117
object.pointee.refcount = 1 | HeapObject.doNotFreeBit
115118
return object
116119
}

0 commit comments

Comments
 (0)