AddressSanitizer: heap-buffer-overflow in libxkbcommon-x11.so

Bug #1743401 reported by Oliver Stöneberg
6
This bug affects 1 person
Affects Status Importance Assigned to Milestone
libxkbcommon (Ubuntu)
New
Undecided
Unassigned

Bug Description

I am running an application which has a feature which utilizes Qt5. For testing purposes this application was built with the AddressSanitizer of the official clang 5.0.1 binariesfor ubuntu 16.04. This was working fine until a few days ago. It started out with another user reporting issues with Qt and the pt_BR.UTF-8 locale which I was able to confirm after I installed it. Shorty after that I was no longer able to run anything that used the Qt code. I tried removing the additional locale or setting a different one via the environment, but that didn't help. I also did some changes in the "Text Input" settings like removing removing the "English" keyboard layout before I encountered this.
Unfortunately I didn't have the time yet to set the system back up from scratch and try to reproduce what exact change caused this.

Below I added the traces of ASAN and the debugger.

The code in question is found in xkbcommon/src/x11/util.c

length = xcb_get_atom_name_name_length(reply);
name = xcb_get_atom_name_name(reply);

*out = strndup(name, length);

Unfortunately I was not able to see what "name" is, but length was 8.

lsb_release -rd
Description: Ubuntu 16.04.3 LTS
Release: 16.04

libxkbcommon0:
  Installed: 0.5.0-1ubuntu2
  Candidate: 0.5.0-1ubuntu2
  Version table:
 *** 0.5.0-1ubuntu2 500
        500 http://de.archive.ubuntu.com/ubuntu xenial/main amd64 Packages
        100 /var/lib/dpkg/status

qt5-default:
  Installed: 5.5.1+dfsg-16ubuntu7.5
  Candidate: 5.5.1+dfsg-16ubuntu7.5
  Version table:
 *** 5.5.1+dfsg-16ubuntu7.5 500
        500 http://de.archive.ubuntu.com/ubuntu xenial-updates/universe amd64 Packages
        100 /var/lib/dpkg/status
     5.5.1+dfsg-16ubuntu7 500
        500 http://de.archive.ubuntu.com/ubuntu xenial/universe amd64 Packages

locale
LANG=en_US.UTF-8
LANGUAGE=
LC_CTYPE="en_US.UTF-8"
LC_NUMERIC=de_DE.UTF-8
LC_TIME=de_DE.UTF-8
LC_COLLATE="en_US.UTF-8"
LC_MONETARY=de_DE.UTF-8
LC_MESSAGES="en_US.UTF-8"
LC_PAPER=de_DE.UTF-8
LC_NAME=de_DE.UTF-8
LC_ADDRESS=de_DE.UTF-8
LC_TELEPHONE=de_DE.UTF-8
LC_MEASUREMENT=de_DE.UTF-8
LC_IDENTIFICATION=de_DE.UTF-8
LC_ALL=

