Skip to content

Commit 7535d5d

Browse files
Jana Grillmibrunin
authored andcommitted
[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 <[email protected]> Reviewed-by: Ian Kilpatrick <[email protected]> Commit-Queue: Ian Kilpatrick <[email protected]> Cr-Original-Commit-Position: refs/heads/master@{#861724} Commit-Queue: Jana Grill <[email protected]> Reviewed-by: Achuith Bhandarkar <[email protected]> Reviewed-by: Koji Ishii <[email protected]> Cr-Commit-Position: refs/branch-heads/4240@{#1577} Cr-Branched-From: f297677702651916bbf65e59c0d4bbd4ce57d1ee-refs/heads/master@{#800218} Reviewed-by: Jüri Valdmann <[email protected]>
1 parent 78b0928 commit 7535d5d

File tree

1 file changed

+20
-2
lines changed

1 file changed

+20
-2
lines changed

chromium/third_party/blink/renderer/core/layout/line/line_box_list.cc

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -348,14 +348,32 @@ void LineBoxList::DirtyLinesFromChangedChild(LineLayoutItem container,
348348
// findNextLineBreak. findNextLineBreak, despite the name, actually returns
349349
// the first LayoutObject after the BR. <rdar://problem/3849947> "Typing
350350
// after pasting line does not appear until after window resize."
351-
if (RootInlineBox* prev_root_box = box->PrevRootBox())
351+
if (RootInlineBox* prev_root_box = box->PrevRootBox()) {
352352
prev_root_box->MarkDirty();
353+
#if DCHECK_IS_ON()
354+
for (; prev_root_box; prev_root_box = prev_root_box->PrevRootBox()) {
355+
DCHECK(prev_root_box->IsDirty() ||
356+
prev_root_box->LineBreakObj() != child);
357+
}
358+
#endif
359+
}
353360
// If |child| or any of its immediately previous siblings with culled
354361
// lineboxes is the object after a line-break in |box| or the linebox after
355362
// it then that means |child| actually sits on the linebox after |box| (or
356363
// is its line-break object) and so we need to dirty it as well.
357-
if (RootInlineBox* next_root_box = box->NextRootBox())
364+
if (RootInlineBox* next_root_box = box->NextRootBox()) {
358365
next_root_box->MarkDirty();
366+
367+
next_root_box = next_root_box->NextRootBox();
368+
if (next_root_box && next_root_box->LineBreakObj() == child)
369+
next_root_box->MarkDirty();
370+
#if DCHECK_IS_ON()
371+
for (; next_root_box; next_root_box = next_root_box->NextRootBox()) {
372+
DCHECK(next_root_box->IsDirty() ||
373+
next_root_box->LineBreakObj() != child);
374+
}
375+
#endif
376+
}
359377
}
360378
}
361379

0 commit comments

Comments
 (0)