Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
REGRESSION (PSON): Can't access optumbank.com from myuhc.com
https://bugs.webkit.org/show_bug.cgi?id=194797
<rdar://problem/48055151>

Reviewed by Geoffrey Garen.

Source/WebKit:

The issue was caused by us mistakenly process-swapping for a same-site server side redirect.
The reason we were getting it wrong is because the logic in
WebProcessPool::processForNavigationInternal() was expecting page.process() to be the source
process and page.pageLoadState().url() to be the source URL. Those assumptions are incorrect
when a server-side redirect occurs in a provisional process. In such case, the source process
is the ProvisionalPageProxy's process and the source URL is the provisional URL, not the
committed one.

* UIProcess/ProvisionalPageProxy.cpp:
(WebKit::ProvisionalPageProxy::didPerformServerRedirect):
(WebKit::ProvisionalPageProxy::didReceiveServerRedirectForProvisionalLoadForFrame):
(WebKit::ProvisionalPageProxy::didReceiveMessage):
* UIProcess/ProvisionalPageProxy.h:
Make sure the provisional page forwards IPC related to server-side redirects to the page so
that the client gets informed.

* UIProcess/WebPageProxy.cpp:
(WebKit::WebPageProxy::receivedNavigationPolicyDecision):
(WebKit::WebPageProxy::didPerformServerRedirect):
(WebKit::WebPageProxy::didPerformServerRedirectShared):
* UIProcess/WebPageProxy.h:
* UIProcess/WebProcessPool.cpp:
(WebKit::WebProcessPool::processForNavigation):
(WebKit::WebProcessPool::processForNavigationInternal):
* UIProcess/WebProcessPool.h:

Tools:

Add API test coverage.

* TestWebKitAPI/Tests/WebKitCocoa/ProcessSwapOnNavigation.mm:


Canonical link: https://commits.webkit.org/209183@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@241752 268f45cc-cd09-0410-ab3c-d52691b4dbfc
  • Loading branch information
cdumez committed Feb 19, 2019
1 parent bd98801 commit df474d1
Show file tree
Hide file tree
Showing 9 changed files with 210 additions and 36 deletions.
34 changes: 34 additions & 0 deletions Source/WebKit/ChangeLog
@@ -1,3 +1,37 @@
2019-02-18 Chris Dumez <cdumez@apple.com>

REGRESSION (PSON): Can't access optumbank.com from myuhc.com
https://bugs.webkit.org/show_bug.cgi?id=194797
<rdar://problem/48055151>

Reviewed by Geoffrey Garen.

The issue was caused by us mistakenly process-swapping for a same-site server side redirect.
The reason we were getting it wrong is because the logic in
WebProcessPool::processForNavigationInternal() was expecting page.process() to be the source
process and page.pageLoadState().url() to be the source URL. Those assumptions are incorrect
when a server-side redirect occurs in a provisional process. In such case, the source process
is the ProvisionalPageProxy's process and the source URL is the provisional URL, not the
committed one.

* UIProcess/ProvisionalPageProxy.cpp:
(WebKit::ProvisionalPageProxy::didPerformServerRedirect):
(WebKit::ProvisionalPageProxy::didReceiveServerRedirectForProvisionalLoadForFrame):
(WebKit::ProvisionalPageProxy::didReceiveMessage):
* UIProcess/ProvisionalPageProxy.h:
Make sure the provisional page forwards IPC related to server-side redirects to the page so
that the client gets informed.

* UIProcess/WebPageProxy.cpp:
(WebKit::WebPageProxy::receivedNavigationPolicyDecision):
(WebKit::WebPageProxy::didPerformServerRedirect):
(WebKit::WebPageProxy::didPerformServerRedirectShared):
* UIProcess/WebPageProxy.h:
* UIProcess/WebProcessPool.cpp:
(WebKit::WebProcessPool::processForNavigation):
(WebKit::WebProcessPool::processForNavigationInternal):
* UIProcess/WebProcessPool.h:

2019-02-16 Darin Adler <darin@apple.com>

Continue reducing use of String::format, now focusing on hex: "%p", "%x", etc.
Expand Down
20 changes: 20 additions & 0 deletions Source/WebKit/UIProcess/ProvisionalPageProxy.cpp
Expand Up @@ -284,6 +284,16 @@ void ProvisionalPageProxy::decidePolicyForResponse(uint64_t frameID, const WebCo
m_page.decidePolicyForResponseShared(m_process.copyRef(), frameID, frameSecurityOrigin, identifier, navigationID, response, request, canShowMIMEType, listenerID, userData);
}

void ProvisionalPageProxy::didPerformServerRedirect(const String& sourceURLString, const String& destinationURLString, uint64_t frameID)
{
m_page.didPerformServerRedirectShared(m_process.copyRef(), sourceURLString, destinationURLString, frameID);
}