==3008==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x60400015c4b8 at pc 0x000001445853 bp 0x7ffd07632920 sp 0x7ffd076320b8
READ of size 9 at 0x60400015c4b8 thread T0
    #0 0x1445852 in __interceptor___strndup /opt/media/clang_nightly/llvm/utils/release/final/llvm.src/projects/compiler-rt/lib/asan/../sanitizer_common/sanitizer_common_interceptors.inc:337:3
    #1 0x7fc1481fd70e (/usr/lib/x86_64-linux-gnu/libxkbcommon-x11.so.0+0x470e)
    #2 0x7fc1481fcd79 in xkb_x11_keymap_new_from_device (/usr/lib/x86_64-linux-gnu/libxkbcommon-x11.so.0+0x3d79)
    #3 0x7fc149cb9c8f (/usr/lib/x86_64-linux-gnu/libQt5XcbQpa.so.5+0x42c8f)
    #4 0x7fc149cba0ec (/usr/lib/x86_64-linux-gnu/libQt5XcbQpa.so.5+0x430ec)
    #5 0x7fc149cb4931 in QXcbConnection::QXcbConnection(QXcbNativeInterface*, bool, unsigned int, char const*) (/usr/lib/x86_64-linux-gnu/libQt5XcbQpa.so.5+0x3d931)
    #6 0x7fc149cb7bac in QXcbIntegration::QXcbIntegration(QStringList const&, int&, char**) (/usr/lib/x86_64-linux-gnu/libQt5XcbQpa.so.5+0x40bac)
    #7 0x7fc149d773ac in _init (/usr/lib/x86_64-linux-gnu/qt5/plugins/platforms/libqxcb.so+0x13ac)
    #8 0x7fc179728d91 in QPlatformIntegrationFactory::create(QString const&, QStringList const&, int&, char**, QString const&) (/usr/lib/x86_64-linux-gnu/libQt5Gui.so.5+0xdfd91)
    #9 0x7fc179734fc3 in QGuiApplicationPrivate::createPlatformIntegration() (/usr/lib/x86_64-linux-gnu/libQt5Gui.so.5+0xebfc3)
    #10 0x7fc179735ecc in QGuiApplicationPrivate::createEventDispatcher() (/usr/lib/x86_64-linux-gnu/libQt5Gui.so.5+0xececc)
    #11 0x7fc1793fd7e5 in QCoreApplication::init() (/usr/lib/x86_64-linux-gnu/libQt5Core.so.5+0x28a7e5)
    #12 0x7fc1793fd855 in QCoreApplication::QCoreApplication(QCoreApplicationPrivate&) (/usr/lib/x86_64-linux-gnu/libQt5Core.so.5+0x28a855)
    #13 0x7fc179737cc8 in QGuiApplication::QGuiApplication(QGuiApplicationPrivate&) (/usr/lib/x86_64-linux-gnu/libQt5Gui.so.5+0xeecc8)
    #14 0x7fc179ceebcc in QApplication::QApplication(int&, char**, int) (/usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5+0x15dbcc)
    #15 0x8c7f4e5 in debug_qt::init_debugger(running_machine&) /mnt/mame/build/projects/sdl/mame/gmake-linux-clang/../../../../../src/osd/modules/debugger/debugqt.cpp:251:7
    #16 0x8c81c6c in non-virtual thunk to debug_qt::init_debugger(running_machine&) /mnt/mame/build/projects/sdl/mame/gmake-linux-clang/../../../../../src/osd/modules/debugger/debugqt.cpp
    #17 0x8af8740 in osd_common_t::init_debugger() /mnt/mame/build/projects/sdl/mame/gmake-linux-clang/../../../../../src/osd/modules/lib/osdobj_common.cpp:498:14
    #18 0xe0bded4 in debugger_manager::debugger_manager(running_machine&) /mnt/mame/build/projects/sdl/mame/gmake-linux-clang/../../../../../src/emu/debugger.cpp:138:16
    #19 0xe69fc1c in make_unique<debugger_manager, running_machine &> /usr/lib/gcc/x86_64-linux-gnu/5.4.0/../../../../include/c++/5.4.0/bits/unique_ptr.h:765:34
    #20 0xe69fc1c in running_machine::start() /mnt/mame/build/projects/sdl/mame/gmake-linux-clang/../../../../../src/emu/machine.cpp:254
    #21 0xe6a2a41 in running_machine::run(bool) /mnt/mame/build/projects/sdl/mame/gmake-linux-clang/../../../../../src/emu/machine.cpp:310:3
    #22 0x8cd10e0 in mame_machine_manager::execute() /mnt/mame/build/projects/sdl/mame/gmake-linux-clang/../../../../../src/frontend/mame/mame.cpp:236:19
    #23 0x8e1e0d3 in cli_frontend::start_execution(mame_machine_manager*, std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > const&) /mnt/mame/build/projects/sdl/mame/gmake-linux-clang/../../../../../src/frontend/mame/clifront.cpp:257:22
    #24 0x8e20ee0 in cli_frontend::execute(std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > >&) /mnt/mame/build/projects/sdl/mame/gmake-linux-clang/../../../../../src/frontend/mame/clifront.cpp:273:3
    #25 0x8cd3717 in emulator_info::start_frontend(emu_options&, osd_interface&, std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > >&) /mnt/mame/build/projects/sdl/mame/gmake-linux-clang/../../../../../src/frontend/mame/mame.cpp:336:18
    #26 0x8acddf2 in main /mnt/mame/build/projects/sdl/mame/gmake-linux-clang/../../../../../src/osd/sdl/sdlmain.cpp:216:9
    #27 0x7fc177bff82f in __libc_start_main /build/glibc-bfm8X4/glibc-2.23/csu/../csu/libc-start.c:291
    #28 0x1431838 in _start (/mnt/mame/mame64_as+0x1431838)

