[5.7][Runtime] Fix rare crash when fixing up dynamic subclasses. #60245
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Cherry-pick #60236 to
release/5.7
.Swift vtables can contain NULL entries. This happens when the compiler is able to prove that a method is never called.
When ptrauth is enabled, those NULL entries are still signed. However, there's an inconsistency in the runtime. Most places where we copy a vtable with swift_ptrauth_copy_code_or_data, we accept an unsigned NULL value. But when fixing up a dynamic ObjC subclass with swift_objc_classCopyFixupHandler, we don't.
Since the compiler seems to always sign these NULL values, this still works, except in the case where a signed NULL value coincidentally has a ptrauth signature of all zeroes. When that happens, the code to accept an unsigned NULL value sees this NULL with an all-zero signature as an unsigned NULL, and copies it verbatim. Then we really do have an unsigned NULL in the destination.
If that class is then dynamically subclassed, we'll call swift_objc_classCopyFixupHandler which does not accept unsigned NULL values, and fail ptrauth.
Adjust swift_objc_classCopyFixupHandler to accept unsigned NULL like the rest. These entries should never be called, and any attempt to call them will crash regardless, so it makes little difference.
rdar://92800322