void ProvisionalPageProxy::didReceiveServerRedirectForProvisionalLoadForFrame(uint64_t frameID, uint64_t navigationID, WebCore::ResourceRequest&& request, const UserData& userData)
{
m_page.didReceiveServerRedirectForProvisionalLoadForFrameShared(m_process.copyRef(), frameID, navigationID, WTFMove(request), userData);
}

void ProvisionalPageProxy::startURLSchemeTask(URLSchemeTaskParameters&& parameters)
{
m_page.startURLSchemeTaskShared(m_process.copyRef(), WTFMove(parameters));
Expand Down Expand Up @@ -374,6 +384,16 @@ void ProvisionalPageProxy::didReceiveMessage(IPC::Connection& connection, IPC::D
return;
}

if (decoder.messageName() == Messages::WebPageProxy::DidReceiveServerRedirectForProvisionalLoadForFrame::name()) {
IPC::handleMessage<Messages::WebPageProxy::DidReceiveServerRedirectForProvisionalLoadForFrame>(decoder, this, &ProvisionalPageProxy::didReceiveServerRedirectForProvisionalLoadForFrame);
return;
}

if (decoder.messageName() == Messages::WebPageProxy::DidPerformServerRedirect::name()) {
IPC::handleMessage<Messages::WebPageProxy::DidPerformServerRedirect>(decoder, this, &ProvisionalPageProxy::didPerformServerRedirect);
return;
}

LOG(ProcessSwapping, "Unhandled message %s::%s from provisional process", decoder.messageReceiverName().toString().data(), decoder.messageName().toString().data());
}

Expand Down
3 changes: 3 additions & 0 deletions Source/WebKit/UIProcess/ProvisionalPageProxy.h
Expand Up @@ -64,6 +64,7 @@ class ProvisionalPageProxy : public IPC::MessageReceiver, public CanMakeWeakPtr<
WebProcessProxy& process() { return m_process.get(); }
ProcessSwapRequestedByClient processSwapRequestedByClient() const { return m_processSwapRequestedByClient; }
uint64_t navigationID() const { return m_navigationID; }
const URL& provisionalURL() const { return m_provisionalLoadURL; }

DrawingAreaProxy* drawingArea() const { return m_drawingArea.get(); }
std::unique_ptr<DrawingAreaProxy> takeDrawingArea();
Expand Down Expand Up @@ -91,6 +92,8 @@ class ProvisionalPageProxy : public IPC::MessageReceiver, public CanMakeWeakPtr<
void decidePolicyForResponse(uint64_t frameID, const WebCore::SecurityOriginData&, WebCore::PolicyCheckIdentifier, uint64_t navigationID, const WebCore::ResourceResponse&,
const WebCore::ResourceRequest&, bool canShowMIMEType, uint64_t listenerID, const UserData&);
void didChangeProvisionalURLForFrame(uint64_t frameID, uint64_t navigationID, URL&&);
void didPerformServerRedirect(const String& sourceURLString, const String& destinationURLString, uint64_t frameID);
void didReceiveServerRedirectForProvisionalLoadForFrame(uint64_t frameID, uint64_t navigationID, WebCore::ResourceRequest&&, const UserData&);
void didNavigateWithNavigationData(const WebNavigationDataStore&, uint64_t frameID);
void didPerformClientRedirect(const String& sourceURLString, const String& destinationURLString, uint64_t frameID);
void didCreateMainFrame(uint64_t frameID);
Expand Down
35 changes: 25 additions & 10 deletions Source/WebKit/UIProcess/WebPageProxy.cpp
Expand Up @@ -2748,22 +2748,32 @@ void WebPageProxy::receivedNavigationPolicyDecision(PolicyAction policyAction, A
return;
}