0x60400015c4b8 is located 0 bytes to the right of 40-byte region [0x60400015c490,0x60400015c4b8)
allocated by thread T12 (QXcbEventReader) here:
    #0 0x14d2a23 in malloc /opt/media/clang_nightly/llvm/utils/release/final/llvm.src/projects/compiler-rt/lib/asan/asan_malloc_linux.cc:67:3
    #1 0x7fc174a3e14b (/usr/lib/x86_64-linux-gnu/libxcb.so.1+0xc14b)

Thread T12 (QXcbEventReader) created by T0 here:
    #0 0x14bbd4d in pthread_create /opt/media/clang_nightly/llvm/utils/release/final/llvm.src/projects/compiler-rt/lib/asan/asan_interceptors.cc:317:3
    #1 0x7fc179217d27 in QThread::start(QThread::Priority) (/usr/lib/x86_64-linux-gnu/libQt5Core.so.5+0xa4d27)

SUMMARY: AddressSanitizer: heap-buffer-overflow /opt/media/clang_nightly/llvm/utils/release/final/llvm.src/projects/compiler-rt/lib/asan/../sanitizer_common/sanitizer_common_interceptors.inc:337:3 in __interceptor___strndup
Shadow bytes around the buggy address:
  0x0c0880023840: fa fa fd fd fd fd fd fa fa fa fd fd fd fd fd fa
  0x0c0880023850: fa fa fd fd fd fd fd fa fa fa fd fd fd fd fd fa
  0x0c0880023860: fa fa fd fd fd fd fd fd fa fa fd fd fd fd fd fd
  0x0c0880023870: fa fa fd fd fd fd fd fa fa fa fd fd fd fd fd fa
  0x0c0880023880: fa fa fd fd fd fd fd fa fa fa fd fd fd fd fd fa
=>0x0c0880023890: fa fa 00 00 00 00 00[fa]fa fa fa fa fa fa fa fa
  0x0c08800238a0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c08800238b0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c08800238c0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c08800238d0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c08800238e0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
Shadow byte legend (one shadow byte represents 8 application bytes):
  Addressable: 00
  Partially addressable: 01 02 03 04 05 06 07
  Heap left redzone: fa
  Freed heap region: fd
  Stack left redzone: f1
  Stack mid redzone: f2
  Stack right redzone: f3
  Stack after return: f5
  Stack use after scope: f8
  Global redzone: f9
  Global init order: f6
  Poisoned by user: f7
  Container overflow: fc
  Array cookie: ac
  Intra object redzone: bb
  ASan internal: fe
  Left alloca redzone: ca
  Right alloca redzone: cb

The GDB output:

