https://gcc.gnu.org/bugzilla/show_bug.cgi?id=77538

            Bug ID: 77538
           Summary: segmentation fault: thread sanitizer shadow stack
                    overflow
           Product: gcc
           Version: 4.8.2
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: sanitizer
          Assignee: unassigned at gcc dot gnu.org
          Reporter: coollpe at hotmail dot com
                CC: dodji at gcc dot gnu.org, dvyukov at gcc dot gnu.org,
                    jakub at gcc dot gnu.org, kcc at gcc dot gnu.org
  Target Milestone: ---

The stack back trace showed there is an overflow of shadow stack and caused the
corruption of mset (size_ is written as a strange number in this overflow)

[Switching to Thread 0x7fffe35fc700 (LWP 29912)]
Hardware watchpoint 6: *0x7fffe3562080

Old value = 1
New value = -150984400
__tsan::FuncEntry (thr=thr@entry=0x7fffe3477840, pc=pc@entry=140737337370928)
at ../../../../libsanitizer/tsan/tsan_rtl.cc:583
583     ../../../../libsanitizer/tsan/tsan_rtl.cc: No such file or directory.
(gdb) bt
#0  __tsan::FuncEntry (thr=thr@entry=0x7fffe3477840,
pc=pc@entry=140737337370928) at ../../../../libsanitizer/tsan/tsan_rtl.cc:583
#1  0x00007ffff6f6c97d in ScopedInterceptor::ScopedInterceptor
(this=0x7fffe34766d0, thr=0x7fffe3477840, fname=<optimized out>,
pc=140737337370928)
    at ../../../../libsanitizer/tsan/tsan_interceptors.cc:158
#2  0x00007ffff6f6e0d7 in __interceptor_memcmp (s1=0x7d06000b1108,
s2=0x7d06001a85a8, n=16) at
../../../../libsanitizer/tsan/tsan_interceptors.cc:470
#3  0x00007ffff7002930 in std::char_traits<char>::compare (__s1=0x7d06000b1108
"table_empty_node", __s2=0x7d06001a85a8 "table_empty_node", __n=16)
    at
/home/opt/gcc-4.8.2.bpkg-r2/gcc-4.8.2.bpkg-r2/include/c++/4.8.2/bits/char_traits.h:255
#4  0x00007ffff7002e66 in std::operator==<char> (__lhs=..., __rhs=...) at
/home/opt/gcc-4.8.2.bpkg-r2/gcc-4.8.2.bpkg-r2/include/c++/4.8.2/bits/basic_string.h:2497
#5  0x00007ffff7015ed2 in std::equal_to<std::string>::operator()
(this=0x7d0e0000c752, __x=..., __y=...)
    at
/home/opt/gcc-4.8.2.bpkg-r2/gcc-4.8.2.bpkg-r2/include/c++/4.8.2/bits/stl_function.h:208
#6  0x00007ffff73accdb in __gnu_cxx::hashtable<std::pair<std::string const,
armor::Table*>, std::string, __gnu_cxx::hash<std::string>,
std::_Select1st<std::pair<std::string
const, armor::Table*> >, std::equal_to<std::string>,
std::allocator<armor::Table*> >::find (this=0x7d0e0000c750, __key=...)
    at
/home/opt/gcc-4.8.2.bpkg-r2/gcc-4.8.2.bpkg-r2/include/c++/4.8.2/backward/hashtable.h:539
#7  0x00007ffff73a921f in __gnu_cxx::hash_map<std::string, armor::Table*,
__gnu_cxx::hash<std::string>, std::equal_to<std::string>,
std::allocator<armor::Table*> >::find (
    this=0x7d0e0000c750, __key=...) at
/home/opt/gcc-4.8.2.bpkg-r2/gcc-4.8.2.bpkg-r2/include/c++/4.8.2/ext/hash_map:217

gdb output:
(gdb) frame 0
#0  __tsan::FuncEntry (thr=thr@entry=0x7fffe3477840,
pc=pc@entry=140737337370928) at ../../../../libsanitizer/tsan/tsan_rtl.cc:583
583     in ../../../../libsanitizer/tsan/tsan_rtl.cc
(gdb) p thr->shadow_stack_pos
$24 = (__sanitizer::uptr *) 0x7fffe3562080
(gdb) p &thr->shadow_stack[kShadowStackSize]
$25 = (unsigned long *) 0x7fffe3562080
(gdb) p &thr->shadow_stack_pos[0]
$26 = (__sanitizer::uptr *) 0x7fffe3562080

The source code:
libsanitizer/tsan/tsan_rtl.cc:582
  thr->shadow_stack_pos[0] = pc;

The definition:
libsanitizer/tsan/tsan_rtl.h:360
  uptr shadow_stack[kShadowStackSize];
#else
  // Go uses satellite shadow stack with dynamic size.
  uptr *shadow_stack;
  uptr *shadow_stack_end;
#endif
  MutexSet mset;

So the overflow caused the corruption of mset, and later the size_ in mset is
corrupted, this caused the segmentation fault when accessed later.

Reply via email to