[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#857264: plasma-workspace: xembedsniproxy often segfaults



Control: forward -1 https://bugs.kde.org/show_bug.cgi?id=359664
Control: tags -1 upstream fixed-upstream
Control: fixed -1 plasma-workspace/4:5.12.0-2


Dear Maintainer, hello Michael Meier,
from the segfault line I would suspect that this
crash happened in sniproxy.cpp, line 273.

There image may contain NULL that gets unconditionally
dereferenced.

Upstream would have fixed it in [1], contained first in 5.12.
Also applied in branch 5.8 [2], contained first in 5.8.9.
Upstream bug report would be [3].

This bug may still show up in current stretch version.

Kind regards,
Bernhard


[1] https://cgit.kde.org/plasma-workspace.git/commit/?id=e2b7c395ecdb660b7bec960f3c938fba175ca4f8
[2] https://cgit.kde.org/plasma-workspace.git/commit/?h=Plasma/5.8&id=12e3568042fb365aad3eccf2fefa58bbeb065210
[3] https://bugs.kde.org/show_bug.cgi?id=359664

-------

   0x000055555556022d <+109>:   callq  0x555555559bf0 <xcb_image_get@plt>
   0x0000555555560256 <+150>:   mov    %rax,%rbx

271
272         // Don't hook up cleanup yet, we may use a different QImage after all
273         QImage naiveConversion = QImage(image->data, image->width, image->height, QImage::Format_ARGB32);
   0x0000555555560232 <+114>:   movzwl 0x2(%rax),%ecx                                                                           <<<<<<<<<<<<
   0x0000555555560236 <+118>:   movzwl (%rax),%edx

-------

259     QImage SNIProxy::getImageNonComposite() const
260     {
...
270         xcb_image_t *image = xcb_image_get(c, m_windowId, 0, 0, geom->width, geom->height, 0xFFFFFFFF, XCB_IMAGE_FORMAT_Z_PIXMAP);
271
272         // Don't hook up cleanup yet, we may use a different QImage after all
273         QImage naiveConversion = QImage(image->data, image->width, image->height, QImage::Format_ARGB32);
# Jessie amd64 qemu VM

apt update
apt dist-upgrade


approx:
debian-9-stretch-snapshot.debian.org                https://snapshot.debian.org/archive/debian/20170310T000000Z/
debian-9-stretch-debug-snapshot.debian.org          https://snapshot.debian.org/archive/debian-debug/20170310T000000Z/


sources.list:
# snapshot
deb     [check-valid-until=no] http://192.168.178.25:9999/debian-9-stretch-snapshot.debian.org/ stretch main
deb-src [check-valid-until=no] http://192.168.178.25:9999/debian-9-stretch-snapshot.debian.org/ stretch main
deb     [check-valid-until=no] http://192.168.178.25:9999/debian-9-stretch-debug-snapshot.debian.org/ stretch-debug main

apt-get -o Acquire::Check-Valid-Until=false -o Acquire::Languages=none update
apt dist-upgrade
reboot


apt install xserver-xorg sddm kde-plasma-desktop binutils gdb elfutils plasma-workspace-dbgsym
apt install dpkg-dev devscripts




mkdir source/plasma-workspace/orig -p
cd    source/plasma-workspace/orig
apt source plasma-workspace
cd


benutzer@debian:~$ dpkg -l | grep plasma-workspace
ii  plasma-workspace                              4:5.8.4-1                              amd64        Plasma Workspace for KF5
ii  plasma-workspace-dbgsym                       4:5.8.4-1                              amd64        Debug symbols for plasma-workspace


##############


From https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=857264:
[   49.752174] xembedsniproxy[5458]: segfault at 2 ip 0000561b56ae2232 sp 00007ffffb32c330 error 4 in xembedsniproxy[561b56ad6000+14000]



https://www.enodev.fr/posts/decode-segfault-errors-in-dmesg.html
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/tree/arch/x86/mm/fault.c?h=linux-4.9.y#n31


------


/*
 * Page fault error code bits:
 *
 *   bit 0 ==	 0: no page found	1: protection fault
 *   bit 1 ==	 0: read access		1: write access
 *   bit 2 ==	 0: kernel-mode access	1: user-mode access
 *   bit 3 ==				1: use of reserved bit detected
 *   bit 4 ==				1: fault was an instruction fetch
 *   bit 5 ==				1: protection keys block access
 */
enum x86_pf_error_code {

	PF_PROT		=		1 << 0,
	PF_WRITE	=		1 << 1,
	PF_USER		=		1 << 2,
	PF_RSVD		=		1 << 3,
	PF_INSTR	=		1 << 4,
	PF_PK		=		1 << 5,
};


"error 4" == 0b100

bit 0 ==	 0: no page found
bit 1 ==	 0: read access
bit 2 ==	 1: user-mode access


------



# Create a 'unstripped' binary

benutzer@debian:~$ gdb -q -ex quit --args /usr/bin/xembedsniproxy
Reading symbols from /usr/bin/xembedsniproxy...Reading symbols from /usr/lib/debug/.build-id/78/036ce04f32f09dd53a566ea3e172453fd64037.debug...done.
done.


cp -a /usr/bin/xembedsniproxy /tmp/xembedsniproxy
cp -a /usr/lib/debug/.build-id/78/036ce04f32f09dd53a566ea3e172453fd64037.debug /tmp/036ce04f32f09dd53a566ea3e172453fd64037.debug
eu-unstrip /tmp/xembedsniproxy /tmp/036ce04f32f09dd53a566ea3e172453fd64037.debug


benutzer@debian:~$ objdump --disassemble /tmp/036ce04f32f09dd53a566ea3e172453fd64037.debug | grep -E "232:|^00000" | grep "232:" -B1
00000000000071a0 <_ZN17QtMetaTypePrivate23QMetaTypeFunctionHelperI18KDbusToolTipStructLb1EE8DestructEPv>:
    7232:       ba 08 00 00 00          mov    $0x8,%edx
--
0000000000008230 <_ZN19FdoSelectionManager18compositingChangedEv>:
    8232:       55                      push   %rbp
--
000000000000c1c0 <_ZNK8SNIProxy20getImageNonCompositeEv>:
    c232:       0f b7 48 02             movzwl 0x2(%rax),%ecx
--
000000000000d220 <_ZNK25StatusNotifierItemAdaptor2idEv>:
    d232:       64 48 8b 04 25 28 00    mov    %fs:0x28,%rax
--
000000000000e0a0 <_ZN36OrgKdeStatusNotifierWatcherInterface18qt_static_metacallEP7QObjectN11QMetaObject4CallEiPPv>:
    e232:       83 f8 01                cmp    $0x1,%eax


-> _ZNK8SNIProxy20getImageNonCompositeEv looks most promising -> read at offset 0x2 matches


------


gdb -q \
    -ex 'set width 0' \
    -ex 'set pagination off' \
    -ex 'directory /home/benutzer/source/plasma-workspace/orig/plasma-workspace-5.8.4' \
    -ex 'break main' \
    -ex 'run' \
    -ex 'dele 1' \
    --args /usr/bin/xembedsniproxy


benutzer@debian:~$ gdb -q \
>     -ex 'set width 0' \
>     -ex 'set pagination off' \
>     -ex 'directory /home/benutzer/source/plasma-workspace/orig/plasma-workspace-5.8.4' \
>     -ex 'break main' \
>     -ex 'run' \
>     -ex 'dele 1' \
>     --args /usr/bin/xembedsniproxy
Reading symbols from /usr/bin/xembedsniproxy...Reading symbols from /usr/lib/debug/.build-id/78/036ce04f32f09dd53a566ea3e172453fd64037.debug...done.
done.
Source directories searched: /home/benutzer/source/plasma-workspace/orig/plasma-workspace-5.8.4:$cdir:$cwd
Breakpoint 1 at 0x6790: file ./xembed-sni-proxy/main.cpp, line 39.
Starting program: /usr/bin/xembedsniproxy 
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".

Breakpoint 1, main (argc=1, argv=0x7fffffffe688) at ./xembed-sni-proxy/main.cpp:39
39      {

(gdb) break _ZNK8SNIProxy20getImageNonCompositeEv
Breakpoint 2 at 0x5555555601c0: file ./xembed-sni-proxy/sniproxy.cpp, line 260.
(gdb) info b
Num     Type           Disp Enb Address            What
2       breakpoint     keep y   0x00005555555601c0 in SNIProxy::getImageNonComposite() const at ./xembed-sni-proxy/sniproxy.cpp:260

(gdb) disassemble /m _ZNK8SNIProxy20getImageNonCompositeEv
Dump of assembler code for function SNIProxy::getImageNonComposite() const:
260     {
...
270         xcb_image_t *image = xcb_image_get(c, m_windowId, 0, 0, geom->width, geom->height, 0xFFFFFFFF, XCB_IMAGE_FORMAT_Z_PIXMAP);
   0x0000555555560212 <+82>:    movzwl 0x12(%rax),%r9d
   0x0000555555560217 <+87>:    movzwl 0x10(%rax),%r8d
   0x000055555556021c <+92>:    xor    %ecx,%ecx
   0x000055555556021e <+94>:    mov    0x18(%rbp),%esi
   0x0000555555560221 <+97>:    pushq  $0x2
   0x0000555555560223 <+99>:    xor    %edx,%edx
   0x0000555555560225 <+101>:   pushq  $0xffffffffffffffff
   0x0000555555560227 <+103>:   mov    %rbx,%rdi
   0x000055555556022a <+106>:   mov    %rax,%r12
   0x000055555556022d <+109>:   callq  0x555555559bf0 <xcb_image_get@plt>
   0x0000555555560256 <+150>:   mov    %rax,%rbx

271
272         // Don't hook up cleanup yet, we may use a different QImage after all
273         QImage naiveConversion = QImage(image->data, image->width, image->height, QImage::Format_ARGB32);
   0x0000555555560232 <+114>:   movzwl 0x2(%rax),%ecx                                                                           <<<<<<<<<<<<
   0x0000555555560236 <+118>:   movzwl (%rax),%edx
   0x0000555555560239 <+121>:   lea    0x50(%rsp),%r14
   0x000055555556023e <+126>:   mov    0x28(%rax),%rsi
   0x0000555555560242 <+130>:   xor    %r9d,%r9d
   0x0000555555560245 <+133>:   mov    $0x5,%r8d
   0x000055555556024b <+139>:   mov    %r14,%rdi
   0x000055555556024e <+142>:   movq   $0x0,(%rsp)
   0x0000555555560259 <+153>:   callq  0x555555559c30 <_ZN6QImageC1EPhiiNS_6FormatEPFvPvES2_@plt>
   0x0000555555560297 <+215>:   mov    %r14,%rdi
   0x000055555556029a <+218>:   callq  0x555555559f80 <_ZN6QImageD1Ev@plt>

274
275         if (isTransparentImage(naiveConversion)) {
...
End of assembler dump.

(gdb) list SNIProxy::getImageNonComposite
258
259     QImage SNIProxy::getImageNonComposite() const
260     {
261         auto c = QX11Info::connection();
262         auto cookie = xcb_get_geometry(c, m_windowId);
263         QScopedPointer<xcb_get_geometry_reply_t, QScopedPointerPodDeleter>
264             geom(xcb_get_geometry_reply(c, cookie, Q_NULLPTR));
265
266         if (!geom) {
267             return QImage();
268         }
269
270         xcb_image_t *image = xcb_image_get(c, m_windowId, 0, 0, geom->width, geom->height, 0xFFFFFFFF, XCB_IMAGE_FORMAT_Z_PIXMAP);
271
272         // Don't hook up cleanup yet, we may use a different QImage after all
273         QImage naiveConversion = QImage(image->data, image->width, image->height, QImage::Format_ARGB32);
274
275         if (isTransparentImage(naiveConversion)) {
276             QImage elaborateConversion = QImage(convertFromNative(image));
277
278             // Update icon only if it is at least partially opaque.
279             // This is just a workaround for X11 bug: xembed icon may suddenly
280             // become transparent for a one or few frames. Reproducible at least
281             // with WINE applications.
282             if (isTransparentImage(elaborateConversion)) {
283                 qCDebug(SNIPROXY) << "Skip transparent xembed icon for" << m_windowId << Title();
284                 return QImage();
285             } else
286                 return elaborateConversion;
287         } else {
288             // Now we are sure we can eventually delete the xcb_image_t with this version
289             return QImage(image->data, image->width, image->height, image->stride, QImage::Format_ARGB32, sni_cleanup_xcb_image, image);
290         }
291     }



... I knew that I have seen this already ...

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

Branch master, seems v5.12.0 was the first release containing it:
https://cgit.kde.org/plasma-workspace.git/commit/?id=e2b7c395ecdb660b7bec960f3c938fba175ca4f8

Branch 5.8, Tag v5.8.9 contains it:
https://cgit.kde.org/plasma-workspace.git/commit/?h=Plasma/5.8&id=12e3568042fb365aad3eccf2fefa58bbeb065210

Reply to: