New issue
Advanced search Search tips
Note: Color blocks (like or ) mean that a user may not be available. Tooltip shows the reason.

Issue 818025 link

Starred by 2 users

Issue metadata

Status: Verified
Owner:
Closed: Mar 2018
Cc:
Components:
EstimatedDays: ----
NextAction: ----
OS: Android
Pri: 1
Type: Bug

Blocking:
issue 766255
issue 773793



Sign in to add a comment

[O] Tapping back from the interstitial links flow does not display interstitial on tapping the links again

Project Member Reported by sbash...@chromium.org, Mar 1 2018

Issue description

This report will ONLY be viewable by Google.

Device name: Pixel XL
Android version:OPM1.171019.022.A1
Fingerprint:
WebView version (from system settings -> Apps -> Android System WebView)/ Monochrome stable : 66.0.3358.0


(1) Install SuperSafebrowsingOptIn.apk from https://sites.google.com/a/google.com/clank/engineering/android-webview/zzarchive/webview-manual-testing?pli=1

Steps to reproduce:
1.Tap the SuperSafeBrowsingOptIn Test application 
2. Tap 
d. Loud/red
3 i. Tap first link "Should show a phishing warning"
4.Tap a." Learn more"
b. " System information and page content"
c. " Privacy policy"
5.Tap device back key
6. Repeat steps 3 i.
7.Observe the Device
Expected result:

Interstitial should be displayed after step 6
Actual result:
Interstitial is not displayed after step 6

Frequency:
5/5

NOTE :
1. This issue is not reproduced on Moto Z2 Play / NRD90M on the same build 
2. This issue is reproducible on O devices and above on M65 latest beta.
 
Video & Bugreport attached =>  http://go/chrome-androidlogs1/8/818025
Thanks for filing a bug for this, this is exactly what I observed when investigating issue 813739 (see bullet #2 in comment #8).

This is specific to multiprocess (and it repros on N with multiprocess enabled). Basic issue is related to the Set() and Erase() methods for frame_tree_node_to_io_thread_client_ (see aw_contents_io_thread_client.cc).

We Erase() ID 1 (main frame) from the map, but don't Set() it again. So when we try to check that resource, it says that Safe Browsing is not enabled for that IoThreadClientData object (because we can't find it in our map). Interestingly, subresources still work fine (so clicking the "malicious subresource" link will trigger the interstitial as expected).

So the question remains: are we missing a call to Set(id = 1) after the final Erase(id = 1), or do we have one too many Erase(id = 1) calls? I'll do more investigation.

