Safely copy MIMEType to prevent use after free (Issue #14734) #15313
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.
Copied response.MIMEType before assigning to responseContentType to avoid EXC_BAD_ACCESS caused by early deallocation under certain network or SDK conditions.
Discussion
Clients state that they where experiencing a crash in FPRNetworkTrace on devices running iOS and iPadOS 17.5.1 and up, its not a 100% reproducible crash but it seems to happen under certain network conditions
After I began to read the stack trace and logs I found out that the root cause is a use after bug that is triggered by accessing response.MIMEType from a possibly deallocated NSURLResponse object inside the didCompleteRequestWithResponse method located inside of FPRNetworkTrace.m
Where the crash happens on the user provided stack trace (EXC_BAD_ACCESS (SIGSEGV) type crash):
0 libsystem_malloc.dylib __CFStringDeallocate 1 CoreFoundation _CFRelease 2 CFNetwork URLResponse::getMIMEType() 3 FPRNetworkTrace didCompleteRequestWithResponse:error:The MIME type string returned by NSURLResponse.MIMEType is a non retained CoreFoundation owned pointer that may be deallocated if the NSURLResponse instance is no longer strongly referenced or becomes invalid if the delegate method is invoked on a separate queue after the response’s lifecycle ends, without retaining a response, this opens a race condition where response may be freed before MIMEType is accessed.
Possible repro scenarios (Hard to reproduce!!!)
Proposed Fix
My proposed fix consists of modifying the assignment of response.MIMEType in -didCompleteRequestWithResponse:error: to defensively copy the value, this will address the crash users had and adds an extra layer of safety when this value is being accessed, and it also doesn’t add or makes a behavioral change to the existing flow also under certain network conditions or when third-party SDKs like AppLovin hook into NSURLSession, the original NSURLResponse instance may be prematurely deallocated or altered, copying the MIME type ensures the string is retained independently on the heap, breaking potential races with early deallocation or thread-unsafe memory access.
Testing
Testing Screenshots
iPhone 14 Pro
iPhone SE 3rd Gen Simulator
API Changes