• Pâris MEULEMAN's avatar
    Prevent crashes in WPT due to UAF of TestInterfaces::Delegate · d3cd6849
    Pâris MEULEMAN authored
    This works around crashes that surfaced in Cross-origin-opener-policy
    WPT tests. Two possible crashes happened:
      1 - The |RenderView| that created the |BlinkTestRunner| used as a
        delegate got deleted. Later a new |RenderView| is created, followed
        by its |RenderFrame|. The creation of the |RenderFrame|'s associated
        |WebFrameTestClient| crashes as |TestInterfaces::delegate_| is now
        uninitialized (DCHECK in |WebFrameTestClient| ctor).
      2 - Two |RenderViews| are created, both create a |BlinkTestRunner|,
        the first one created is used for |TestInterfaces::delegate_|. Then
        |WebFrameTestClient|s are created, and take a pointer to this
        |delegate_|. Later the |RenderView| associated to the delegate is
        deleted, deleting the delegate. Leading to UAFs by
        |WebFrameTestClient|s under the other |RenderView|.
    
    This failures happen in COOP tests as multiple tests opening and closing
    popups are ran simultaneously from the same window.
    
    A bit more context: The creation of the |RenderView|, instrumentalized
    for tests through |CreateWebViewTestProxy| creates a new
    |BlinkTestRunner| and a child class of |RenderView|: |WebViewTestProxy|.
    The first execution of |CreateWebViewTestProxy| registers the
    |BlinkTestRunner| using |TestInterfaces::SetDelegate|. The |RenderView|
    destruction updates |TestInterfaces::delegate_| to nullptr.
    Likewise, the creation of |RenderFrame| through
    |CreateWebFrameTestProxy| creates a |WebFrameTestProxy| and closely
    related |WebFrameTestClient|. The latter saves a pointer to
    |TestInterfaces::delegate_|.
    
    To Prevent these crashes, this CL changes:
      - When a |RenderView| is created and no delegate exists, i.e.
        |TestInterfaces::delegate_| is nullptr, use the newly created
        |BlinkTestRunner| as the delegate_. This avoids 1-.
      - When a |RenderView| is deleted and another exists, switch to that
        one's |BlinkTestRunner| as the |TestInterfaces::delegate_|.
      - |WebFrameTestClient| to not hold a pointer to
        |TestInterfaces::delegate_| and instead access  it through the
        |WebViewTestProxy| pointer it already had:
        |web_view_test_proxy_->test_interfaces()->GetDelegate()|. These two
        combined avoid 2-.
    
    Bug: 922191
    Change-Id: I83e16a4064afca1c595b04c5ccbb46f1488188f5
    Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2074482
    Commit-Queue: Arthur Hemery <ahemery@chromium.org>
    Auto-Submit: Pâris Meuleman <pmeuleman@chromium.org>
    Reviewed-by: default avatarŁukasz Anforowicz <lukasza@chromium.org>
    Reviewed-by: default avatarCamille Lamy <clamy@chromium.org>
    Cr-Commit-Position: refs/heads/master@{#746316}
    d3cd6849
test_interfaces.cc 5.27 KB