Thread 1 "mame64_as" received signal SIGABRT, Aborted.
0x00007ffff4412428 in __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:54
#0 0x00007ffff4412428 in __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:54
#1 0x00007ffff441402a in __GI_abort () at abort.c:89
#2 0x00000000014f10a7 in __sanitizer::Abort() () at /opt/media/clang_nightly/llvm/utils/release/final/llvm.src/projects/compiler-rt/lib/sanitizer_common/sanitizer_posix_libcdep.cc:146
#3 0x00000000014ef341 in __sanitizer::Die() () at /opt/media/clang_nightly/llvm/utils/release/final/llvm.src/projects/compiler-rt/lib/sanitizer_common/sanitizer_termination.cc:59
#4 0x00000000014d6e3b in ~ScopedInErrorReport () at /opt/media/clang_nightly/llvm/utils/release/final/llvm.src/projects/compiler-rt/lib/asan/asan_report.cc:225
#5 0x00000000014d7e32 in ReportGenericError () at /opt/media/clang_nightly/llvm/utils/release/final/llvm.src/projects/compiler-rt/lib/asan/asan_report.cc:421
#6 0x000000000144587e in __interceptor___strndup () at /opt/media/clang_nightly/llvm/utils/release/final/llvm.src/projects/compiler-rt/lib/asan/../sanitizer_common/sanitizer_common_interceptors.inc:337
#7 0x00007fffc448270f in get_atom_name (conn=conn@entry=0x62a0000ae200, atom=<optimized out>, out=out@entry=0x61b0000ef400) at src/x11/util.c:146
#8 0x00007fffc4481d7a in get_names (device_id=3, conn=0x62a0000ae200, keymap=0x61b0000eee80) at src/x11/keymap.c:1092
#9 xkb_x11_keymap_new_from_device (ctx=<optimized out>, conn=0x62a0000ae200, device_id=3, flags=flags@entry=XKB_KEYMAP_COMPILE_NO_FLAGS) at src/x11/keymap.c:1169
#10 0x00007fffc5f3ec90 in QXcbKeyboard::updateKeymap (this=this@entry=0x6100002cfc40) at qxcbkeyboard.cpp:710
#11 0x00007fffc5f3f0ed in QXcbKeyboard::QXcbKeyboard (this=0x6100002cfc40, connection=<optimized out>) at qxcbkeyboard.cpp:1148
#12 0x00007fffc5f39932 in QXcbConnection::QXcbConnection (this=0x618000083c80, nativeInterface=<optimized out>, canGrabServer=<optimized out>, defaultVisualId=<optimized out>, displayName=<optimized out>) at qxcbconnection.cpp:596
#13 0x00007fffc5f3cbad in QXcbIntegration::QXcbIntegration (this=<optimized out>, parameters=..., argc=@0x1e87a2c0: 0, argv=0x7ffff5e374e8 <QCoreApplicationPrivate::QCoreApplicationPrivate(int&, char**, unsigned int)::empty>) at qxcbintegration.cpp:177
#14 0x00007fffc5ffc3ad in QXcbIntegrationPlugin::create (this=<optimized out>, system=..., parameters=..., argc=@0x1e87a2c0: 0, argv=0x7ffff5e374e8 <QCoreApplicationPrivate::QCoreApplicationPrivate(int&, char**, unsigned int)::empty>) at qxcbmain.cpp:50
#15 0x00007ffff5f26d92 in loadIntegration (argv=0x7ffff5e374e8 <QCoreApplicationPrivate::QCoreApplicationPrivate(int&, char**, unsigned int)::empty>, argc=@0x1e87a2c0: 0, parameters=..., key=..., loader=0x7ffff6389c70 <_ZZN12_GLOBAL__N_112Q_QGS_loader13innerFunctionEvE6holder>) at kernel/qplatformintegrationfactory.cpp:56
#16 QPlatformIntegrationFactory::create (platform=..., paramList=..., argc=@0x1e87a2c0: 0, argv=argv@entry=0x7ffff5e374e8 <QCoreApplicationPrivate::QCoreApplicationPrivate(int&, char**, unsigned int)::empty>, platformPluginPath=...) at kernel/qplatformintegrationfactory.cpp:73
#17 0x00007ffff5f32fc4 in init_platform (argv=0x7ffff5e374e8 <QCoreApplicationPrivate::QCoreApplicationPrivate(int&, char**, unsigned int)::empty>, argc=<optimized out>, platformThemeName=..., platformPluginPath=..., pluginArgument=...) at kernel/qguiapplication.cpp:1031
#18 QGuiApplicationPrivate::createPlatformIntegration (this=0x613000084240) at kernel/qguiapplication.cpp:1188
#19 0x00007ffff5f33ecd in QGuiApplicationPrivate::createEventDispatcher (this=<optimized out>) at kernel/qguiapplication.cpp:1205
#20 0x00007ffff5bfb7e6 in QCoreApplication::init (this=this@entry=0x60200010dad0) at kernel/qcoreapplication.cpp:768
#21 0x00007ffff5bfb856 in QCoreApplication::QCoreApplication (this=0x60200010dad0, p=...) at kernel/qcoreapplication.cpp:689
#22 0x00007ffff5f35cc9 in QGuiApplication::QGuiApplication (this=0x60200010dad0, p=...) at kernel/qguiapplication.cpp:569
#23 0x00007ffff64ecbcd in QApplication::QApplication (this=0x60200010dad0, argc=@0x1e87a2c0: 0, argv=0x0, _internal=328961) at kernel/qapplication.cpp:568
#24 0x0000000008c7f4e6 in init_debugger () at ../../../../../src/osd/modules/debugger/debugqt.cpp:251
#25 0x0000000008c81c6d in non-virtual thunk to debug_qt::init_debugger(running_machine&) ()
#26 0x0000000008af8741 in init_debugger () at ../../../../../src/osd/modules/lib/osdobj_common.cpp:498
#27 0x000000000e0bded5 in debugger_manager () at ../../../../../src/emu/debugger.cpp:138
#28 0x000000000e69fc1d in make_unique<debugger_manager, running_machine&> () at /usr/lib/gcc/x86_64-linux-gnu/5.4.0/../../../../include/c++/5.4.0/bits/unique_ptr.h:765
#29 start () at ../../../../../src/emu/machine.cpp:254
#30 0x000000000e6a2a42 in run () at ../../../../../src/emu/machine.cpp:310
#31 0x0000000008cd10e1 in execute () at ../../../../../src/frontend/mame/mame.cpp:236
#32 0x0000000008e1e0d4 in start_execution () at ../../../../../src/frontend/mame/clifront.cpp:257
#33 0x0000000008e20ee1 in execute () at ../../../../../src/frontend/mame/clifront.cpp:273
#34 0x0000000008cd3718 in emulator_info::start_frontend(emu_options&, osd_interface&, std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > >&) () at ../../../../../src/frontend/mame/mame.cpp:336
#35 0x0000000008acddf3 in main () at ../../../../../src/osd/sdl/sdlmain.cpp:216

