https://bugs.winehq.org/show_bug.cgi?id=51496
Bug ID: 51496 Summary: On KDE riched20:editor triggers a clipboard infinite loop, crashing explorer.exe Product: Wine Version: unspecified Hardware: x86-64 OS: Linux Status: NEW Severity: normal Priority: P2 Component: -unknown Assignee: wine-bugs@winehq.org Reporter: fgouget@codeweavers.com Distribution: ---
Created attachment 70337 --> https://bugs.winehq.org/attachment.cgi?id=70337 Minimal riched20:editor test to reproduce the crash
On my machine, running riched20:editor results in one of explorer.exe's threads being terminated following a stack overflow caused by a clipboard infinite loop:
0098:trace:clipboard:X11DRV_SelectionRequest got request on e00004 for selection "CLIPBOARD" target "STRING" win 3af prop "STRING" 0098:trace:clipboard:OpenClipboard 00010040
0098:trace:clipboard:GetClipboardData (CF_UNICODETEXT) 0098:trace:clipboard:GetClipboardData status=0 data 00A127D8 size=0 seqno 10 0098:trace:clipboard:GetClipboardData render=1 from=CF_TEXT 0098:trace:clipboard:GetClipboardData calling render_synthesized_format 0098:trace:clipboard:render_synthesized_format (CF_UNICODETEXT, CF_TEXT) 0098:err:clipboard:render_synthesized_format calling GetClipboardData
0098:trace:clipboard:GetClipboardData (CF_TEXT) 0098:trace:clipboard:GetClipboardData status=0 data 00A127D8 size=0 seqno 8 0098:trace:clipboard:GetClipboardData render=1 from=CF_UNICODETEXT 0098:trace:clipboard:GetClipboardData calling render_synthesized_format 0098:trace:clipboard:render_synthesized_format (CF_TEXT, CF_UNICODETEXT) 0098:err:clipboard:render_synthesized_format calling GetClipboardData
0098:trace:clipboard:GetClipboardData (CF_UNICODETEXT) 0098:trace:clipboard:GetClipboardData status=0 data 00A127D8 size=0 seqno 10 0098:trace:clipboard:GetClipboardData render=1 from=CF_TEXT 0098:trace:clipboard:GetClipboardData calling render_synthesized_format 0098:trace:clipboard:render_synthesized_format (CF_UNICODETEXT, CF_TEXT) 0098:err:clipboard:render_synthesized_format calling GetClipboardData
0098:trace:clipboard:GetClipboardData (CF_TEXT) ...
This happens specifically on KDE because KDE's clipboard manager queries Wine's clipboard content.
Notes: * The TestBot Wine VM(s) do not run KDE or any form of clipboard manager which is why they are not impacted. * Since 308a5e7 the crash happens while explorer holds the "main process heap" critical section causing it to be unresponsive from that point forward:
006c:err:ntdll:RtlpWaitForCriticalSection section 00480094 "dlls/ntdll/heap.c: main process heap section" wait timed out in thread 006c, blocked by 0098, retrying (60 sec)
* In turn this causes many timeouts in winetest.exe which is why my machine has not been submitting results since then. * This bug was already present before 308a5e7. * At the time the stack overflow did not happen while the critical section was being held so the consequences were not as far ranging which allowed winetest.exe to complete (almost?) normally.
https://bugs.winehq.org/show_bug.cgi?id=51496
François Gouget fgouget@codeweavers.com changed:
What |Removed |Added ---------------------------------------------------------------------------- Keywords| |source, testcase
https://bugs.winehq.org/show_bug.cgi?id=51496
Bernhard Übelacker bernhardu@mailbox.org changed:
What |Removed |Added ---------------------------------------------------------------------------- CC| |bernhardu@mailbox.org
--- Comment #1 from Bernhard Übelacker bernhardu@mailbox.org --- Created attachment 70343 --> https://bugs.winehq.org/attachment.cgi?id=70343 Remove in release_clipboard entries where the depending entry got removed.
I tried to collect some more information.
As far as I see in wineservers clipboard objects format list appears an entry similar to that one with id=13=CF_UNICODETEXT: (rr) print *(struct clip_format *)clipboard->formats->next $148 = {entry = {}, id = 13, from = 0, seqno = 10, size = 0, data = 0x0}
A little later it looks like another entry appears that is derived from that one, this with id=1=CF_TEXT: (rr) print *(struct clip_format *)clipboard->formats->next->...next->next $154 = {entry = {}, id = 1, from = 13, seqno = 16, size = 0, data = 0x0}
Then in a request release_clipboard the first entry gets removed from the list. (rr) print *(struct clip_format *)clipboard->formats->next->...->next $57 = {entry = {}, id = 13, from = 1, seqno = 18, size = 0, data = 0x0}
And now a call GetClipboardData(CF_UNICODETEXT) by explorer.exe recreates an entry with id=13=CF_UNICODETEXT, but now with from=1=CF_TEXT:
That way GetClipboardData never returns because the wineserver request CF_UNICODETEXT returns the depending CF_TEXT and vice versa.
(rr) bt #0 GetClipboardData@4 (format=1) at dlls/user32/clipboard.c:1035 #1 0x6ed0f4e6 in GetClipboardData@4 () at dlls/user32/clipboard.c:581 #2 0x6ed0f4e6 in GetClipboardData@4 () at dlls/user32/clipboard.c:581 #3 0x6ed0f4e6 in GetClipboardData@4 () at dlls/user32/clipboard.c:581 #4 0x6ed0f4e6 in GetClipboardData@4 () at dlls/user32/clipboard.c:581 #5 0x6ed0f4e6 in GetClipboardData@4 () at dlls/user32/clipboard.c:581 #6 0x7e702b48 in export_selection () at dlls/winex11.drv/clipboard.c:1505 #7 0x7e7041db in X11DRV_SelectionRequest at dlls/winex11.drv/clipboard.c:2120 #8 0x7e708dba in call_event_handler () at dlls/winex11.drv/event.c:405 #9 0x7e708f2b in process_events () at dlls/winex11.drv/event.c:460 #10 0x7e7090c4 in X11DRV_MsgWaitForMultipleObjectsEx event.c:500 #11 0x6edad1f3 in wait_message () at dlls/user32/winproc.c:1164 #12 0x6ed6025b in wait_objects () at dlls/user32/message.c:3007 #13 0x6ed68b46 in GetMessageW@16 () at dlls/user32/message.c:3815 #14 0x7e704024 in clipboard_thread () at dlls/winex11.drv/clipboard.c:2071 #15 0x7b62e250 in WriteTapemark@16 ()
Attached draft patch is an attempt to remove also the entry with from=13, when the entry with id=13 is removed in release_clipboard.
Then I could not observe the crash, but some tests fail, maybe visible because of the KDE desktop. It passed here: https://testbot.winehq.org/JobDetails.pl?Key=94491
https://bugs.winehq.org/show_bug.cgi?id=51496
François Gouget fgouget@codeweavers.com changed:
What |Removed |Added ---------------------------------------------------------------------------- Blocks| |48112
https://bugs.winehq.org/show_bug.cgi?id=51496
François Gouget fgouget@codeweavers.com changed:
What |Removed |Added ---------------------------------------------------------------------------- Keywords| |patch Assignee|wine-bugs@winehq.org |fgouget@codeweavers.com
--- Comment #2 from François Gouget fgouget@codeweavers.com --- Thanks a lot for the patch, it pinpointed the source of the issue.
Looking into it I figured out that the patch can be simplified: * Only the Wine server can set the from field. * The from field also can only reference entries that precede it in the list because the synthesized formats must have a lower priority. That means when we loop other the list the formats referenced by the from field will be removed first. * All the synthesized formats are below CF_MAX.
All that combined means we can check whether the format referenced by the from field is 'present' by checking the format_map field which simplifies the code. So I submitted a patch based on that idea.
https://www.winehq.org/pipermail/wine-devel/2021-August/192280.html
I also wanted a test that can reproduce the issue to be sure I understood it correctly. I also submitted a user32:clipboard patch for that:
https://www.winehq.org/pipermail/wine-devel/2021-August/192279.html
https://bugs.winehq.org/show_bug.cgi?id=51496
François Gouget fgouget@codeweavers.com changed:
What |Removed |Added ---------------------------------------------------------------------------- Status|NEW |RESOLVED Resolution|--- |FIXED Fixed by SHA1| |a716b13974b43bd0dd80322fd85 | |84cc96f2f8f3b
--- Comment #3 from François Gouget fgouget@codeweavers.com --- This is fixed.
commit a716b13974b43bd0dd80322fd8584cc96f2f8f3b Author: Francois Gouget fgouget@codeweavers.com Date: Tue Aug 10 05:51:46 2021 +0200
server: Remove obsolete synthesized formats in release_clipboard().
Synthesized formats must be removed too if the format they depend on has been removed.
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=51496 Signed-off-by: Francois Gouget fgouget@codeweavers.com Signed-off-by: Alexandre Julliard julliard@winehq.org
And the patch below added a test reproducing the issue:
commit ce98c3b58e1006c86b1ab5d1600e0c2d2b56413e Author: Francois Gouget fgouget@codeweavers.com Date: Tue Aug 10 05:51:39 2021 +0200
user32/tests: Test delayed clipboard rendering after window destruction.
If the window does not render the delayed-rendering clipboard formats before it is destroyed, then they should be removed from the clipboard, including the derived formats added by CloseClipboard().
Signed-off-by: Francois Gouget fgouget@codeweavers.com Signed-off-by: Alexandre Julliard julliard@winehq.org
https://bugs.winehq.org/show_bug.cgi?id=51496
Alexandre Julliard julliard@winehq.org changed:
What |Removed |Added ---------------------------------------------------------------------------- Status|RESOLVED |CLOSED
--- Comment #4 from Alexandre Julliard julliard@winehq.org --- Closing bugs fixed in 6.15.