Also, this means that multiprocess effectively disables Safe Browsing, which means that multiprocess paradoxically reduces security :(
Labels: Proj-PlzNavigate
Huh, turns out this is a regression from PlzNavigate. Range:

https://chromium.googlesource.com/chromium/src/+log/63.0.3215.0..63.0.3217.0?pretty=fuller

Confirmed that the "--enable-browser-side-navigation" switch breaks this for early M63 builds and the "--disable-browser-side-navigation" switch fixes it for later PlzNavigate builds.
Blocking: 766255
Blocking: 773793
Labels: WebView-SafeBrowsing
Follow-up to the investigation in comment #2. It looks like pre-plznavigate we never actually check frame_tree_node_id's, so the pattern of Set/Erase doesn't appear to affect Safe Browsing. Still unsure of the correct behavior.
Cc: changwan@chromium.org jam@chromium.org boliu@chromium.org
Labels: -Pri-2 -Target-65 Pri-1
Chatted with Bo today. We think our map is incorrect.

Our 2 maps [1] are:

 1. RenderFrameHost -> IoThreadClientData
 2. FrameTreeNode -> IoThreadClientData (added for PlzNavigate)

The basic issue is that we Set & Erase both maps in similar spots, but FrameTreeNode and RenderFrameHost don't have a 1:1 relationship (a FrameTreeNode may have multiple RenderFrameHosts).

I did 3 cross-site browser-initiated navigations. The Set and Erase calls look like:

Set   FrameTreeNode 1 / RenderFrameHost (2,2) (this happens when the WebView is instantiated)
Set   FrameTreeNode 1 / RenderFrameHost (2,2) (this is the first navigation)

Set   FrameTreeNode 1 / RenderFrameHost (2,5)
Erase FrameTreeNode 1 / RenderFrameHost (2,2) <-- problem starts here: map 2 is empty.

Set   FrameTreeNode 1 / RenderFrameHost (2,9)
Erase FrameTreeNode 1 / RenderFrameHost (2,5)

---

Root cause: the maps fall out of sync because map 2 doesn't distinguish between RenderFrameHosts for a given FrameTreeNode. If we later do a renderer-initiated navigation, we try to check for FrameTreeNode 1 in the map, but we already erased it.

jam@ do you know if map 1 and map 2 are designed to stay in-sync? I see you filed  issue 645983 , where we originally introduced map 2.

[1] https://cs.chromium.org/chromium/src/android_webview/browser/aw_contents_io_thread_client.cc?type=cs&sq=package:chromium&l=84

Comment 8 by boliu@chromium.org, Mar 6 2018

The maps should always hold the correct state of the world, and the FrameTreeNode does not, so is broken should be fixed.
If both maps should hold the state of the world, then we should consolidate them into one.
huh? but they are different maps, with different keys..
Both maps are implementation details of AwContentsIoThreadClient::FromID() (there are 2 methods with different signatures). Judging by the name, it sounds wrong for one FromID(frame_tree_node_id) to return one thing and FromID(render_process_id, render_frame_id) to return something else.

Since both FromID() methods serve a similar purpose, and should return equivalent* values given valid input, then it makes sense for them to use the same internal state.

* FromID() actually returns unique_ptr<AwContentsIoThreadClient>, so invoking each method would return different unique pointers, however the underlying AwContentsIoThreadClient native object should pin the same AwContentsIoThreadClient Java object [1]. So these don't return "equal" values, but return values are arguably conceptually "equivalent" because they refer to the same Java instance.

[1] https://cs.chromium.org/chromium/src/android_webview/browser/aw_contents_io_thread_client.h?type=cs&sq=package:chromium&l=42
Project Member

Comment 12 by bugdroid1@chromium.org, Mar 10 2018

The following revision refers to this bug:
  https://chromium.googlesource.com/chromium/src.git/+/1715b8dc26a9b994de4fcb3487b0bb98f16fba2e

commit 1715b8dc26a9b994de4fcb3487b0bb98f16fba2e
Author: Nate Fischer <ntfschr@chromium.org>
Date: Sat Mar 10 03:03:29 2018

AW: fix AwContentsIoThreadClient::FromID map

This fixes a bug related to the implementation of
AwContentsIoThreadClient::FromID(frame_tree_node_id). This function is
implemented using a map to keep track of the AwContentsIoThreadClient
for a particular FrameTreeNode.

Before this change, we would remove a map entry for a frame_tree_node_id
whenever we destroy an associated RenderFrameHost. This is incorrect in
multiprocess mode however, because a FrameTreeNode may have multiple
associated RenderFrameHosts in its lifetime (such as swapping
RenderFrameHosts for cross-site navigations). When we swap, we would
first overwrite the map entry for the new RenderFrameHost, then erase
the map entry when we destroy the old RenderFrameHost.

The issue manifests most visibly for Safe Browsing, because FromID()
returns nullptr, and Safe Browsing logic defaults to disabling the
feature. However, this issue is not specific to Safe Browsing, and this
would bug would cause a bad state whenever we trigger multiple
cross-site browser-initiated navigations.

With this change, we keep track of live RenderFrameHosts for a given
FrameTreeNode, and only remove an entry from the map if we've destroyed
the last associated RenderFrameHost.

Bug:  818025 
Test: manual - see bug for repro steps
Change-Id: I2ae81fdb5338084cdf253582206144b4f45704b1
Reviewed-on: https://chromium-review.googlesource.com/956411
Reviewed-by: Bo <boliu@chromium.org>
Commit-Queue: Nate Fischer <ntfschr@chromium.org>
Cr-Commit-Position: refs/heads/master@{#542334}
[modify] https://crrev.com/1715b8dc26a9b994de4fcb3487b0bb98f16fba2e/android_webview/browser/aw_contents_io_thread_client.cc

Comment 13 by ntfschr@google.com, Mar 10 2018

Status: Fixed (was: Assigned)

Comment 14 Deleted

@Nate : Can you please merge the fix to M66 branch?. I could verify the fix on Tot.Thanks
Labels: Merge-Request-66
Status: Started (was: Fixed)
Reopening this to request a merge. This landed in Monday's canary (67.0.3368.0). As per the 24-hr requirement, I'll hold until Tuesday for the merge.

In terms of risk, this will have no impact on Chrome.

Comment 17 by cmasso@google.com, Mar 12 2018

Labels: -Merge-Request-66 Merge-Approved-66
Merge approved upon verification of the fix in canary
Summary: [O] Tapping back from the interstitial links flow does not display interstitial on tapping the links again (was: [O] Tapping back from the interstial links flow does not display interstial on tapping the links again)

Comment 19 by cmasso@google.com, Mar 13 2018

Please merge this change as soon as possible
this issue no longer reproducible on 67.0.3370.0 (ToT) . Please merge the changes to M66 .Thanks
Project Member

Comment 21 by bugdroid1@chromium.org, Mar 15 2018

Labels: -merge-approved-66 merge-merged-3359
The following revision refers to this bug:
  https://chromium.googlesource.com/chromium/src.git/+/a262cc22e17455c7ec69690ae70be74ffc745b84

commit a262cc22e17455c7ec69690ae70be74ffc745b84
Author: Nate Fischer <ntfschr@chromium.org>
Date: Thu Mar 15 03:25:16 2018

AW: fix AwContentsIoThreadClient::FromID map

This fixes a bug related to the implementation of
AwContentsIoThreadClient::FromID(frame_tree_node_id). This function is
implemented using a map to keep track of the AwContentsIoThreadClient
for a particular FrameTreeNode.

Before this change, we would remove a map entry for a frame_tree_node_id
whenever we destroy an associated RenderFrameHost. This is incorrect in
multiprocess mode however, because a FrameTreeNode may have multiple
associated RenderFrameHosts in its lifetime (such as swapping
RenderFrameHosts for cross-site navigations). When we swap, we would
first overwrite the map entry for the new RenderFrameHost, then erase
the map entry when we destroy the old RenderFrameHost.

The issue manifests most visibly for Safe Browsing, because FromID()
returns nullptr, and Safe Browsing logic defaults to disabling the
feature. However, this issue is not specific to Safe Browsing, and this
would bug would cause a bad state whenever we trigger multiple
cross-site browser-initiated navigations.

With this change, we keep track of live RenderFrameHosts for a given
FrameTreeNode, and only remove an entry from the map if we've destroyed
the last associated RenderFrameHost.

Bug:  818025 
Test: manual - see bug for repro steps
Change-Id: I2ae81fdb5338084cdf253582206144b4f45704b1
Reviewed-on: https://chromium-review.googlesource.com/956411
Reviewed-by: Bo <boliu@chromium.org>
Commit-Queue: Nate Fischer <ntfschr@chromium.org>
Cr-Original-Commit-Position: refs/heads/master@{#542334}(cherry picked from commit 1715b8dc26a9b994de4fcb3487b0bb98f16fba2e)
Reviewed-on: https://chromium-review.googlesource.com/963676
Reviewed-by: Nate Fischer <ntfschr@chromium.org>
Cr-Commit-Position: refs/branch-heads/3359@{#263}
Cr-Branched-From: 66afc5e5d10127546cc4b98b9117aff588b5e66b-refs/heads/master@{#540276}
[modify] https://crrev.com/a262cc22e17455c7ec69690ae70be74ffc745b84/android_webview/browser/aw_contents_io_thread_client.cc

Status: Fixed (was: Started)
Status: Verified (was: Fixed)
Verified on Nexus 6P/OPM1.171019.028 having 65.0.3359.35 and 67.0.3372.0 , issue mentioned in #0 no longer reproducible. Thanks for the fix and merge to 66.
Labels: -Restrict-View-Google
Opening this up, because there's nothing private.
Cc: ntfschr@chromium.org sandeepkumars@chromium.org
 Issue 830850  has been merged into this issue.

Sign in to add a comment