mirror of
https://github.com/chromium/crashpad.git
synced 2025-03-09 14:06:33 +00:00
ios: Tighten up UIGestureEnvironment exception detection.
iOS 15.1 reordered private APIs before public APIs when looking at the unw_get_proc_info() frame_info.start_ip, so doing a min/max within UIGestureEnvironment would fail on devices. However, this API is always called by UIWindow sendEvent, which is not a private API. Do the same check, but instead look back 2 frames, and check to see if we are within UIWindow. Both APIs are still marked <redacted>, but the detection should still work. Also cleans up some tests fixtures when running in release. Change-Id: I762615e9cb44389800cf3291af52a7568c3825d5 Reviewed-on: https://chromium-review.googlesource.com/c/crashpad/crashpad/+/3299008 Reviewed-by: Mark Mentovai <mark@chromium.org> Commit-Queue: Justin Cohen <justincohen@chromium.org>
This commit is contained in:
parent
54f2581bf1
commit
c7ce2e3ec1
@ -403,20 +403,22 @@ id ObjcExceptionPreprocessor(id exception) {
|
||||
// internally and also has has non-sinkhole handlers. While all the
|
||||
// calling methods in UIKit are marked <redacted> starting in iOS14, it's
|
||||
// currently true that all callers to _UIGestureEnvironmentUpdate are within
|
||||
// UIGestureEnvironment. That means a very hacky way to detect this are to
|
||||
// check if the calling method IMP is within the range of all
|
||||
// UIGestureEnvironment methods.
|
||||
// UIWindow sendEvent -> UIGestureEnvironment. That means a very hacky way
|
||||
// to detect this is to check if the calling (2x) method IMP is within the
|
||||
// range of all UIWindow methods.
|
||||
static constexpr const char kUIKitCorePath[] =
|
||||
"/System/Library/PrivateFrameworks/UIKitCore.framework/UIKitCore";
|
||||
if (ModulePathMatchesSinkhole(dl_info.dli_fname, kUIKitCorePath)) {
|
||||
unw_proc_info_t caller_frame_info;
|
||||
if (LoggingUnwStep(&cursor) > 0 &&
|
||||
unw_get_proc_info(&cursor, &caller_frame_info) == UNW_ESUCCESS &&
|
||||
LoggingUnwStep(&cursor) > 0 &&
|
||||
unw_get_proc_info(&cursor, &caller_frame_info) == UNW_ESUCCESS) {
|
||||
auto uigestureimp_lambda = [](IMP* max) {
|
||||
auto uiwindowimp_lambda = [](IMP* max) {
|
||||
IMP min = *max = bit_cast<IMP>(nullptr);
|
||||
unsigned int method_count = 0;
|
||||
std::unique_ptr<Method[], base::FreeDeleter> method_list(
|
||||
class_copyMethodList(NSClassFromString(@"UIGestureEnvironment"),
|
||||
class_copyMethodList(NSClassFromString(@"UIWindow"),
|
||||
&method_count));
|
||||
if (method_count > 0) {
|
||||
min = *max = method_getImplementation(method_list[0]);
|
||||
@ -431,15 +433,14 @@ id ObjcExceptionPreprocessor(id exception) {
|
||||
return min;
|
||||
};
|
||||
|
||||
static IMP gesture_environment_max_imp;
|
||||
static IMP gesture_environment_min_imp =
|
||||
uigestureimp_lambda(&gesture_environment_max_imp);
|
||||
static IMP uiwindow_max_imp;
|
||||
static IMP uiwindow_min_imp = uiwindowimp_lambda(&uiwindow_max_imp);
|
||||
|
||||
if (gesture_environment_min_imp && gesture_environment_max_imp &&
|
||||
if (uiwindow_min_imp && uiwindow_max_imp &&
|
||||
caller_frame_info.start_ip >=
|
||||
reinterpret_cast<unw_word_t>(gesture_environment_min_imp) &&
|
||||
reinterpret_cast<unw_word_t>(uiwindow_min_imp) &&
|
||||
caller_frame_info.start_ip <=
|
||||
reinterpret_cast<unw_word_t>(gesture_environment_max_imp)) {
|
||||
reinterpret_cast<unw_word_t>(uiwindow_max_imp)) {
|
||||
return HANDLE_UNCAUGHT_NSEXCEPTION(exception,
|
||||
"_UIGestureEnvironmentUpdate");
|
||||
}
|
||||
|
@ -85,12 +85,8 @@
|
||||
|
||||
- (void)testSegv {
|
||||
[rootObject_ crashSegv];
|
||||
#if defined(NDEBUG)
|
||||
#if TARGET_OS_SIMULATOR
|
||||
#if defined(NDEBUG) && TARGET_OS_SIMULATOR
|
||||
[self verifyCrashReportException:SIGINT];
|
||||
#else
|
||||
[self verifyCrashReportException:SIGABRT];
|
||||
#endif
|
||||
#else
|
||||
[self verifyCrashReportException:SIGHUP];
|
||||
#endif
|
||||
@ -117,12 +113,8 @@
|
||||
|
||||
- (void)testBadAccess {
|
||||
[rootObject_ crashBadAccess];
|
||||
#if defined(NDEBUG)
|
||||
#if TARGET_OS_SIMULATOR
|
||||
#if defined(NDEBUG) && TARGET_OS_SIMULATOR
|
||||
[self verifyCrashReportException:SIGINT];
|
||||
#else
|
||||
[self verifyCrashReportException:SIGABRT];
|
||||
#endif
|
||||
#else
|
||||
[self verifyCrashReportException:SIGHUP];
|
||||
#endif
|
||||
@ -221,6 +213,7 @@
|
||||
XCTAssertTrue([dict[@"ver"] isEqualToString:@"42"]);
|
||||
}
|
||||
|
||||
#if TARGET_OS_SIMULATOR
|
||||
- (void)testCrashWithCrashInfoMessage {
|
||||
if (@available(iOS 15.0, *)) {
|
||||
// Figure out how to test this on iOS15.
|
||||
@ -232,9 +225,10 @@
|
||||
NSString* dyldMessage = dict[@"vector"][0];
|
||||
XCTAssertTrue([dyldMessage isEqualToString:@"dyld: in dlsym()"]);
|
||||
}
|
||||
#endif
|
||||
|
||||
// TODO(justincohen): Codesign crashy_initializer.so so it can run on devices.
|
||||
#if !TARGET_OS_SIMULATOR
|
||||
#if TARGET_OS_SIMULATOR
|
||||
- (void)testCrashWithDyldErrorString {
|
||||
if (@available(iOS 15.0, *)) {
|
||||
// iOS 15 uses dyld4, which doesn't use CRSetCrashLogMessage2
|
||||
|
Loading…
x
Reference in New Issue
Block a user