https://bugs.kde.org/show_bug.cgi?id=510781

--- Comment #1 from nyanpasu64 <[email protected]> ---
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.

-- 
You are receiving this mail because:
You are watching all bug changes.

Reply via email to