diff options
author | Jana Grill <janagrill@google.com> | 2021-03-16 14:07:07 +0000 |
---|---|---|
committer | Michael Brüning <michael.bruning@qt.io> | 2021-03-29 09:43:49 +0000 |
commit | 4a749092925888e15a0dc3cb818e0cff857c9cfa (patch) | |
tree | 048f823db48df1306305a8f370624f4166ad435d | |
parent | 71b72721f644be8cd92f5d3f2245f65993799f56 (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.cc | 22 |
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 + } } } |