| Summary: | KWin Wayland crash in KWin::ItemRendererOpenGL::createRenderNode | ||
|---|---|---|---|
| Product: | [Plasma] kwin | Reporter: | nyanpasu64 <nyanpasu64> |
| Component: | scene-opengl | Assignee: | KWin default assignee <kwin-bugs-null> |
| Status: | RESOLVED DUPLICATE | ||
| Severity: | crash | CC: | xaver.hugl |
| Priority: | NOR | ||
| Version First Reported In: | 6.4.91 | ||
| Target Milestone: | --- | ||
| Platform: | Arch Linux | ||
| OS: | Linux | ||
| Latest Commit: | Version Fixed/Implemented In: | ||
| Sentry Crash Report: | |||
|
Description
nyanpasu64
2025-10-19 09:36:12 UTC
Loading libkwin.so.6.4.91 into Ghidra and navigating to file(0x34cc95) reveals we're trying to call [RAX + 0xb0] (vtable?) but gdb says RAX is 1.
gdb's disassembly says the crash site is in function (inhale): std::_Function_handler<bool(KWin::Item*), KWin::WorkspaceScene::finalDrawWindow(const KWin::RenderTarget&, const KWin::RenderViewport&, KWin::EffectWindow*, int, const QRegion&, KWin::WindowPaintData&)::<lambda(KWin::Item*)> >::_M_invoke(const std::_Any_data &, KWin::Item *&&)
It appears we're calling a std::function<bool(KWin::Item*)>, and invoking an internal specialization for KWin::WorkspaceScene::finalDrawWindow#lambda. Tracing the call tree, itemrenderer_opengl.cpp:127 is trying to call filter() not holeFilter(). filter is defined as:
[this](Item *item) {
return !painted_delegate->shouldRenderItem(item);
}
In class WorkplaceScene, `SceneView *painted_delegate` lives at offset 72 or 0x48.
I don't know all the layers of C++ stdlib function templating. From the disassembly, it seems we're passed a & (aka pointer) to std::_Any_data, which consists of a this pointer, rather than being passed a this pointer directly, and a & to Item *. Since the lambda has been inlined into the C++ implementation details, we must load this into RAX, (dereferencing RSI from Item*& to Item*), compute &painted_delegate by adding 0x48, and load `SceneView* painted_delegate` into RDI. Then we save the stack pointer into RBP, load the vtable address into RAX, and call shouldRenderItem (vtable + 0xb0) with painted_delegate in RDI and item in RSI.
(gdb) info reg
rax 0x1 1
rbx 0x7ffffac59070 140737400639600
rcx 0x7ffffac59220 140737400640032
rdx 0x7ffffac59070 140737400639600
rsi 0x5564bf3e2fa0 93891193614240
rdi 0x5564bf30b830 93891192731696
rbp 0x7ffffac58b90 0x7ffffac58b90
rsp 0x7ffffac58b90 0x7ffffac58b90
r8 0x7ffffac59200 140737400640000
r9 0x7f689ae09ac0 140087251737280
r10 0x2 2
r11 0x0 0
r12 0x5564bf3e2fa0 93891193614240
r13 0x7ffffac59200 140737400640000
r14 0x5564bd4d9450 93891161068624
r15 0x7ffffac58cf0 140737400638704
rip 0x7f689e14cc95 0x7f689e14cc95 <(long method name omitted)+21>
eflags 0x10206 [ PF IF RF ]
cs 0x33 51
ss 0x2b 43 (https://stackoverflow.com/questions/19502868/meaning-of-cs-and-ss-registers-on-x86-64-linux-in-userland ???)
...fs_base 0x7f6894644400 140087142925312
gs_base 0x0 0
We crashed with RAX=1, meaning that our "SceneView" memory at *painted_delegate is corrupted with a vtable address of 1. gdb says (manually formatted, I hope I didn't break any indentation):
(gdb) print *(KWin::SceneView*)$rdi
$9 = {
<KWin::RenderView> = {
<QObject> = {
_vptr.QObject = 0x1,
... (all non-static variables are 0xffffffffffffffff) ...
m_underlayViews = {
<QListSpecialMethods<KWin::RenderView*>> = {<QListSpecialMethodsBase<KWin::RenderView*>> = {<No data fields>}, <No data fields>},
d = {d = 0xffffffffffffffff, ptr = 0xffffffffffffffff, size = 93891192044384}
}
}
This memory looks well and truly trampled, though I don't know if it's a bad pointer or a use-after-free. Oddly that last size value is a valid heap pointer, to what I don't know:
(gdb) x /64xh 93891192044384
0x5564bf263b60: 0xea30 0xbf36 0x5564 0x0000 0x0000 0x0000 0x0000 0x0000
0x5564bf263b70: 0x0000 0x0000 0x0000 0x0000 0x0000 0x0000 0x0000 0x409e
0x5564bf263b80: 0x0000 0x0000 0xe000 0x4090 0x0002 0x0000 0x0000 0x0000
0x5564bf263b90: 0x0000 0x0000 0x0000 0x0000 0x0000 0x0000 0x0000 0x0000
0x5564bf263ba0: 0x0000 0x0000 0x0000 0x0000 0x0000 0x0000 0x0000 0x0000
0x5564bf263bb0: 0x0003 0x0000 0x0000 0x0000 0x0000 0x0000 0x0000 0x0000
0x5564bf263bc0: 0x0000 0x0000 0x0000 0x0000 0x0000 0x0000 0x0000 0x0000
0x5564bf263bd0: 0x0000 0x0000 0x0000 0x0000 0x0004 0x0000 0x0000 0x0000
In summary, it looks like WorkspaceScene's member SceneView *painted_delegate is pointing to invalid SceneView bytes. Whether the pointer was overwritten with a distinct pointer, or the target was corrupted or freed, I don't know.
For completeness, since you don't have the same binary/disassembly as I do: (gdb) set disassembly-flavor intel (gdb) disas Dump of assembler code for function std::_Function_handler<bool(KWin::Item*), KWin::WorkspaceScene::finalDrawWindow(const KWin::RenderTarget&, const KWin::RenderViewport&, KWin::EffectWindow*, int, const QRegion&, KWin::WindowPaintData&)::<lambda(KWin::Item*)> >::_M_invoke(const std::_Any_data &, KWin::Item *&&): 0x00007f689e14cc80 <+0>: endbr64 0x00007f689e14cc84 <+4>: push rbp 0x00007f689e14cc85 <+5>: mov rax,QWORD PTR [rdi] 0x00007f689e14cc88 <+8>: mov rsi,QWORD PTR [rsi] 0x00007f689e14cc8b <+11>: mov rdi,QWORD PTR [rax+0x48] 0x00007f689e14cc8f <+15>: mov rbp,rsp 0x00007f689e14cc92 <+18>: mov rax,QWORD PTR [rdi] => 0x00007f689e14cc95 <+21>: call QWORD PTR [rax+0xb0] 0x00007f689e14cc9b <+27>: pop rbp 0x00007f689e14cc9c <+28>: xor eax,0x1 0x00007f689e14cc9f <+31>: ret End of assembler dump. *** This bug has been marked as a duplicate of bug 509690 *** |