pioneerspacesim / pioneer

A game of lonely space adventure
https://pioneerspacesim.net
1.62k stars 376 forks source link

Heap use after free in audio thread. #2724

Open lwho opened 10 years ago

lwho commented 10 years ago

Just got another use-after-free report by the memory checker, when the game was exiting after a Lua error (#2701). Unfortunately, it was a release build, so quite incomplete stacktrace. Just tracking it now, so it doesn't get forgotten.

==1875== ERROR: AddressSanitizer: heap-use-after-free on address 0x600e00345ea4 at pc 0x6e10ad bp 0x7fffd099f000 sp 0x7fffd099eff8
READ of size 4 at 0x600e00345ea4 thread T4 (SDLAudioDev1)
    #0 0x6e10ac in fill_audio /home/lw/pioneer/lwho_pioneer/src/Sound.cpp:414
    #1 0x7ffff7ed4dbd in ?? ??:0
    #2 0x7ffff7f2204c in ?? ??:0
    #3 0x7ffff7f69278 in ?? ??:0
    #4 0x7ffff4e63cf7 in ?? ??:0
    #5 0x7ffff4666e99 in start_thread /build/buildd/eglibc-2.15/nptl/pthread_create.c:308
    #6 0x7ffff26343fc in ?? /build/buildd/eglibc-2.15/misc/../sysdeps/unix/sysv/linux/x86_64/clone.S:112
0x600e00345ea4 is located 52 bytes inside of 80-byte region [0x600e00345e70,0x600e00345ec0)
freed by thread T0 here:
    #0 0x7ffff4e5cb1a in ?? ??:0
    #1 0x6e59ec in __gnu_cxx::new_allocator<std::_Rb_tree_node<std::pair<std::string const, Sound::Sample> > >::deallocate(std::_Rb_tree_node<std::pair<std::string const, Sound::Sample> >*, unsigned long) /usr/include/c++/4.8/ext/new_allocator.h:110
previously allocated by thread T0 here:
    #0 0x7ffff4e5c95a in ?? ??:0
    #1 0x6e6db2 in __gnu_cxx::new_allocator<std::_Rb_tree_node<std::pair<std::string const, Sound::Sample> > >::allocate(unsigned long, void const*) /usr/include/c++/4.8/ext/new_allocator.h:104
    #2 0x0
Thread T4 (SDLAudioDev1) created by T0 here:
    #0 0x7ffff4e55c6b in ?? ??:0
    #1 0x7ffff7f692d1 in ?? ??:0
Shadow bytes around the buggy address:
  0x0c0240060b80: 00 00 00 00 fa fa fa fa 00 00 00 00 00 00 00 00
  0x0c0240060b90: 00 00 fa fa fa fa fd fd fd fd fd fd fd fd fd fa
  0x0c0240060ba0: fa fa fa fa 00 00 00 00 00 00 00 00 00 00 fa fa
  0x0c0240060bb0: fa fa fd fd fd fd fd fd fd fd fd fa fa fa fa fa
  0x0c0240060bc0: 00 00 00 00 00 00 00 00 00 fa fa fa fa fa fd fd
=>0x0c0240060bd0: fd fd fd fd[fd]fd fd fd fa fa fa fa 00 00 00 00
  0x0c0240060be0: 00 00 00 00 00 fa fa fa fa fa fd fd fd fd fd fd
  0x0c0240060bf0: fd fd fd fa fa fa fa fa fd fd fd fd fd fd fd fd
  0x0c0240060c00: fd fa fa fa fa fa 00 00 00 00 00 00 00 00 00 fa
  0x0c0240060c10: fa fa fa fa 00 00 00 00 00 00 00 00 00 fa fa fa
  0x0c0240060c20: fa fa 00 00 00 00 00 00 00 00 00 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
  Heap righ redzone:     fb
  Freed Heap region:     fd
  Stack left redzone:    f1
  Stack mid redzone:     f2
  Stack right redzone:   f3
  Stack partial redzone: f4
  Stack after return:    f5
  Stack use after scope: f8
  Global redzone:        f9
  Global init order:     f6
  Poisoned by user:      f7
  ASan internal:         fe
==1875== ABORTING
jaj22 commented 7 years ago

Unless I'm missing a mechanism, Pioneer lua errors skip the cleanup and just exit(1). Apparently the audio mixer thread was still running while either the heap or static memory was being deallocated, which is interesting but not wholly unexpected.

The cplusplus reference includes the following caveat, which seems to cover it:

Calling this function destroys all objects with static duration: A program with multiple threads running shall not call exit (see quick_exit for a similar function that does not affect static objects).