diff --git a/ios/chrome/browser/settings/ui_bundled/password/password_details/add_password_coordinator.mm b/ios/chrome/browser/settings/ui_bundled/password/password_details/add_password_coordinator.mm --- a/ios/chrome/browser/settings/ui_bundled/password/password_details/add_password_coordinator.mm +++ b/ios/chrome/browser/settings/ui_bundled/password/password_details/add_password_coordinator.mm @@ -129,6 +129,14 @@ #pragma mark - UIAdaptivePresentationControllerDelegate +- (BOOL)presentationControllerShouldDismiss: + (UIPresentationController*)presentationController { + // Block interactive swipe-to-dismiss while the blocking + // LocalReauthenticationViewController is on top of the nav stack, so a + // pending LAContext callback cannot be raced by a sheet dismissal. + return ![_reauthCoordinator isPresentingBlockingUI]; +} + - (void)presentationControllerDidDismiss: (UIPresentationController*)presentationController { [self.delegate passwordDetailsTableViewControllerDidFinish:self]; diff --git a/ios/chrome/browser/settings/ui_bundled/password/widget_promo_instructions/widget_promo_instructions_coordinator.mm b/ios/chrome/browser/settings/ui_bundled/password/widget_promo_instructions/widget_promo_instructions_coordinator.mm --- a/ios/chrome/browser/settings/ui_bundled/password/widget_promo_instructions/widget_promo_instructions_coordinator.mm +++ b/ios/chrome/browser/settings/ui_bundled/password/widget_promo_instructions/widget_promo_instructions_coordinator.mm @@ -74,6 +74,14 @@ #pragma mark - UIAdaptivePresentationControllerDelegate +- (BOOL)presentationControllerShouldDismiss: + (UIPresentationController*)presentationController { + // Block interactive swipe-to-dismiss while the blocking + // LocalReauthenticationViewController is on top of the nav stack, so a + // pending LAContext callback cannot be raced by a sheet dismissal. + return ![_reauthCoordinator isPresentingBlockingUI]; +} + - (void)presentationControllerDidDismiss: (UIPresentationController*)presentationController { [self.delegate removeWidgetPromoInstructionsCoordinator:self]; diff --git a/ios/chrome/browser/settings/ui_bundled/password/reauthentication/local_reauthentication_view_controller.mm b/ios/chrome/browser/settings/ui_bundled/password/reauthentication/local_reauthentication_view_controller.mm --- a/ios/chrome/browser/settings/ui_bundled/password/reauthentication/local_reauthentication_view_controller.mm +++ b/ios/chrome/browser/settings/ui_bundled/password/reauthentication/local_reauthentication_view_controller.mm @@ -30,6 +30,9 @@ _reauthModule = reauthenticationModule; _reauthUponPresentation = reauthUponPresentation; self.navigationItem.hidesBackButton = YES; + // Defense-in-depth: prevent the hosting modal sheet from being + // swipe-dismissed while this blocking VC is presented. + self.modalInPresentation = YES; // This view does not support large titles as it uses a custom title view. self.navigationItem.largeTitleDisplayMode =