summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorarthursonzogni <arthursonzogni@chromium.org>2019-10-08 14:40:36 +0000
committerMichal Klocek <michal.klocek@qt.io>2020-01-16 13:22:48 +0000
commite89fce7cfa3ca9736edb7380b876bd4934615ea7 (patch)
treedceb5dd75b3c6ab43d39ea3315125d77d2c82a9e
parent6cd2b35a45343f0228109f5475e0ffa16f9120d2 (diff)
downloadqtwebengine-chromium-e89fce7cfa3ca9736edb7380b876bd4934615ea7.tar.gz
[Backport] CVE-2019-13746 2/2
Clear matching pending NavigationEntry on NavigationRequest deletion. The goal is to fix a big class of URL spoof issues. They happen when a NavigationRequest is canceled, but the associated pending navigation entry remains. This causes the wrong URL to be displayed in the omnibox. To fix it, delete the matching pending NavigationEntry in the NavigationRequest's destructor. This is a bit more complex: 1) During an history navigation, several NavigationRequest can starts at the same time for iframes. All of them are associated with the same pending NavigationEntry. 2) A pending NavigationEntry can be used, discarded and reused. It can is used twice, but not associated with the same NavigationRequest(s) on every use. The class PendingEntryRef is used to track one NavigationRequest being associated with a pending NavigationEntry for a given history navigation. Bug: 999932 Change-Id: I0a63dec4293d09120c892411cd9d9ea47a79af66 Reviewed-by: Michael BrĂ¼ning <michael.bruning@qt.io>
-rw-r--r--chromium/content/browser/frame_host/frame_tree_node.cc9
-rw-r--r--chromium/content/browser/frame_host/navigation_controller_delegate.h4
-rw-r--r--chromium/content/browser/frame_host/navigation_controller_impl.cc78
-rw-r--r--chromium/content/browser/frame_host/navigation_controller_impl.h51
-rw-r--r--chromium/content/browser/frame_host/navigation_request.cc42
-rw-r--r--chromium/content/browser/frame_host/navigation_request.h13
-rw-r--r--chromium/content/browser/frame_host/navigator_delegate.cc4
-rw-r--r--chromium/content/browser/frame_host/navigator_delegate.h4
-rw-r--r--chromium/content/browser/frame_host/navigator_impl.cc53
-rw-r--r--chromium/content/browser/frame_host/navigator_impl.h2
-rw-r--r--chromium/content/browser/web_contents/web_contents_impl.h2
11 files changed, 183 insertions, 79 deletions
diff --git a/chromium/content/browser/frame_host/frame_tree_node.cc b/chromium/content/browser/frame_host/frame_tree_node.cc
index f367008b050..79d7556ee04 100644
--- a/chromium/content/browser/frame_host/frame_tree_node.cc
+++ b/chromium/content/browser/frame_host/frame_tree_node.cc
@@ -532,15 +532,8 @@ void FrameTreeNode::DidChangeLoadProgress(double load_progress) {
}
bool FrameTreeNode::StopLoading() {
- if (navigation_request_) {
- int expected_pending_nav_entry_id = navigation_request_->nav_entry_id();
- if (navigation_request_->navigation_handle()) {
+ if (navigation_request_ && navigation_request_->IsNavigationStarted())
navigation_request_->set_net_error(net::ERR_ABORTED);
- expected_pending_nav_entry_id =
- navigation_request_->navigation_handle()->pending_nav_entry_id();
- }
- navigator_->DiscardPendingEntryIfNeeded(expected_pending_nav_entry_id);
- }
ResetNavigationRequest(false, true);
// TODO(nasko): see if child frames should send IPCs in site-per-process
diff --git a/chromium/content/browser/frame_host/navigation_controller_delegate.h b/chromium/content/browser/frame_host/navigation_controller_delegate.h
index 2615790454e..e738630db57 100644
--- a/chromium/content/browser/frame_host/navigation_controller_delegate.h
+++ b/chromium/content/browser/frame_host/navigation_controller_delegate.h
@@ -56,6 +56,10 @@ class NavigationControllerDelegate {
virtual void ActivateAndShowRepostFormWarningDialog() = 0;
virtual bool HasAccessedInitialDocument() = 0;
+ // Returns whether URLs for aborted browser-initiated navigations should be
+ // preserved in the omnibox. Defaults to false.
+ virtual bool ShouldPreserveAbortedURLs() = 0;
+
// TODO(crbug.com/934637): Remove when pdf and any inner web contents user
// gesture is properly propagated.
virtual bool HadInnerWebContents() = 0;
diff --git a/chromium/content/browser/frame_host/navigation_controller_impl.cc b/chromium/content/browser/frame_host/navigation_controller_impl.cc
index 9f2da225cc0..3a457e1c739 100644
--- a/chromium/content/browser/frame_host/navigation_controller_impl.cc
+++ b/chromium/content/browser/frame_host/navigation_controller_impl.cc
@@ -448,6 +448,19 @@ bool DoesSandboxNavigationStayWithinSubtree(
} // namespace
+// NavigationControllerImpl::PendingEntryRef------------------------------------
+
+NavigationControllerImpl::PendingEntryRef::PendingEntryRef(
+ base::WeakPtr<NavigationControllerImpl> controller)
+ : controller_(controller) {}
+
+NavigationControllerImpl::PendingEntryRef::~PendingEntryRef() {
+ if (!controller_) // Can be null with interstitials.
+ return;
+
+ controller_->PendingEntryRefDeleted(this);
+}
+
// NavigationControllerImpl ----------------------------------------------------
const size_t kMaxEntryCountForTestingNotSet = static_cast<size_t>(-1);
@@ -2083,6 +2096,11 @@ void NavigationControllerImpl::DiscardPendingEntry(bool was_failure) {
pending_entry_index_ = -1;
pending_entry_ = nullptr;
}
+
+ // Ensure any refs to the current pending entry are ignored if they get
+ // deleted, by clearing the set of known refs. All future pending entries will
+ // only be affected by new refs.
+ pending_entry_refs_.clear();
}
void NavigationControllerImpl::SetPendingNavigationSSLError(bool error) {
@@ -2620,6 +2638,11 @@ void NavigationControllerImpl::NavigateToExistingPendingEntry(
CHECK(!in_navigate_to_pending_entry_);
in_navigate_to_pending_entry_ = true;
+ // It is not possible to delete the pending NavigationEntry while navigating
+ // to it. Grab a reference to delay potential deletion until the end of this
+ // function.
+ std::unique_ptr<PendingEntryRef> pending_entry_ref = ReferencePendingEntry();
+
// Send all the same document frame loads before the different document loads.
for (auto& item : same_document_loads) {
FrameTreeNode* frame = item->frame_tree_node();
@@ -2850,6 +2873,11 @@ void NavigationControllerImpl::NavigateWithoutEntry(
CHECK(!in_navigate_to_pending_entry_);
in_navigate_to_pending_entry_ = true;
+ // It is not possible to delete the pending NavigationEntry while navigating
+ // to it. Grab a reference to delay potential deletion until the end of this
+ // function.
+ std::unique_ptr<PendingEntryRef> pending_entry_ref = ReferencePendingEntry();
+
node->navigator()->Navigate(std::move(request), reload_type,
RestoreType::NONE);
@@ -3439,4 +3467,54 @@ void NavigationControllerImpl::SetSkippableForSameDocumentEntries(
}
}
+std::unique_ptr<NavigationControllerImpl::PendingEntryRef>
+NavigationControllerImpl::ReferencePendingEntry() {
+ DCHECK(pending_entry_);
+ auto pending_entry_ref =
+ std::make_unique<PendingEntryRef>(weak_factory_.GetWeakPtr());
+ pending_entry_refs_.insert(pending_entry_ref.get());
+ return pending_entry_ref;
+}
+
+void NavigationControllerImpl::PendingEntryRefDeleted(PendingEntryRef* ref) {
+ // Ignore refs that don't correspond to the current pending entry.
+ auto it = pending_entry_refs_.find(ref);
+ if (it == pending_entry_refs_.end())
+ return;
+ pending_entry_refs_.erase(it);
+
+ if (!pending_entry_refs_.empty())
+ return;
+
+ // The pending entry may be deleted before the last PendingEntryRef.
+ if (!pending_entry_)
+ return;
+
+ // We usually clear the pending entry when the matching NavigationRequest
+ // fails, so that an arbitrary URL isn't left visible above a committed page.
+ //
+ // However, we do preserve the pending entry in some cases, such as on the
+ // initial navigation of an unmodified blank tab. We also allow the delegate
+ // to say when it's safe to leave aborted URLs in the omnibox, to let the
+ // user edit the URL and try again. This may be useful in cases that the
+ // committed page cannot be attacker-controlled. In these cases, we still
+ // allow the view to clear the pending entry and typed URL if the user
+ // requests (e.g., hitting Escape with focus in the address bar).
+ //
+ // Do not leave the pending entry visible if it has an invalid URL, since this
+ // might be formatted in an unexpected or unsafe way.
+ // TODO(creis): Block navigations to invalid URLs in https://crbug.com/850824.
+ //
+ // Note: don't touch the transient entry, since an interstitial may exist.
+ bool should_preserve_entry =
+ (pending_entry_ == GetVisibleEntry()) &&
+ pending_entry_->GetURL().is_valid() &&
+ (IsUnmodifiedBlankTab() || delegate_->ShouldPreserveAbortedURLs());
+ if (should_preserve_entry)
+ return;
+
+ DiscardPendingEntry(true);
+ delegate_->NotifyNavigationStateChanged(INVALIDATE_TYPE_URL);
+}
+
} // namespace content
diff --git a/chromium/content/browser/frame_host/navigation_controller_impl.h b/chromium/content/browser/frame_host/navigation_controller_impl.h
index b962bb24371..7e90cc92ce7 100644
--- a/chromium/content/browser/frame_host/navigation_controller_impl.h
+++ b/chromium/content/browser/frame_host/navigation_controller_impl.h
@@ -8,12 +8,14 @@
#include <stddef.h>
#include <stdint.h>
+#include <set>
#include <vector>
#include "base/callback.h"
#include "base/compiler_specific.h"
#include "base/gtest_prod_util.h"
#include "base/macros.h"
+#include "base/memory/weak_ptr.h"
#include "base/optional.h"
#include "base/time/time.h"
#include "build/build_config.h"
@@ -36,6 +38,35 @@ struct LoadCommittedDetails;
class CONTENT_EXPORT NavigationControllerImpl : public NavigationController {
public:
+ // This tracks one NavigationRequest navigating to a pending NavigationEntry.
+ // In some cases, several NavigationRequests are referencing the same pending
+ // NavigationEntry. For instance:
+ // - A reload requested while a reload is already in progress.
+ // - An history navigation causing several subframes to navigate.
+ //
+ // When no NavigationRequests are referencing the pending NavigationEntry
+ // anymore, it should be discarded to avoid a URL spoof.
+ //
+ // The deletion is not always immediate, because it is not possible to delete
+ // the entry while requesting a navigation to it at the same time. In this
+ // case, the deletion happens later, when returning from the function.
+ //
+ // If the pending NavigationEntry is discarded before the PendingEntryRef(s),
+ // then removing the last associated PendingEntryRef is a no-op. It is a no-op
+ // forever, even if the entry becomes the pending NavigationEntry again in the
+ // meantime. Rather than track the NavigationRequest or pending entry
+ // explicitly, this ref class simply goes into a set that gets cleared with
+ // each change to the pending entry
+ class PendingEntryRef {
+ public:
+ PendingEntryRef(base::WeakPtr<NavigationControllerImpl> controller);
+ ~PendingEntryRef();
+
+ private:
+ base::WeakPtr<NavigationControllerImpl> controller_;
+ DISALLOW_COPY_AND_ASSIGN(PendingEntryRef);
+ };
+
NavigationControllerImpl(
NavigationControllerDelegate* delegate,
BrowserContext* browser_context);
@@ -264,6 +295,11 @@ class CONTENT_EXPORT NavigationControllerImpl : public NavigationController {
// entries can be updated as needed.
void NotifyUserActivation();
+ // Tracks a new association between the current pending entry and a
+ // NavigationRequest. Callers are responsible for only calling this for
+ // requests corresponding to the current pending entry.
+ std::unique_ptr<PendingEntryRef> ReferencePendingEntry();
+
private:
friend class RestoreHelper;
@@ -491,6 +527,11 @@ class CONTENT_EXPORT NavigationControllerImpl : public NavigationController {
// at |reference_index| will get their skippable flag set to |skippable|.
void SetSkippableForSameDocumentEntries(int reference_index, bool skippable);
+ // Called when one PendingEntryRef is deleted. When all of the refs for the
+ // current pending entry have been deleted, this automatically discards the
+ // pending NavigationEntry.
+ void PendingEntryRefDeleted(PendingEntryRef* ref);
+
// ---------------------------------------------------------------------------
// The user browser context associated with this controller.
@@ -508,6 +549,14 @@ class CONTENT_EXPORT NavigationControllerImpl : public NavigationController {
// the memory management.
NavigationEntryImpl* pending_entry_;
+ // This keeps track of the NavigationRequests associated with the pending
+ // NavigationEntry. When all of them have been deleted, or have stopped
+ // loading, the pending NavigationEntry can be discarded.
+ //
+ // This is meant to avoid a class of URL spoofs where the navigation is
+ // canceled, but the stale pending NavigationEntry is left in place.
+ std::set<PendingEntryRef*> pending_entry_refs_;
+
// If a new entry fails loading, details about it are temporarily held here
// until the error page is shown (or 0 otherwise).
//
@@ -584,6 +633,8 @@ class CONTENT_EXPORT NavigationControllerImpl : public NavigationController {
// Stores frozen RenderFrameHost. Restores them on history navigation.
// See BackForwardCache class documentation.
BackForwardCache back_forward_cache_;
+ // NOTE: This must be the last member.
+ base::WeakPtrFactory<NavigationControllerImpl> weak_factory_{this};
DISALLOW_COPY_AND_ASSIGN(NavigationControllerImpl);
};
diff --git a/chromium/content/browser/frame_host/navigation_request.cc b/chromium/content/browser/frame_host/navigation_request.cc
index 112542e5c64..eca80212954 100644
--- a/chromium/content/browser/frame_host/navigation_request.cc
+++ b/chromium/content/browser/frame_host/navigation_request.cc
@@ -621,6 +621,14 @@ std::unique_ptr<NavigationRequest> NavigationRequest::CreateForCommit(
return navigation_request;
}
+void NavigationRequest::DropPendingEntryRef() {
+ pending_entry_ref_.reset();
+}
+
+bool NavigationRequest::IsNavigationStarted() const {
+ return state_ >= STARTED;
+}
+
NavigationRequest::NavigationRequest(
FrameTreeNode* frame_tree_node,
const CommonNavigationParams& common_params,
@@ -661,7 +669,8 @@ NavigationRequest::NavigationRequest(
"frame_tree_node",
frame_tree_node_->frame_tree_node_id(), "url",
common_params_.url.possibly_invalid_spec());
-
+ NavigationControllerImpl* controller = static_cast<NavigationControllerImpl*>(
+ frame_tree_node_->navigator()->GetController());
// Setup for navigation to the BundledExchanges.
if (GetContentClient()->browser()->CanAcceptUntrustedExchangesIfNeeded() &&
common_params_.url.SchemeIsFile() &&
@@ -722,6 +731,12 @@ NavigationRequest::NavigationRequest(
entry->back_forward_cache_metrics()
->MainFrameDidStartNavigationToDocument();
}
+
+ // If this NavigationRequest is for the current pending entry, make sure
+ // that we will discard the pending entry if all of associated its requests
+ // go away, by creating a ref to it.
+ if (entry == controller->GetPendingEntry())
+ pending_entry_ref_ = controller->ReferencePendingEntry();
}
std::string user_agent_override;
@@ -735,8 +750,7 @@ NavigationRequest::NavigationRequest(
// Only add specific headers when creating a NavigationRequest before the
// network request is made, not at commit time.
if (!is_for_commit) {
- BrowserContext* browser_context =
- frame_tree_node_->navigator()->GetController()->GetBrowserContext();
+ BrowserContext* browser_context = controller->GetBrowserContext();
ClientHintsControllerDelegate* client_hints_delegate =
browser_context->GetClientHintsControllerDelegate();
if (client_hints_delegate) {
@@ -750,8 +764,7 @@ NavigationRequest::NavigationRequest(
headers.AddHeadersFromString(begin_params_->headers);
AddAdditionalRequestHeaders(
&headers, common_params_.url, common_params_.navigation_type,
- common_params_.transition,
- frame_tree_node_->navigator()->GetController()->GetBrowserContext(),
+ common_params_.transition, controller->GetBrowserContext(),
common_params.method, user_agent_override,
common_params_.has_user_gesture, common_params.initiator_origin,
common_params_.referrer.policy,
@@ -793,6 +806,17 @@ NavigationRequest::~NavigationRequest() {
*this, network::URLLoaderCompletionStatus(net::ERR_ABORTED));
}
+ // If this NavigationRequest is the last one referencing the pending
+ // NavigationEntry, the entry is discarded.
+ //
+ // Leaving a stale pending NavigationEntry with no matching navigation can
+ // potentially lead to URL-spoof issues.
+ //
+ // Note: Discarding the pending NavigationEntry is done before notifying the
+ // navigation finished to the observers. One class is relying on this:
+ // org.chromium.chrome.browser.toolbar.ToolbarManager
+ pending_entry_ref_.reset();
+
#if defined(OS_ANDROID)
if (navigation_handle_proxy_)
navigation_handle_proxy_->DidFinish();
@@ -1515,11 +1539,9 @@ void NavigationRequest::OnRequestFailedInternal(
"OnRequestFailed", "error", status.error_code);
state_ = FAILED;
- int expected_pending_entry_id =
- navigation_handle_.get() ? navigation_handle_->pending_nav_entry_id()
- : nav_entry_id_;
- frame_tree_node_->navigator()->DiscardPendingEntryIfNeeded(
- expected_pending_entry_id);
+ // Ensure the pending entry also gets discarded if it has no other active
+ // requests.
+ pending_entry_ref_.reset();
net_error_ = static_cast<net::Error>(status.error_code);
diff --git a/chromium/content/browser/frame_host/navigation_request.h b/chromium/content/browser/frame_host/navigation_request.h
index 9ab87957266..bd9226f0586 100644
--- a/chromium/content/browser/frame_host/navigation_request.h
+++ b/chromium/content/browser/frame_host/navigation_request.h
@@ -14,6 +14,7 @@
#include "base/optional.h"
#include "base/strings/string_util.h"
#include "build/build_config.h"
+#include "content/browser/frame_host/navigation_controller_impl.h"
#include "content/browser/frame_host/navigation_entry_impl.h"
#include "content/browser/frame_host/navigation_throttle_runner.h"
#include "content/browser/initiator_csp_context.h"
@@ -462,6 +463,13 @@ class CONTENT_EXPORT NavigationRequest : public NavigationURLLoaderDelegate,
int64_t navigation_handle_id() { return navigation_handle_id_; }
+ bool IsNavigationStarted() const;
+
+ // Stop referencing the pending NavigationEntry.
+ //
+ // Note: To be removed after removing DidFailProvisionalLoadWithError().
+ void DropPendingEntryRef();
+
private:
// TODO(clamy): Transform NavigationHandleImplTest into NavigationRequestTest
// once NavigationHandleImpl has become a wrapper around NavigationRequest.
@@ -963,6 +971,11 @@ class CONTENT_EXPORT NavigationRequest : public NavigationURLLoaderDelegate,
// The unique id to identify the NavigationHandle with.
int64_t navigation_handle_id_ = 0;
+ // This tracks a connection between the current pending entry and this
+ // request, such that the pending entry can be discarded if no requests are
+ // left referencing it.
+ std::unique_ptr<NavigationControllerImpl::PendingEntryRef> pending_entry_ref_;
+
base::WeakPtrFactory<NavigationRequest> weak_factory_{this};
DISALLOW_COPY_AND_ASSIGN(NavigationRequest);
diff --git a/chromium/content/browser/frame_host/navigator_delegate.cc b/chromium/content/browser/frame_host/navigator_delegate.cc
index 5ab06ef5a4b..143f5041900 100644
--- a/chromium/content/browser/frame_host/navigator_delegate.cc
+++ b/chromium/content/browser/frame_host/navigator_delegate.cc
@@ -19,10 +19,6 @@ bool NavigatorDelegate::ShouldTransferNavigation(
return true;
}
-bool NavigatorDelegate::ShouldPreserveAbortedURLs() {
- return false;
-}
-
std::vector<std::unique_ptr<NavigationThrottle>>
NavigatorDelegate::CreateThrottlesForNavigation(
NavigationHandle* navigation_handle) {
diff --git a/chromium/content/browser/frame_host/navigator_delegate.h b/chromium/content/browser/frame_host/navigator_delegate.h
index 909f3dfd594..f8abaed63ec 100644
--- a/chromium/content/browser/frame_host/navigator_delegate.h
+++ b/chromium/content/browser/frame_host/navigator_delegate.h
@@ -91,10 +91,6 @@ class CONTENT_EXPORT NavigatorDelegate {
// different process between the load start and commit.
virtual bool ShouldTransferNavigation(bool is_main_frame_navigation);
- // Returns whether URLs for aborted browser-initiated navigations should be
- // preserved in the omnibox. Defaults to false.
- virtual bool ShouldPreserveAbortedURLs();
-
// Returns the overriden user agent string if it's set.
virtual const std::string& GetUserAgentOverride() = 0;
diff --git a/chromium/content/browser/frame_host/navigator_impl.cc b/chromium/content/browser/frame_host/navigator_impl.cc
index 80901a82ea3..c2fc02e1e72 100644
--- a/chromium/content/browser/frame_host/navigator_impl.cc
+++ b/chromium/content/browser/frame_host/navigator_impl.cc
@@ -176,11 +176,9 @@ void NavigatorImpl::DidFailProvisionalLoadWithError(
}
// Discard the pending navigation entry if needed.
- int expected_pending_entry_id =
- render_frame_host->GetNavigationHandle()
- ? render_frame_host->GetNavigationHandle()->pending_nav_entry_id()
- : 0;
- DiscardPendingEntryIfNeeded(expected_pending_entry_id);
+ NavigationRequest* request = render_frame_host->navigation_request();
+ if (request)
+ request->DropPendingEntryRef();
}
void NavigatorImpl::DidFailLoadWithError(
@@ -765,51 +763,6 @@ void NavigatorImpl::LogBeforeUnloadTime(
}
}
-void NavigatorImpl::DiscardPendingEntryIfNeeded(int expected_pending_entry_id) {
- // Racy conditions can cause a fail message to arrive after its corresponding
- // pending entry has been replaced by another navigation. If
- // |DiscardPendingEntry| is called in this case, then the completely valid
- // entry for the new navigation would be discarded. See crbug.com/513742. To
- // catch this case, the current pending entry is compared against the current
- // navigation handle's entry id, which should correspond to the failed load.
- NavigationEntry* pending_entry = controller_->GetPendingEntry();
- bool pending_matches_fail_msg =
- pending_entry &&
- expected_pending_entry_id == pending_entry->GetUniqueID();
- if (!pending_matches_fail_msg)
- return;
-
- // We usually clear the pending entry when it fails, so that an arbitrary URL
- // isn't left visible above a committed page. This must be enforced when the
- // pending entry isn't visible (e.g., renderer-initiated navigations) to
- // prevent URL spoofs for same-document navigations that don't go through
- // DidStartProvisionalLoadForFrame.
- //
- // However, we do preserve the pending entry in some cases, such as on the
- // initial navigation of an unmodified blank tab. We also allow the delegate
- // to say when it's safe to leave aborted URLs in the omnibox, to let the
- // user edit the URL and try again. This may be useful in cases that the
- // committed page cannot be attacker-controlled. In these cases, we still
- // allow the view to clear the pending entry and typed URL if the user
- // requests (e.g., hitting Escape with focus in the address bar).
- //
- // Do not leave the pending entry visible if it has an invalid URL, since this
- // might be formatted in an unexpected or unsafe way.
- // TODO(creis): Block navigations to invalid URLs in https://crbug.com/850824.
- //
- // Note: don't touch the transient entry, since an interstitial may exist.
- bool should_preserve_entry = pending_entry->GetURL().is_valid() &&
- (controller_->IsUnmodifiedBlankTab() ||
- delegate_->ShouldPreserveAbortedURLs());
- if (pending_entry != controller_->GetVisibleEntry() ||
- !should_preserve_entry) {
- controller_->DiscardPendingEntry(true);
-
- // Also force the UI to refresh.
- controller_->delegate()->NotifyNavigationStateChanged(INVALIDATE_TYPE_URL);
- }
-}
-
void NavigatorImpl::RecordNavigationMetrics(
const LoadCommittedDetails& details,
const FrameHostMsg_DidCommitProvisionalLoad_Params& params,
diff --git a/chromium/content/browser/frame_host/navigator_impl.h b/chromium/content/browser/frame_host/navigator_impl.h
index 0f635c7a00b..3006503117e 100644
--- a/chromium/content/browser/frame_host/navigator_impl.h
+++ b/chromium/content/browser/frame_host/navigator_impl.h
@@ -110,8 +110,6 @@ class CONTENT_EXPORT NavigatorImpl : public Navigator {
const base::TimeTicks& renderer_before_unload_end_time) override;
void CancelNavigation(FrameTreeNode* frame_tree_node,
bool inform_renderer) override;
- void DiscardPendingEntryIfNeeded(int expected_pending_entry_id) override;
-
private:
// Holds data used to track browser side navigation metrics.
struct NavigationMetricsData;
diff --git a/chromium/content/browser/web_contents/web_contents_impl.h b/chromium/content/browser/web_contents/web_contents_impl.h
index a7f1c27f7c7..1481362691e 100644
--- a/chromium/content/browser/web_contents/web_contents_impl.h
+++ b/chromium/content/browser/web_contents/web_contents_impl.h
@@ -724,7 +724,6 @@ class CONTENT_EXPORT WebContentsImpl : public WebContents,
void DidStartNavigationToPendingEntry(const GURL& url,
ReloadType reload_type) override;
bool ShouldTransferNavigation(bool is_main_frame_navigation) override;
- bool ShouldPreserveAbortedURLs() override;
void DidStartLoading(FrameTreeNode* frame_tree_node,
bool to_different_document) override;
void DidStopLoading() override;
@@ -883,6 +882,7 @@ class CONTENT_EXPORT WebContentsImpl : public WebContents,
const EntryChangedDetails& change_details) override;
void NotifyNavigationListPruned(const PrunedDetails& pruned_details) override;
void NotifyNavigationEntriesDeleted() override;
+ bool ShouldPreserveAbortedURLs() override;
// Invoked before a form repost warning is shown.
void NotifyBeforeFormRepostWarningShow() override;