RESOLVED FIXED 206099
Null deref crash in DOMWindow::scrollBy after evoking updateLayoutIgnorePendingStylesheets()
https://bugs.webkit.org/show_bug.cgi?id=206099
Summary Null deref crash in DOMWindow::scrollBy after evoking updateLayoutIgnorePendi...
Jack
Reported 2020-01-10 14:49:19 PST
<radr://problem/57213791> Similar to https://webkit.org/b/200409, but the frame is removed by reentrancy after calling updateLayoutIgnorePendingStylesheets.
Attachments
Test case (2.30 KB, text/html)
2020-01-10 14:55 PST, Jack
no flags
Patch (3.76 KB, patch)
2020-01-10 16:40 PST, Jack
simon.fraser: review-
Patch (4.53 KB, patch)
2020-01-27 21:30 PST, Pinki Gyanchandani
no flags
Patch (3.53 KB, patch)
2020-01-28 14:22 PST, Pinki Gyanchandani
no flags
Patch (3.53 KB, patch)
2020-01-28 14:25 PST, Pinki Gyanchandani
no flags
Patch (3.52 KB, patch)
2020-01-28 14:37 PST, Pinki Gyanchandani
no flags
Patch (3.58 KB, patch)
2020-01-28 14:53 PST, Pinki Gyanchandani
no flags
Jack
Comment 1 2020-01-10 14:52:47 PST
Jack
Comment 2 2020-01-10 14:55:06 PST
Created attachment 387377 [details] Test case The test case becomes flaky if we further reduce the html file.
Jack
Comment 3 2020-01-10 16:40:26 PST
Geoffrey Garen
Comment 4 2020-01-10 16:49:21 PST
Comment on attachment 387396 [details] Patch View in context: https://bugs.webkit.org/attachment.cgi?id=387396&action=review > Source/WebCore/page/DOMWindow.cpp:1609 > + auto frame = makeRefPtr(this->frame()); > + if (!frame) > + return; > > - FrameView* view = frame()->view(); > + auto view = makeRefPtr(frame->view()); > if (!view) > return; In this case, do we even need "frame" and "view" before layout, or should we just delete these accesses, and only use the "afterLayout" variants? (Is there a specific need to perform these null checks? If so, maybe we should just perform them as expressions without saving a local variable at all.) > Source/WebCore/page/DOMWindow.cpp:1655 > + // Layout may have affected the current frame: Can you specify why? For example, is there an event that fires?
Chris Dumez
Comment 5 2020-01-10 16:53:40 PST
Comment on attachment 387396 [details] Patch View in context: https://bugs.webkit.org/attachment.cgi?id=387396&action=review > Source/WebCore/page/DOMWindow.cpp:1604 > + if (!frame) This is a bogus check. if (!isCurrentlyDisplayedInFrame()) would have returned early above if the frame was null.
Simon Fraser (smfr)
Comment 6 2020-01-10 17:41:40 PST
Comment on attachment 387396 [details] Patch View in context: https://bugs.webkit.org/attachment.cgi?id=387396&action=review > Source/WebCore/page/DOMWindow.cpp:1644 > + auto frame = makeRefPtr(this->frame()); > + if (!frame) > return; > > + auto view = makeRefPtr(frame->view()); > + if (!view) > + return; We repeat this pattern in various accessors in this file. It's so common I think we should share code for it. I also think we should limit 'view' and 'frame' to a scope that ends before the updateLayoutIgnorePendingStylesheets call. I see no reason to keep a ref to these across the updateLayoutIgnorePendingStylesheets call.
Jack
Comment 7 2020-01-13 08:40:58 PST
We had the same discussion. In this test case, frame is null after calling "updateLayoutIgnorePendingStylesheets". Some have concern about using freed frame pointer, so we use the same approach as in other functions. (In reply to Geoffrey Garen from comment #4) > Comment on attachment 387396 [details] > Patch > > View in context: > https://bugs.webkit.org/attachment.cgi?id=387396&action=review > > > Source/WebCore/page/DOMWindow.cpp:1609 > > + auto frame = makeRefPtr(this->frame()); > > + if (!frame) > > + return; > > > > - FrameView* view = frame()->view(); > > + auto view = makeRefPtr(frame->view()); > > if (!view) > > return; > > In this case, do we even need "frame" and "view" before layout, or should we > just delete these accesses, and only use the "afterLayout" variants? (Is > there a specific need to perform these null checks? If so, maybe we should > just perform them as expressions without saving a local variable at all.) > > > Source/WebCore/page/DOMWindow.cpp:1655 > > + // Layout may have affected the current frame: > > Can you specify why? For example, is there an event that fires?
Jack
Comment 8 2020-01-13 08:45:04 PST
Thanks! Will either keep this line or add reference count to prevent frame being deleted. (In reply to Chris Dumez from comment #5) > Comment on attachment 387396 [details] > Patch > > View in context: > https://bugs.webkit.org/attachment.cgi?id=387396&action=review > > > Source/WebCore/page/DOMWindow.cpp:1604 > > + if (!frame) > > This is a bogus check. if (!isCurrentlyDisplayedInFrame()) would have > returned early above if the frame was null.
Chris Dumez
Comment 9 2020-01-13 08:53:03 PST
(In reply to Jack from comment #8) > Thanks! Will either keep this line or add reference count to prevent frame > being deleted. > > (In reply to Chris Dumez from comment #5) > > Comment on attachment 387396 [details] > > Patch > > > > View in context: > > https://bugs.webkit.org/attachment.cgi?id=387396&action=review > > > > > Source/WebCore/page/DOMWindow.cpp:1604 > > > + if (!frame) > > > > This is a bogus check. if (!isCurrentlyDisplayedInFrame()) would have > > returned early above if the frame was null. I think Simon already mentioned this but I don't think we want to keep the frame alive past the updateLayoutIgnorePendingStylesheets() call. Instead, you should get the frame *after* the updateLayoutIgnorePendingStylesheets() call and null check it then.
Jack
Comment 10 2020-01-13 09:19:59 PST
Thanks! Yes, there is a pattern in this file that can be abstracted out. (In reply to Simon Fraser (smfr) from comment #6) > Comment on attachment 387396 [details] > Patch > > View in context: > https://bugs.webkit.org/attachment.cgi?id=387396&action=review > > > Source/WebCore/page/DOMWindow.cpp:1644 > > + auto frame = makeRefPtr(this->frame()); > > + if (!frame) > > return; > > > > + auto view = makeRefPtr(frame->view()); > > + if (!view) > > + return; > > We repeat this pattern in various accessors in this file. It's so common I > think we should share code for it. > > I also think we should limit 'view' and 'frame' to a scope that ends before > the updateLayoutIgnorePendingStylesheets call. I see no reason to keep a ref > to these across the updateLayoutIgnorePendingStylesheets call.
Jack
Comment 11 2020-01-13 09:33:35 PST
Geoffrey commented about the lifespan of frame pointer. There was concern about using freed frame pointer so we follow the pattern of other functions. Will discuss further with Geoffrey and others to decide if we should protect old frame pointer. (In reply to Chris Dumez from comment #9) > (In reply to Jack from comment #8) > > Thanks! Will either keep this line or add reference count to prevent frame > > being deleted. > > > > (In reply to Chris Dumez from comment #5) > > > Comment on attachment 387396 [details] > > > Patch > > > > > > View in context: > > > https://bugs.webkit.org/attachment.cgi?id=387396&action=review > > > > > > > Source/WebCore/page/DOMWindow.cpp:1604 > > > > + if (!frame) > > > > > > This is a bogus check. if (!isCurrentlyDisplayedInFrame()) would have > > > returned early above if the frame was null. > > I think Simon already mentioned this but I don't think we want to keep the > frame alive past the updateLayoutIgnorePendingStylesheets() call. Instead, > you should get the frame *after* the updateLayoutIgnorePendingStylesheets() > call and null check it then.
Pinki Gyanchandani
Comment 12 2020-01-27 21:30:12 PST
Ryosuke Niwa
Comment 13 2020-01-27 21:51:56 PST
Comment on attachment 388966 [details] Patch View in context: https://bugs.webkit.org/attachment.cgi?id=388966&action=review r- due to the following issues. > Source/WebCore/ChangeLog:3 > + Deploy Ref and RefPtr in DOMWindow::scroll* functions The title of this bug doesn’t match your patch at all. Please fix it. > Source/WebCore/ChangeLog:8 > + Added Null pointer check for frame in scrollBy function before usage. Nit: null pointer check, not Null pointer check. > Source/WebCore/page/DOMWindow.cpp:1690 > + FrameView* view = frame->view(); We should store FrameView in RefPtr. Use auto & makeRefPtr. > LayoutTests/platform/mac/fast/dom/Window/window-scroll-ignore-null-frame-expected.txt:1 > +layer at (0,0) size 800x600 Please call dumpAsText in the test and add a platform agnostic result.
Ryosuke Niwa
Comment 14 2020-01-27 21:52:48 PST
Wait a minute, maybe you uploaded your patch to a wrong bug?
Pinki Gyanchandani
Comment 15 2020-01-28 14:22:06 PST
Pinki Gyanchandani
Comment 16 2020-01-28 14:25:45 PST
Ryosuke Niwa
Comment 17 2020-01-28 14:29:05 PST
Comment on attachment 389063 [details] Patch View in context: https://bugs.webkit.org/attachment.cgi?id=389063&action=review > Source/WebCore/ChangeLog:3 > + Deploy Ref and RefPtr in DOMWindow::scroll* functions This line should be updated to reflect the new bug title. > Source/WebCore/ChangeLog:9 > + Added null pointer check for frame in scrollBy function before usage. > + Test: fast/dom/Window/window-scroll-ignore-null-frame.html Nit: There should be a blank line between the description & Test: ~ line. > LayoutTests/ChangeLog:3 > + Deploy Ref and RefPtr in DOMWindow::scroll* functions Ditto about updating this line. > LayoutTests/ChangeLog:8 > + Addedd null pointer check for frame in scrollBy, before using. This description should be describing what we're doing in LayoutTests directory. In this case, you're only adding a test case so it's sufficient to say: Added a regression test.
Pinki Gyanchandani
Comment 18 2020-01-28 14:37:42 PST
Ryosuke Niwa
Comment 19 2020-01-28 14:42:50 PST
Comment on attachment 389066 [details] Patch View in context: https://bugs.webkit.org/attachment.cgi?id=389066&action=review > LayoutTests/ChangeLog:8 > + Added null pointer check for frame in scrollBy function before usage. Again, this line should describe what change we're making in this directory. e.g. "Added a regression test" > LayoutTests/ChangeLog:10 > + * fast/dom/Window/window-scroll-ignore-null-frame.html: Added. This is missing a line for -expected.txt file.
Pinki Gyanchandani
Comment 20 2020-01-28 14:53:45 PST
Ryosuke Niwa
Comment 21 2020-01-28 15:16:44 PST
Comment on attachment 389069 [details] Patch Cool. r=me.
Ryosuke Niwa
Comment 22 2020-01-28 15:25:32 PST
Let's wait for EWS first. Please also set cq? flag in your patch to ask for your patch to be landed by the commit queue in the future.
Ryosuke Niwa
Comment 23 2020-01-28 18:19:22 PST
Comment on attachment 389069 [details] Patch Looks like iOS EWS is hosed :(
WebKit Commit Bot
Comment 24 2020-01-28 19:02:04 PST
Comment on attachment 389069 [details] Patch Clearing flags on attachment: 389069 Committed r255334: <https://trac.webkit.org/changeset/255334>
WebKit Commit Bot
Comment 25 2020-01-28 19:02:06 PST
All reviewed patches have been landed. Closing bug.
Note You need to log in before you can comment on or make changes to this bug.