Skip to content

Commit

Permalink
Cherry-pick 256843.8@webkit-2022.12-embargoed (fe2f16c). https://bugs…
Browse files Browse the repository at this point in the history
….webkit.org/show_bug.cgi?id=251013

    Recalculate normal flow value in RenderLayer::establishesTopLayerDidChange
    https://bugs.webkit.org/show_bug.cgi?id=251013

    Reviewed by Tim Nguyen.

    In RenderLayer::rebuildZOrderLists the RenderView layer makes sure the layers for dialogs/top-level elements are appended after
    everything else in the positive z-order list. When removing the dialog layer, dirtyPaintOrderListsOnChildChange will be called
    and since it is not a normal only flow everything will be handled correctly through dirtyStackingContextZOrderLists.

    In the test case the behaviour is the same until dirtyPaintOrderListsOnChildChange is called on the dialog layer removal. Now that
    layer to be removed *is* a normal only flow (the element is no longer positioned and has non visible overflow, see
    RenderLayer::shouldBeNormalFlowOnly). This means the positive z-order list is unchanged and the deleted layer still part of it.
    When the test cleanup code does a final repaint, the RenderView positive z-order list is processed as normal and when trying to
    access the deleted layer the UAF happens.

    To fix this, make sure the normal flow value is correct when adding the layer in RenderLayer::establishesTopLayerDidChange.

    * LayoutTests/fast/layers/normal-flow-dialog-remove-layer-crash-expected.html: Added.
    * LayoutTests/fast/layers/normal-flow-dialog-remove-layer-crash.html: Added.
    * Source/WebCore/rendering/RenderLayer.cpp:
    (WebCore::RenderLayer::establishesTopLayerDidChange):

    Canonical link: https://commits.webkit.org/256843.8@webkit-2022.12-embargoed
  • Loading branch information
rwlbuis authored and aperezdc committed Apr 3, 2023
1 parent 7eb6a23 commit af00482
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 1 deletion.
@@ -0,0 +1 @@
Pass if no crash.
30 changes: 30 additions & 0 deletions LayoutTests/fast/layers/normal-flow-dialog-remove-layer-crash.html
@@ -0,0 +1,30 @@
<style>
div {
overflow: hidden;
}
dialog {
overflow: hidden;
position: static;
display: inline;
float: left;
}
head {
display: inline;
}
</style>
<script>
if (window.testRunner)
testRunner.waitUntilDone();
onload = () => {
document.head.append(dialog);
setTimeout(() => {
dialog.showModal();
document.styleSheets[0].disabled = true;
testRunner.notifyDone();
}, 0);
};
</script>
<body>
<dialog id="dialog"><div></div></dialog>
Pass if no crash.
</body>
4 changes: 3 additions & 1 deletion Source/WebCore/rendering/RenderLayer.cpp
Expand Up @@ -3927,8 +3927,10 @@ void RenderLayer::establishesTopLayerWillChange()

void RenderLayer::establishesTopLayerDidChange()
{
if (auto* parentLayer = renderer().layerParent())
if (auto* parentLayer = renderer().layerParent()) {
setIsNormalFlowOnly(shouldBeNormalFlowOnly());
parentLayer->addChild(*this);
}
}

RenderLayer* RenderLayer::enclosingFragmentedFlowAncestor() const
Expand Down

0 comments on commit af00482

Please sign in to comment.