process().processPool().processForNavigation(*this, *navigation, processSwapRequestedByClient, [this, protectedThis = makeRef(*this), policyAction, navigation = makeRef(*navigation),
Ref<WebProcessProxy> sourceProcess = process();
URL sourceURL = URL { URL(), pageLoadState().url() };
if (auto* provisionalPage = provisionalPageProxy()) {
if (provisionalPage->navigationID() == navigation->navigationID()) {
ASSERT(navigation->currentRequestIsRedirect());
sourceProcess = provisionalPage->process();
sourceURL = provisionalPage->provisionalURL();
}
}

process().processPool().processForNavigation(*this, *navigation, sourceProcess.copyRef(), sourceURL, processSwapRequestedByClient, [this, protectedThis = makeRef(*this), policyAction, navigation = makeRef(*navigation), sourceProcess = sourceProcess.copyRef(),
data = WTFMove(data), sender = WTFMove(sender), processSwapRequestedByClient] (Ref<WebProcessProxy>&& processForNavigation, SuspendedPageProxy* destinationSuspendedPage, const String& reason) mutable {
// If the navigation has been destroyed, then no need to proceed.
if (isClosed() || !navigationState().hasNavigation(navigation->navigationID())) {
receivedPolicyDecision(policyAction, navigation.ptr(), WTFMove(data), WTFMove(sender));
return;
}

if (processForNavigation.ptr() != &process()) {
bool shouldProcessSwap = processForNavigation.ptr() != sourceProcess.ptr();
if (shouldProcessSwap) {
policyAction = PolicyAction::StopAllLoads;
RELEASE_LOG_IF_ALLOWED(ProcessSwapping, "decidePolicyForNavigationAction, swapping process %i with process %i for navigation, reason: %{public}s", processIdentifier(), processForNavigation->processIdentifier(), reason.utf8().data());
LOG(ProcessSwapping, "(ProcessSwapping) Switching from process %i to new process (%i) for navigation %" PRIu64 " '%s'", processIdentifier(), processForNavigation->processIdentifier(), navigation->navigationID(), navigation->loggingString());
} else
RELEASE_LOG_IF_ALLOWED(ProcessSwapping, "decidePolicyForNavigationAction: keep using process %i for navigation, reason: %{public}s", processIdentifier(), reason.utf8().data());

bool shouldProcessSwap = processForNavigation.ptr() != &process();
receivedPolicyDecision(policyAction, navigation.ptr(), shouldProcessSwap ? WTF::nullopt : WTFMove(data), WTFMove(sender), shouldProcessSwap ? WillContinueLoadInNewProcess::Yes : WillContinueLoadInNewProcess::No);

if (!shouldProcessSwap)
Expand Down Expand Up @@ -4798,23 +4808,28 @@ void WebPageProxy::didPerformClientRedirectShared(Ref<WebProcessProxy>&& process

void WebPageProxy::didPerformServerRedirect(const String& sourceURLString, const String& destinationURLString, uint64_t frameID)
{
RELEASE_LOG_IF_ALLOWED(Loading, "didPerformServerRedirect: webPID = %i, pageID = %" PRIu64, m_process->processIdentifier(), m_pageID);
didPerformServerRedirectShared(m_process.copyRef(), sourceURLString, destinationURLString, frameID);
}

void WebPageProxy::didPerformServerRedirectShared(Ref<WebProcessProxy>&& process, const String& sourceURLString, const String& destinationURLString, uint64_t frameID)
{
RELEASE_LOG_IF_ALLOWED(Loading, "didPerformServerRedirect: webPID = %i, pageID = %" PRIu64, process->processIdentifier(), m_pageID);

PageClientProtector protector(pageClient());

if (sourceURLString.isEmpty() || destinationURLString.isEmpty())
return;

WebFrameProxy* frame = m_process->webFrame(frameID);
MESSAGE_CHECK(m_process, frame);
MESSAGE_CHECK(m_process, frame->page() == this);
WebFrameProxy* frame = process->webFrame(frameID);
MESSAGE_CHECK(process, frame);
MESSAGE_CHECK(process, frame->page() == this);

MESSAGE_CHECK_URL(m_process, sourceURLString);
MESSAGE_CHECK_URL(m_process, destinationURLString);
MESSAGE_CHECK_URL(process, sourceURLString);
MESSAGE_CHECK_URL(process, destinationURLString);

if (frame->isMainFrame())
m_historyClient->didPerformServerRedirect(*this, sourceURLString, destinationURLString);
process().processPool().historyClient().didPerformServerRedirect(process().processPool(), *this, sourceURLString, destinationURLString, *frame);
process->processPool().historyClient().didPerformServerRedirect(process->processPool(), *this, sourceURLString, destinationURLString, *frame);
}

void WebPageProxy::didUpdateHistoryTitle(const String& title, const String& url, uint64_t frameID)
Expand Down
1 change: 1 addition & 0 deletions Source/WebKit/UIProcess/WebPageProxy.h
Expand Up @@ -1442,6 +1442,7 @@ class WebPageProxy : public API::ObjectImpl<API::Object::Type::Page>
void didStartProvisionalLoadForFrameShared(Ref<WebProcessProxy>&&, uint64_t frameID, uint64_t navigationID, URL&&, URL&& unreachableURL, const UserData&);
void didFailProvisionalLoadForFrameShared(Ref<WebProcessProxy>&&, uint64_t frameID, const WebCore::SecurityOriginData& frameSecurityOrigin, uint64_t navigationID, const String& provisionalURL, const WebCore::ResourceError&, const UserData&);
void didReceiveServerRedirectForProvisionalLoadForFrameShared(Ref<WebProcessProxy>&&, uint64_t frameID, uint64_t navigationID, WebCore::ResourceRequest&&, const UserData&);
void didPerformServerRedirectShared(Ref<WebProcessProxy>&&, const String& sourceURLString, const String& destinationURLString, uint64_t frameID);
void didPerformClientRedirectShared(Ref<WebProcessProxy>&&, const String& sourceURLString, const String& destinationURLString, uint64_t frameID);
void didNavigateWithNavigationDataShared(Ref<WebProcessProxy>&&, const WebNavigationDataStore&, uint64_t frameID);
void didChangeProvisionalURLForFrameShared(Ref<WebProcessProxy>&&, uint64_t frameID, uint64_t navigationID, URL&&);
Expand Down

0 comments on commit df474d1

Please sign in to comment.