← All issues

[26] WKDateTimePicker SetForScope writes to freed self

Severity: Medium | Component: WebKit UIProcess iOS forms | 7b904b1

Medium severity로 분류됩니다. diff는 UI process 내의 UAF를 수정합니다. [_datePickerController dismissViewControllerAnimated:NO completion:nil] 호출 도중 runloop 작업이 재진입하면서 WKDateTimePicker에 대한 마지막 reference가 해제됩니다. 이때 _isDismissingDatePicker에 바인딩된 SetForScope RAII guard가 self보다 오래 살아남아, scope 종료 시점에 이미 해제된 메모리에 NO를 기록했습니다.

Source/WebKit/UIProcess/ios/forms/WKDateTimeInputControl.mm

- (void)removeDatePickerPresentation
{
if (_datePickerController) {
if (!_isDismissingDatePicker) {
SetForScope isDismissingDatePicker { _isDismissingDatePicker, YES };
- [_datePickerController dismissViewControllerAnimated:NO completion:nil];
+ [protect(_datePickerController) dismissViewControllerAnimated:NO completion:nil];
}
_datePickerController = nil;
}
}

Objective-C re-entrancy 경계에서 RAII scope-guard가 enclosing 객체보다 오래 살아남아 발생하는 use-after-free.

총 세 곳의 호출 지점이 수정되었습니다. removeDatePickerPresentation 외에, WKFormPeripheralBasebeginEditing/endEditing(controlBeginEditing/controlEndEditing 패턴)도 동일하게 처리되었습니다. 한편 WKDatePickerPopoverController.mm에서도 같은 방식으로 __weak _delegate를 보호합니다.

인스턴스 멤버에 바인딩된 RAII scope guard는 Objective-C++에서 조용히 반복되는 함정입니다. C++는 RAII 소멸 순서를 강제하지만, Objective-C reference counting은 동기 메서드 호출에 걸친 receiver를 보호하지 않습니다. 결과적으로, UIKit, delegate, 또는 callback이 있는 API를 호출하는 메서드 내부에서 SetForScope { self->_member, ... } 패턴을 사용하면, receiver가 별도로 retain되지 않는 한 잠재적인 UAF 상태가 됩니다.

이 vulnerability는 UI process 내부의 memory safety를 약화시킵니다. UI process는 WebContent보다 높은 권한을 가지며, renderer sandbox 외부에서 실행됩니다.