Tags: xenial
affects: xubuntu-meta (Ubuntu) → libxkbcommon (Ubuntu)
tags: added: xenial
Revision history for this message
Oliver Stöneberg (oliverst-s) wrote :

Sorry I didn't think about this before, but I gave the non-ASAN version of the application a spin with valgrind 3.13 and it doesn't report any memory errors with it - so it's possible this is either something valgrind won't catch or a false positive by ASAN.

Revision history for this message
Oliver Stöneberg (oliverst-s) wrote :

I rebuild the package without optimizations got some more data. The ASAN out now matches the gdb one

READ of size 9 at 0x6040001944b8 thread T0
    #0 0x14454c2 in __interceptor_strndup /opt/media/clang_nightly/llvm/utils/release/final/llvm.src/projects/compiler-rt/lib/asan/../sanitizer_common/sanitizer_common_interceptors.inc:327:3
    #1 0x7ffa3f4b06f8 in get_atom_name /home/user/libxkbcommon-0.5.0/src/x11/util.c:146
    #2 0x7ffa3f4afd63 in get_names /home/user/libxkbcommon-0.5.0/src/x11/keymap.c:1092
    #3 0x7ffa3f4b026c in xkb_x11_keymap_new_from_device /home/user/libxkbcommon-0.5.0/src/x11/keymap.c:1169

Looking at the variables in the debugger everything seems fine

#7 0x00007fffc44236f9 in get_atom_name (conn=0x62a0000ae200, atom=142,
    out=0x61b0000ef400) at src/x11/util.c:146
146 *out = strndup(name, length);
(gdb) print length
$1 = 8
(gdb) print name
$2 = 0x6040001944b0 "complete"
(gdb) print name[7]
$3 = 101 'e'
(gdb) print name[8]
$4 = 0 '\000'

But judging from the error message somehow the ASAN peaks beyond its end.

I was able reproduce this behavior in a small sample and it turns out it is caused by ASAN_OPTIONS=strict_string_checks=1. So it seems it is a sanitizer issue. I will bring it up with that team.

Sorry about the apparently faulty report.

To post a comment you must log in.
This report contains Public information  
Everyone can see this information.

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.