summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJana Grill <janagrill@google.com>2021-03-16 14:07:07 +0000
committerMichael Brüning <michael.bruning@qt.io>2021-03-29 09:43:49 +0000
commit4a749092925888e15a0dc3cb818e0cff857c9cfa (patch)
tree048f823db48df1306305a8f370624f4166ad435d
parent71b72721f644be8cd92f5d3f2245f65993799f56 (diff)
[Backport] CVE-2021-21193: Use after free in Blink
Cherry-pick of patch originally reviewed on https://chromium-review.googlesource.com/c/chromium/src/+/2748756: Mark additional RootInlineBox dirty when culled inline box is removed When a |LayoutInline| is removed, |LineBoxList:: DirtyLinesFromChangedChild| tries to mark affected |RootInlineBox| dirty. When the |LayoutInline| to be removed is culled, it tries to find the |RootInlineBox| from its previous siblings, then look for its previous and next |RootInlineBox|es. Occasionally, the next next line of the previous sibling is wrapped at the |LayoutInline|, and that its |LineBreakObj()| holds the reference to the |LayoutInline|. This patch marks such |RootInlineBox| dirty. (cherry picked from commit 2dbdabb28d647c8ee20cbe36e3c957e74aff663b) Bug: 1186287 Change-Id: I8ca73ebb4f5e4f13e997662fffd803d6a74ef49a Auto-Submit: Koji Ishii <kojii@chromium.org> Reviewed-by: Ian Kilpatrick <ikilpatrick@chromium.org> Commit-Queue: Ian Kilpatrick <ikilpatrick@chromium.org> Cr-Original-Commit-Position: refs/heads/master@{#861724} Commit-Queue: Jana Grill <janagrill@chromium.org> Reviewed-by: Achuith Bhandarkar <achuith@chromium.org> Reviewed-by: Koji Ishii <kojii@chromium.org> Cr-Commit-Position: refs/branch-heads/4240@{#1577} Cr-Branched-From: f297677702651916bbf65e59c0d4bbd4ce57d1ee-refs/heads/master@{#800218} Reviewed-by: Jüri Valdmann <juri.valdmann@qt.io>
-rw-r--r--chromium/third_party/blink/renderer/core/layout/line/line_box_list.cc22
1 files changed, 20 insertions, 2 deletions
diff --git a/chromium/third_party/blink/renderer/core/layout/line/line_box_list.cc b/chromium/third_party/blink/renderer/core/layout/line/line_box_list.cc
index 9d9d861f00c..ed929849f72 100644
--- a/chromium/third_party/blink/renderer/core/layout/line/line_box_list.cc
+++ b/chromium/third_party/blink/renderer/core/layout/line/line_box_list.cc
@@ -359,14 +359,32 @@ void LineBoxList::DirtyLinesFromChangedChild(LineLayoutItem container,
// findNextLineBreak. findNextLineBreak, despite the name, actually returns
// the first LayoutObject after the BR. <rdar://problem/3849947> "Typing
// after pasting line does not appear until after window resize."
- if (RootInlineBox* prev_root_box = box->PrevRootBox())
+ if (RootInlineBox* prev_root_box = box->PrevRootBox()) {
prev_root_box->MarkDirty();
+#if DCHECK_IS_ON()
+ for (; prev_root_box; prev_root_box = prev_root_box->PrevRootBox()) {
+ DCHECK(prev_root_box->IsDirty() ||
+ prev_root_box->LineBreakObj() != child);
+ }
+#endif
+ }
// If |child| or any of its immediately previous siblings with culled
// lineboxes is the object after a line-break in |box| or the linebox after
// it then that means |child| actually sits on the linebox after |box| (or
// is its line-break object) and so we need to dirty it as well.
- if (RootInlineBox* next_root_box = box->NextRootBox())
+ if (RootInlineBox* next_root_box = box->NextRootBox()) {
next_root_box->MarkDirty();
+
+ next_root_box = next_root_box->NextRootBox();
+ if (next_root_box && next_root_box->LineBreakObj() == child)
+ next_root_box->MarkDirty();
+#if DCHECK_IS_ON()
+ for (; next_root_box; next_root_box = next_root_box->NextRootBox()) {
+ DCHECK(next_root_box->IsDirty() ||
+ next_root_box->LineBreakObj() != child);
+ }
+#endif
+ }
}
}