Bug 160234

Summary: Check if NSURLAuthenticationChallengeSender has implemented optional methods before calling them
Product: WebKit Reporter: Alex Christensen <achristensen>
Component: New BugsAssignee: Alex Christensen <achristensen>
Status: RESOLVED FIXED    
Severity: Normal CC: ap, beidson, bfulgham, cdumez, commit-queue, ddkilzer, ggaren, jer.noble, jonlee, pvollan, webkit-bug-importer
Priority: P2 Keywords: InRadar
Version: WebKit Nightly Build   
Hardware: Unspecified   
OS: Unspecified   
See Also: https://bugs.webkit.org/show_bug.cgi?id=156947
Attachments:
Description Flags
Patch
none
Patch
none
Patch
none
Patch
none
Patch
none
Patch
none
Patch none

Alex Christensen
Reported 2016-07-26 23:20:42 PDT
Check if NSURLAuthenticationChallengeSender has implemented optional methods before calling them
Attachments
Patch (3.34 KB, patch)
2016-07-26 23:32 PDT, Alex Christensen
no flags
Patch (8.24 KB, patch)
2016-07-26 23:58 PDT, Alex Christensen
no flags
Patch (8.23 KB, patch)
2016-07-27 00:32 PDT, Alex Christensen
no flags
Patch (3.19 KB, patch)
2017-10-24 16:27 PDT, Per Arne Vollan
no flags
Patch (7.10 KB, patch)
2017-10-25 08:44 PDT, Per Arne Vollan
no flags
Patch (7.29 KB, patch)
2017-10-25 09:55 PDT, Per Arne Vollan
no flags
Patch (7.32 KB, patch)
2017-10-25 10:49 PDT, Per Arne Vollan
no flags
Alex Christensen
Comment 1 2016-07-26 23:32:32 PDT
Alex Christensen
Comment 2 2016-07-26 23:58:56 PDT
Alex Christensen
Comment 3 2016-07-27 00:32:02 PDT
Alexey Proskuryakov
Comment 4 2016-07-27 09:03:36 PDT
Comment on attachment 284678 [details] Patch View in context: https://bugs.webkit.org/attachment.cgi?id=284678&action=review > Source/WebCore/ChangeLog:12 > + This is clear from the stack traces in the radars and the fact that only the two optional methods are causing crashes. Wasn't that WebCore challenge sender, which you already fixed?
Alexey Proskuryakov
Comment 5 2016-07-27 09:06:18 PDT
Comment on attachment 284678 [details] Patch View in context: https://bugs.webkit.org/attachment.cgi?id=284678&action=review > Source/WebCore/ChangeLog:16 > + If something is exploitable, then it does not become more exploitable with this check. This is a strong statement when dealing with an impossible situation.
Alexey Proskuryakov
Comment 6 2016-07-27 16:13:52 PDT
Comment on attachment 284678 [details] Patch Clearing review flag, as this doesn't seem needed at this time.
David Kilzer (:ddkilzer)
Comment 7 2016-07-27 16:44:12 PDT
Comment on attachment 284678 [details] Patch View in context: https://bugs.webkit.org/attachment.cgi?id=284678&action=review >> Source/WebCore/ChangeLog:12 >> + This is clear from the stack traces in the radars and the fact that only the two optional methods are causing crashes. > > Wasn't that WebCore challenge sender, which you already fixed? How do you know that WebCoreAuthenticationClientAsChallengeSender is the only type of object used in this code path? The NSProtocol definition of NSURLAuthenticationChallengeSender states that the following methods are optional: - performDefaultHandlingForAuthenticationChallenge: - rejectProtectionSpaceAndContinueWithChallenge: <https://developer.apple.com/library/mac/documentation/Cocoa/Reference/Foundation/Protocols/NSURLAuthenticationChallengeSender_Protocol/> I don't understand the logic in assuming these optional methods always exist on whatever object is passed into this method unless it's provable that it's always a WebCoreAuthenticationClientAsChallengeSender object. >> Source/WebCore/ChangeLog:16 >> + If something is exploitable, then it does not become more exploitable with this check. > > This is a strong statement when dealing with an impossible situation. NOTE: This statement assumes that the only type of object ever passed into this method is a WebCoreAuthenticationClientAsChallengeSender created by WebCore.
Alexey Proskuryakov
Comment 8 2016-07-27 16:50:00 PDT
> The NSProtocol definition of NSURLAuthenticationChallengeSender states that the following methods are optional: We are not allowing arbitrary NSURLAuthenticationChallengeSenders here, so it is not relevant whether these methods are marked as optional in the protocol.
David Kilzer (:ddkilzer)
Comment 9 2016-10-28 11:31:05 PDT
David Kilzer (:ddkilzer)
Comment 10 2016-10-28 11:36:34 PDT
Comment on attachment 284678 [details] Patch r-, but only because I think we need to add logging for the type of object being used that doesn't respond to each of the selectors. Then this patch will prevent crashes due to unimplemented selectors, and when unexpected authentication failures occur (as Alex notes in the ChangeLog), we'll capture what type of object is being used with a sysdiagnose.
David Kilzer (:ddkilzer)
Comment 11 2016-10-28 11:38:32 PDT
(In reply to comment #8) > > The NSProtocol definition of NSURLAuthenticationChallengeSender states that the following methods are optional: > > We are not allowing arbitrary NSURLAuthenticationChallengeSenders here, so > it is not relevant whether these methods are marked as optional in the > protocol. The crashes are still occurring in iOS 10.x, so it seems like being defensive (plus logging to determine what the type of the failing objects is) would be a good path forward here.
Alexey Proskuryakov
Comment 12 2016-10-28 13:27:12 PDT
Is there some other defensive fix? I think that discussing the latest attached patch takes us further away from addressing the problem.
David Kilzer (:ddkilzer)
Comment 13 2016-10-28 16:25:17 PDT
(In reply to comment #12) > Is there some other defensive fix? I don't know of one. Do you have any? I feel you're blocking > I think that discussing the latest > attached patch takes us further away from addressing the problem. I think the latest patch would fix the crash, and with the additional logging then any user-visible side-effect would be obvious and more easily fixed. As it stands, we have no known individual bug reports about this crash.
David Kilzer (:ddkilzer)
Comment 14 2016-10-28 16:29:04 PDT
(In reply to comment #13) > (In reply to comment #12) > > Is there some other defensive fix? > > I don't know of one. Do you have any? I feel you're blocking ...progress on fixing this crash without having a specific direction in mind. I agree that this patch avoids the crash and doesn't address the root cause, but I also feel that not crashing is better than crashing in this case. Do you feel that it's still better to crash in this case?
David Kilzer (:ddkilzer)
Comment 15 2016-10-28 16:40:50 PDT
(In reply to comment #14) > (In reply to comment #13) > > (In reply to comment #12) > > > Is there some other defensive fix? > > > > I don't know of one. Do you have any? I feel you're blocking > > ...progress on fixing this crash without having a specific direction in mind. > > I agree that this patch avoids the crash and doesn't address the root cause, > but I also feel that not crashing is better than crashing in this case. > > Do you feel that it's still better to crash in this case? Just found some internal crashes that include the class name! Taking discussion to <rdar://problem/27439617>.
Alexey Proskuryakov
Comment 16 2016-10-28 18:53:09 PDT
I'm glad that I was blocking the patch :)
Brent Fulgham
Comment 17 2017-01-17 11:30:26 PST
Comment on attachment 284678 [details] Patch View in context: https://bugs.webkit.org/attachment.cgi?id=284678&action=review >>> Source/WebCore/ChangeLog:12 >>> + This is clear from the stack traces in the radars and the fact that only the two optional methods are causing crashes. >> >> Wasn't that WebCore challenge sender, which you already fixed? > > How do you know that WebCoreAuthenticationClientAsChallengeSender is the only type of object used in this code path? > > The NSProtocol definition of NSURLAuthenticationChallengeSender states that the following methods are optional: > > - performDefaultHandlingForAuthenticationChallenge: > - rejectProtectionSpaceAndContinueWithChallenge: > > <https://developer.apple.com/library/mac/documentation/Cocoa/Reference/Foundation/Protocols/NSURLAuthenticationChallengeSender_Protocol/> > > I don't understand the logic in assuming these optional methods always exist on whatever object is passed into this method unless it's provable that it's always a WebCoreAuthenticationClientAsChallengeSender object. Since the two methods are not required, there is probably nothing in Xcode that notifies developers that their sender object is missing these delegate methods. Given that these are documented to be optional, it really seems correct that the changes in ResourceHandleMac.mm and AuthenticationManagerCocoa.mm are NEEDED.
Alexey Proskuryakov
Comment 18 2017-01-17 11:52:25 PST
Brent, I don't think that this is the case. 3rd party clients don't have a way to run custom code in the Networking process, so they can't introduce delegates that don't implement these methods.
Alexey Proskuryakov
Comment 19 2017-02-07 15:12:59 PST
Hopefully obsoleted by the fix in bug 167951.
Alex Christensen
Comment 20 2017-06-14 10:48:09 PDT
*** Bug 173372 has been marked as a duplicate of this bug. ***
Jon Lee
Comment 21 2017-06-15 14:14:58 PDT
Chris Dumez
Comment 22 2017-07-17 13:14:28 PDT
Comment on attachment 284678 [details] Patch View in context: https://bugs.webkit.org/attachment.cgi?id=284678&action=review >>>> Source/WebCore/ChangeLog:12 >>>> + This is clear from the stack traces in the radars and the fact that only the two optional methods are causing crashes. >>> >>> Wasn't that WebCore challenge sender, which you already fixed? >> >> How do you know that WebCoreAuthenticationClientAsChallengeSender is the only type of object used in this code path? >> >> The NSProtocol definition of NSURLAuthenticationChallengeSender states that the following methods are optional: >> >> - performDefaultHandlingForAuthenticationChallenge: >> - rejectProtectionSpaceAndContinueWithChallenge: >> >> <https://developer.apple.com/library/mac/documentation/Cocoa/Reference/Foundation/Protocols/NSURLAuthenticationChallengeSender_Protocol/> >> >> I don't understand the logic in assuming these optional methods always exist on whatever object is passed into this method unless it's provable that it's always a WebCoreAuthenticationClientAsChallengeSender object. > > Since the two methods are not required, there is probably nothing in Xcode that notifies developers that their sender object is missing these delegate methods. > > Given that these are documented to be optional, it really seems correct that the changes in ResourceHandleMac.mm and AuthenticationManagerCocoa.mm are NEEDED. Even if the ChallengeSender was WebCoreAuthenticationClientAsChallengeSender, as far as I can tell, the implementation of [WebCoreAuthenticationClientAsChallengeSender rejectProtectionSpaceAndContinueWithChallenge] ends up calling AuthenticationClient::receivedChallengeRejection(). The AuthenticationClient I believe is the ResourceHandle. On Cocoa, ResourceHandle::receivedChallengeRejection() ends up calling: [[d->m_currentMacChallenge sender] rejectProtectionSpaceAndContinueWithChallenge:d->m_currentMacChallenge]; It looks to me we are merely proxying to CFNetwork, no? And rejectProtectionSpaceAndContinueWithChallenge is unimplemented in CFNetwork.
Chris Dumez
Comment 23 2017-07-17 13:33:10 PDT
Comment on attachment 284678 [details] Patch View in context: https://bugs.webkit.org/attachment.cgi?id=284678&action=review >>>>> Source/WebCore/ChangeLog:12 >>>>> + This is clear from the stack traces in the radars and the fact that only the two optional methods are causing crashes. >>>> >>>> Wasn't that WebCore challenge sender, which you already fixed? >>> >>> How do you know that WebCoreAuthenticationClientAsChallengeSender is the only type of object used in this code path? >>> >>> The NSProtocol definition of NSURLAuthenticationChallengeSender states that the following methods are optional: >>> >>> - performDefaultHandlingForAuthenticationChallenge: >>> - rejectProtectionSpaceAndContinueWithChallenge: >>> >>> <https://developer.apple.com/library/mac/documentation/Cocoa/Reference/Foundation/Protocols/NSURLAuthenticationChallengeSender_Protocol/> >>> >>> I don't understand the logic in assuming these optional methods always exist on whatever object is passed into this method unless it's provable that it's always a WebCoreAuthenticationClientAsChallengeSender object. >> >> Since the two methods are not required, there is probably nothing in Xcode that notifies developers that their sender object is missing these delegate methods. >> >> Given that these are documented to be optional, it really seems correct that the changes in ResourceHandleMac.mm and AuthenticationManagerCocoa.mm are NEEDED. > > Even if the ChallengeSender was WebCoreAuthenticationClientAsChallengeSender, as far as I can tell, the implementation of [WebCoreAuthenticationClientAsChallengeSender rejectProtectionSpaceAndContinueWithChallenge] ends up calling AuthenticationClient::receivedChallengeRejection(). The AuthenticationClient I believe is the ResourceHandle. On Cocoa, ResourceHandle::receivedChallengeRejection() ends up calling: > [[d->m_currentMacChallenge sender] rejectProtectionSpaceAndContinueWithChallenge:d->m_currentMacChallenge]; > > It looks to me we are merely proxying to CFNetwork, no? And rejectProtectionSpaceAndContinueWithChallenge is unimplemented in CFNetwork. Actually, WebCoreAuthenticationClientAsChallengeSender is not used at all in the WebKit2 with NETWORK_SESSION enabled case.
Geoffrey Garen
Comment 24 2017-10-24 14:27:10 PDT
We have an explanation for how we can end up with an NSURLAuthenticationChallengeSender that is not WebCoreAuthenticationClientAsChallengeSender: AVFoundation can supply its own challenge and sender. For example, we see in MediaPlayerPrivateAVFoundationObjC::shouldWaitForResponseToAuthenticationChallenge that AVFoundation provides its own NSURLAuthenticationChallenge.
Per Arne Vollan
Comment 25 2017-10-24 16:27:52 PDT
Per Arne Vollan
Comment 26 2017-10-24 16:30:47 PDT
(In reply to Per Arne Vollan from comment #25) > Created attachment 324749 [details] > Patch This is basically just a rebase of Alex's original patch, without the parts of it that are not strictly needed.
Alexey Proskuryakov
Comment 27 2017-10-24 23:50:10 PDT
> For example, we see in MediaPlayerPrivateAVFoundationObjC::shouldWaitForResponseToAuthenticationChallenge that AVFoundation provides its own NSURLAuthenticationChallenge. Isn't that in the WebContent process? How does that explain Networking process crashes?
Alexey Proskuryakov
Comment 28 2017-10-24 23:52:24 PDT
Comment on attachment 324749 [details] Patch From previous discussions with Alex, I thought that we had a different plan of attack, what changed? In particular, it's not only wrong to call these methods, it's wrong to call any methods on the sender object.
Per Arne Vollan
Comment 29 2017-10-25 08:44:25 PDT
Per Arne Vollan
Comment 30 2017-10-25 08:54:53 PDT
(In reply to Alexey Proskuryakov from comment #28) > Comment on attachment 324749 [details] > Patch > > From previous discussions with Alex, I thought that we had a different plan > of attack, what changed? > > In particular, it's not only wrong to call these methods, it's wrong to call > any methods on the sender object. I have uploaded a new patch, where no methods are called on the authentication challenge sender when network session is used. In the USE(NETWORK_SESSION) case, I believe we never need to call methods on the challenge sender, since the challenge sender in the network process will always be the internal CFNetwork challenge sender. The challenge sender is deprecated when network session is used, and only contains empty implementations, and also does not implement all methods. Is this a correct assumption? Thanks for reviewing!
Brent Fulgham
Comment 31 2017-10-25 08:57:07 PDT
Comment on attachment 324826 [details] Patch View in context: https://bugs.webkit.org/attachment.cgi?id=324826&action=review > Source/WebKit/ChangeLog:3 > + Check if NSURLAuthenticationChallengeSender has implemented optional methods before calling them We should probably change this title, as the focus of the change has shifted.
Per Arne Vollan
Comment 32 2017-10-25 09:55:52 PDT
Brent Fulgham
Comment 33 2017-10-25 10:10:17 PDT
Comment on attachment 324836 [details] Patch View in context: https://bugs.webkit.org/attachment.cgi?id=324836&action=review > Source/WebKit/ChangeLog:4 > + https://bugs.webkit.org/show_bug.cgi?id=160234 Please include the relevant <rdar> here as well. > Source/WebKit/ChangeLog:9 > + challenge sender, which has not implemented the optional method. The methods on the authentication challenge which DOES NOT implement THIS optional method. > Source/WebKit/ChangeLog:10 > + sender has been deprecated when network session is used, so we should not call them in that case. sender ARE deprecated when ....
Geoffrey Garen
Comment 34 2017-10-25 10:13:46 PDT
Are we still surprised to receive a CFNetwork challenge sender, and do we still believe that might indicate a bug? If so, we can also add an internal-build-only RELEASE_ASSERT at the point we first encounter a challenge to assert that it has the type we expect. That will give us backtraces to explain where these surprising challenges come from.
Per Arne Vollan
Comment 35 2017-10-25 10:49:21 PDT
Per Arne Vollan
Comment 36 2017-10-25 10:50:56 PDT
(In reply to Brent Fulgham from comment #33) > Comment on attachment 324836 [details] > Patch > > View in context: > https://bugs.webkit.org/attachment.cgi?id=324836&action=review > > > Source/WebKit/ChangeLog:4 > > + https://bugs.webkit.org/show_bug.cgi?id=160234 > > Please include the relevant <rdar> here as well. > > > Source/WebKit/ChangeLog:9 > > + challenge sender, which has not implemented the optional method. The methods on the authentication challenge > > which DOES NOT implement THIS optional method. > > > Source/WebKit/ChangeLog:10 > > + sender has been deprecated when network session is used, so we should not call them in that case. > > sender ARE deprecated when .... Updated. Thanks for reviewing!
Per Arne Vollan
Comment 37 2017-10-25 10:56:05 PDT
(In reply to Geoffrey Garen from comment #34) > Are we still surprised to receive a CFNetwork challenge sender, and do we > still believe that might indicate a bug? > > If so, we can also add an internal-build-only RELEASE_ASSERT at the point we > first encounter a challenge to assert that it has the type we expect. That > will give us backtraces to explain where these surprising challenges come > from. No, I believe we always should receive a CFNetwork challenge sender in the network process in the USE(NETWORK_SESSION) case. This patch is based on that assumption. If that assumption is incorrect, then this patch is incorrect. What is surprising is that both the completion handler and the authentication client is null, which makes us fall through to the place where we call the unimplemented method on the CFNetwork challenge sender. I can replace the ASSERTS in the current patch with RELEASE_ASSERTs for internal builds. Thanks for reviewing!
Per Arne Vollan
Comment 38 2017-10-25 11:34:09 PDT
(In reply to Geoffrey Garen from comment #34) > Are we still surprised to receive a CFNetwork challenge sender, and do we > still believe that might indicate a bug? > > If so, we can also add an internal-build-only RELEASE_ASSERT at the point we > first encounter a challenge to assert that it has the type we expect. That > will give us backtraces to explain where these surprising challenges come > from. I can't seem to find any examples of RELEASE_ASSERTs for internal builds only, how would you do this?
Geoffrey Garen
Comment 39 2017-10-25 11:49:30 PDT
> I can't seem to find any examples of RELEASE_ASSERTs for internal builds > only, how would you do this? The best way to write internal-only behavior is to use <os/variant_private.h>. I believe the right check in this case would be os_variant_has_internal_diagnostics. That said, it sounds like your analysis is that a CFNetwork challenge sender is expected, and we were just handling it incorrectly before. So, an internal-only assert for the sake of investigation may not be necessary.
Alexey Proskuryakov
Comment 40 2017-10-25 13:33:59 PDT
Here is my current understanding after talking to Alex. This code should not be reachable at all on modern OS versions. As Per Arne said above, we get here because both completion handler and authentication handler are null. A couple ways that could happen are: - bookkeeping problems in our networking code, so we lose track of the completion handler too early; - incomplete/unexpected messages coming from media code in WebContent (but again, that shouldn't be happening in modern OS versions).
Geoffrey Garen
Comment 41 2017-10-25 15:48:55 PDT
It looks like we encountered a very similar problem before, and tried to work around its low-level consequences. See <https://trac.webkit.org/changeset/197865/webkit>.
Geoffrey Garen
Comment 42 2017-10-25 15:52:38 PDT
> It looks like we encountered a very similar problem before, and tried to > work around its low-level consequences. See > <https://trac.webkit.org/changeset/197865/webkit>. The central trigger point for this kind of bug might be NetworkDataTaskCocoa::didReceiveChallenge.
Geoffrey Garen
Comment 43 2017-10-25 15:57:13 PDT
Comment on attachment 324849 [details] Patch r=me I think this is an improvement because it clarifies that NETWORK_SESSION code is never supposed to invoke the deprecated default... selector, and it removes the crash from customer builds. To continue investigating the mystery of why we end up with an authentication challenge that has no client or completion handler, I'd suggest adding code like this to NetworkDataTaskCocoa::didReceiveChallenge: if (internal_build()) RELEASE_ASSERT_NOT_REACHED(); else ASSERT_NOT_REACHED(); If we discover that we use this kind of technique more often, consider making a shared macro in Assertions.h that encapsulates this behavior.
Per Arne Vollan
Comment 44 2017-10-25 16:01:25 PDT
(In reply to Geoffrey Garen from comment #43) > Comment on attachment 324849 [details] > Patch > > r=me > > I think this is an improvement because it clarifies that NETWORK_SESSION > code is never supposed to invoke the deprecated default... selector, and it > removes the crash from customer builds. > > To continue investigating the mystery of why we end up with an > authentication challenge that has no client or completion handler, I'd > suggest adding code like this to NetworkDataTaskCocoa::didReceiveChallenge: > > if (internal_build()) > RELEASE_ASSERT_NOT_REACHED(); > else > ASSERT_NOT_REACHED(); > > If we discover that we use this kind of technique more often, consider > making a shared macro in Assertions.h that encapsulates this behavior. I'll create a separate patch for this. Thanks for reviewing!
WebKit Commit Bot
Comment 45 2017-10-25 16:24:18 PDT
Comment on attachment 324849 [details] Patch Clearing flags on attachment: 324849 Committed r223993: <https://trac.webkit.org/changeset/223993>
WebKit Commit Bot
Comment 46 2017-10-25 16:24:20 PDT
All reviewed patches have been landed. Closing bug.
Note You need to log in before you can comment on or make changes to this bug.