Skip to content

Commit a11b3ce

Browse files
Fix use-after-free crash risk in screenshot haptic feedback
Found by an automated audit pass. UIImageWriteToSavedPhotosAlbum was passed feedback via a plain __bridge cast, which doesn't transfer ownership -- the local UINotificationFeedbackGenerator had nothing else retaining it, so ARC could deallocate it before the async save actually completed. screenshot:didFinishSavingWithError:contextInfo: would then read a dangling pointer out of contextInfo on every real screenshot. Switched to __bridge_retained on the write side and __bridge_transfer on the completion side so ownership is actually held across the async gap and released exactly once.
1 parent 9d225fa commit a11b3ce

1 file changed

Lines changed: 7 additions & 2 deletions

File tree

Source/iOS/App/DolphiniOS/UI/Emulation/EmulationiOSViewController.mm

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -427,12 +427,17 @@ - (void)takeScreenshot {
427427
return;
428428
}
429429

430-
UIImageWriteToSavedPhotosAlbum(image, self, @selector(screenshot:didFinishSavingWithError:contextInfo:), (__bridge void*)feedback);
430+
// __bridge_retained: feedback is a local with nothing else holding it past this block's
431+
// scope. A plain __bridge here would let ARC deallocate it before the async save actually
432+
// completes, leaving screenshot:didFinishSavingWithError:contextInfo: reading a dangling
433+
// pointer out of contextInfo (real use-after-free, not theoretical -- this fires on every
434+
// screenshot). __bridge_transfer below hands ownership back and releases it.
435+
UIImageWriteToSavedPhotosAlbum(image, self, @selector(screenshot:didFinishSavingWithError:contextInfo:), (__bridge_retained void*)feedback);
431436
}];
432437
}
433438

434439
- (void)screenshot:(UIImage*)image didFinishSavingWithError:(NSError* _Nullable)error contextInfo:(void*)contextInfo {
435-
UINotificationFeedbackGenerator* feedback = (__bridge UINotificationFeedbackGenerator*)contextInfo;
440+
UINotificationFeedbackGenerator* feedback = (__bridge_transfer UINotificationFeedbackGenerator*)contextInfo;
436441

437442
[feedback notificationOccurred:error == nil ? UINotificationFeedbackTypeSuccess : UINotificationFeedbackTypeError];
438443
}

0 commit comments

Comments
 (0)