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

            Bug ID: 71370
           Summary: asan infinite recursion if gcc configured without tls
           Product: gcc
           Version: 5.3.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: sanitizer
          Assignee: unassigned at gcc dot gnu.org
          Reporter: vladimir.simonov at acronis 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: ---

Hi,

If gcc configured x86_64 with --disable-tls below code
crashes in runtime with stack overflow.

#include <cstdio>
#include <cstdlib>

namespace 
{
  class A
  {
  public:
    A() : B(malloc(10))
    {
    }
    ~A()
    {
      free(B);
    }
    void* B;
  };

  A C;
}

int main(int argc, char* argv[])
{
  printf("Hello world!\n");
  return 0;
}


Here is gdb log
Program received signal SIGSEGV, Segmentation fault.
__sanitizer::StackDepotBase<__sanitizer::StackDepotNode, 1, 20>::Put (
    this=this@entry=0x9510a0 <__sanitizer::theDepot>, args=...,
    inserted=inserted@entry=0x0)
    at
../../../../gcc-5.3.0/libsanitizer/sanitizer_common/sanitizer_stackdepotbase.h:95
95     
../../../../gcc-5.3.0/libsanitizer/sanitizer_common/sanitizer_stackdepotbase.h:
No such file or directory.
(gdb) up 10000
#10000 0x00000000004ad512 in __emutls_get_address (
    obj=obj@entry=0x4dbda0 <__emutls_v._ZN6__lsan15disable_counterE>)
    at ../../../gcc-5.3.0/libgcc/emutls.c:159
159     ../../../gcc-5.3.0/libgcc/emutls.c: No such file or directory.
(gdb)
#17245 0x0000000000404d46 in _start ()
(gdb) down
#17244 0x00007ffff751caa5 in __libc_start_main () from /lib64/libc.so.6
(gdb)
#17243 0x00000000004a8ccb in __libc_csu_init ()
(gdb)
#17242 _GLOBAL__sub_I_main.cpp(void) ()
    at H:/AB2/linex/dsk_supp/test/asan/main.cpp:26
26      H:/AB2/linex/dsk_supp/test/asan/main.cpp: No such file or directory.
(gdb)
#17241 __static_initialization_and_destruction_0 (__initialize_p=1,
    __priority=65535) at H:/AB2/linex/dsk_supp/test/asan/main.cpp:19
19      in H:/AB2/linex/dsk_supp/test/asan/main.cpp
(gdb)
#17240 0x0000000000404cba in (anonymous namespace)::A::A (
    this=0x1151d40 <(anonymous namespace)::C>)
    at H:/AB2/linex/dsk_supp/test/asan/main.cpp:9
9       in H:/AB2/linex/dsk_supp/test/asan/main.cpp
(gdb)
#17239 0x000000000047b359 in __interceptor_malloc (size=size@entry=10)
    at ../../../../gcc-5.3.0/libsanitizer/asan/asan_malloc_linux.cc:39
39      ../../../../gcc-5.3.0/libsanitizer/asan/asan_malloc_linux.cc: No such
file or directory.
(gdb)
#17238 0x000000000040b228 in __asan::asan_malloc (size=size@entry=10,
    stack=stack@entry=0x7fffffffdb60)
    at ../../../../gcc-5.3.0/libsanitizer/asan/asan_allocator2.cc:595
595     ../../../../gcc-5.3.0/libsanitizer/asan/asan_allocator2.cc: No such
file or directory.
(gdb)
#17237 0x000000000040ab1a in __asan::Allocate (size=<optimized out>,
    size@entry=10, alignment=<optimized out>, alignment@entry=8,
    stack=stack@entry=0x7fffffffdb60,
    alloc_type=alloc_type@entry=__asan::FROM_MALLOC,
    can_fill=can_fill@entry=true)
    at ../../../../gcc-5.3.0/libsanitizer/asan/asan_allocator2.cc:383
383     in ../../../../gcc-5.3.0/libsanitizer/asan/asan_allocator2.cc
(gdb)
#17236 0x0000000000493db0 in __lsan::DisabledInThisThread ()
    at ../../../../gcc-5.3.0/libsanitizer/lsan/lsan_common.cc:33
33      ../../../../gcc-5.3.0/libsanitizer/lsan/lsan_common.cc: No such file or
directory.
(gdb)
#17235 0x00000000004ad512 in __emutls_get_address (
    obj=obj@entry=0x4dbda0 <__emutls_v._ZN6__lsan15disable_counterE>)
    at ../../../gcc-5.3.0/libgcc/emutls.c:159
159     ../../../gcc-5.3.0/libgcc/emutls.c: No such file or directory.
(gdb)
#17234 0x000000000047b4c6 in __interceptor_calloc (nmemb=nmemb@entry=34,
    size=size@entry=8)
    at ../../../../gcc-5.3.0/libsanitizer/asan/asan_malloc_linux.cc:55
55      ../../../../gcc-5.3.0/libsanitizer/asan/asan_malloc_linux.cc: No such
file or directory.
(gdb)
#17233 0x000000000040b268 in __asan::asan_calloc (nmemb=nmemb@entry=34,
    size=size@entry=8, stack=stack@entry=0x7fffffffd200)
    at ../../../../gcc-5.3.0/libsanitizer/asan/asan_allocator2.cc:601
601     ../../../../gcc-5.3.0/libsanitizer/asan/asan_allocator2.cc: No such
file or directory.
(gdb)
#17232 0x000000000040ab1a in __asan::Allocate (size=<optimized out>,
    size@entry=272, alignment=<optimized out>, alignment@entry=8,
    stack=stack@entry=0x7fffffffd200,
    alloc_type=alloc_type@entry=__asan::FROM_MALLOC,
    can_fill=can_fill@entry=false)
    at ../../../../gcc-5.3.0/libsanitizer/asan/asan_allocator2.cc:383
383     in ../../../../gcc-5.3.0/libsanitizer/asan/asan_allocator2.cc
(gdb)
#17231 0x0000000000493db0 in __lsan::DisabledInThisThread ()
    at ../../../../gcc-5.3.0/libsanitizer/lsan/lsan_common.cc:33
33      ../../../../gcc-5.3.0/libsanitizer/lsan/lsan_common.cc: No such file or
directory.
(gdb)
#17230 0x00000000004ad512 in __emutls_get_address (
    obj=obj@entry=0x4dbda0 <__emutls_v._ZN6__lsan15disable_counterE>)
    at ../../../gcc-5.3.0/libgcc/emutls.c:159
159     ../../../gcc-5.3.0/libgcc/emutls.c: No such file or directory.
(gdb)
#17229 0x000000000047b4c6 in __interceptor_calloc (nmemb=nmemb@entry=34,
    size=size@entry=8)
    at ../../../../gcc-5.3.0/libsanitizer/asan/asan_malloc_linux.cc:55
55      ../../../../gcc-5.3.0/libsanitizer/asan/asan_malloc_linux.cc: No such
file or directory.
(gdb)
#17228 0x000000000040b268 in __asan::asan_calloc (nmemb=nmemb@entry=34,
    size=size@entry=8, stack=stack@entry=0x7fffffffc880)
    at ../../../../gcc-5.3.0/libsanitizer/asan/asan_allocator2.cc:601
601     ../../../../gcc-5.3.0/libsanitizer/asan/asan_allocator2.cc: No such
file or directory.
(gdb)
#17227 0x000000000040ab1a in __asan::Allocate (size=<optimized out>,
    size@entry=272, alignment=<optimized out>, alignment@entry=8,
    stack=stack@entry=0x7fffffffc880,
    alloc_type=alloc_type@entry=__asan::FROM_MALLOC,
    can_fill=can_fill@entry=false)
    at ../../../../gcc-5.3.0/libsanitizer/asan/asan_allocator2.cc:383
383     in ../../../../gcc-5.3.0/libsanitizer/asan/asan_allocator2.cc
(gdb)
#17226 0x0000000000493db0 in __lsan::DisabledInThisThread ()
    at ../../../../gcc-5.3.0/libsanitizer/lsan/lsan_common.cc:33
33      ../../../../gcc-5.3.0/libsanitizer/lsan/lsan_common.cc: No such file or
directory.
(gdb)
#17225 0x00000000004ad512 in __emutls_get_address (
    obj=obj@entry=0x4dbda0 <__emutls_v._ZN6__lsan15disable_counterE>)
    at ../../../gcc-5.3.0/libgcc/emutls.c:159
159     ../../../gcc-5.3.0/libgcc/emutls.c: No such file or directory.
(gdb)
#17224 0x000000000047b4c6 in __interceptor_calloc (nmemb=nmemb@entry=34,
    size=size@entry=8)
    at ../../../../gcc-5.3.0/libsanitizer/asan/asan_malloc_linux.cc:55
55      ../../../../gcc-5.3.0/libsanitizer/asan/asan_malloc_linux.cc: No such
file or directory.
(gdb)


IMO the problem is in __lsan::DisabledInThisThread call from __asan::Allocate.
Call of DisabledInThisThread "instantiates" thread specific "THREADLOCAL int
disable_counter;". But __emutls_get_address (which is used if gcc configured
without tls) in turn requires memory allocation.

I'd suggested something like
--- gcc-5.3.0/libsanitizer/asan/asan_allocator2.cc      2014-11-13
23:41:38.000000000 +0300
+++ gcc-5.3.0/libsanitizer/asan/asan_allocator2.cc      2016-05-27
16:03:55.616269900 +0300
@@ -379,7 +379,8 @@
     REAL(memset)(res, fl.malloc_fill_byte, fill_size);
   }
 #if CAN_SANITIZE_LEAKS
-  m->lsan_tag = __lsan::DisabledInThisThread() ? __lsan::kIgnored
+  if (common_flags()->detect_leaks)
+    m->lsan_tag = __lsan::DisabledInThisThread() ? __lsan::kIgnored
                                                : __lsan::kDirectlyLeaked;
 #endif
   // Must be the last mutation of metadata in this function.

As minimum if gcc is configured without tls asan will work with detect_leaks=0.

Thank you
Vladimir

Reply via email to