[libcxx-commits] [PATCH] D122864: [libc++] Avoid lifetime UB in __thread_local_data()

Vitaly Buka via Phabricator via libcxx-commits libcxx-commits at lists.llvm.org
Thu Mar 31 22:02:24 PDT 2022


vitalybuka created this revision.
vitalybuka added a reviewer: ldionne.
Herald added a project: All.
vitalybuka requested review of this revision.
Herald added a project: libc++.
Herald added a subscriber: libcxx-commits.
Herald added a reviewer: libc++.

Detected on lld test with -fsanitize-memory-use-after-dtor.

Threads may outlive static variables. Even if __thread_specific_ptr destructor does nothing, lifetime of members ends with destroctor and accessing the ptr is UB https://eel.is/c++draft/basic.life#1

9214==WARNING: MemorySanitizer: use-of-uninitialized-value
----------------------------------------------------------

    #0 0x557e1cec4539 in __libcpp_tls_set ../include/c++/v1/__threading_support:428:12
    #1 0x557e1cec4539 in set_pointer ../include/c++/v1/thread:196:5
    #2 0x557e1cec4539 in void* std::__msan::__thread_proxy<
      std::__msan::tuple<...>, llvm::parallel::detail::(anonymous namespace)::ThreadPoolExecutor::ThreadPoolExecutor(llvm::ThreadPoolStrategy)::'lambda'()::operator()() const::'lambda'()> >(void*) ../include/c++/v1/thread:285:27
  
  Memory was marked as uninitialized
    #0 0x557e10a0759d in __sanitizer_dtor_callback compiler-rt/lib/msan/msan_interceptors.cpp:940:5
    #1 0x557e1d8c478d in std::__msan::__thread_specific_ptr<std::__msan::__thread_struct>::~__thread_specific_ptr() libcxx/include/thread:188:1
    #2 0x557e10a07dc0 in MSanCxaAtExitWrapper(void*) compiler-rt/lib/msan/msan_interceptors.cpp:1151:3


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D122864

Files:
  libcxx/src/thread.cpp


Index: libcxx/src/thread.cpp
===================================================================
--- libcxx/src/thread.cpp
+++ libcxx/src/thread.cpp
@@ -115,8 +115,9 @@
 __thread_specific_ptr<__thread_struct>&
 __thread_local_data()
 {
-    static __thread_specific_ptr<__thread_struct> __p;
-    return __p;
+  alignas(__thread_specific_ptr<__thread_struct>) static char __b[sizeof(__thread_specific_ptr<__thread_struct>)];
+  static __thread_specific_ptr<__thread_struct>* __p = new (__b) __thread_specific_ptr<__thread_struct>();
+  return *__p;
 }
 
 // __thread_struct_imp


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D122864.419620.patch
Type: text/x-patch
Size: 578 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/libcxx-commits/attachments/20220401/e5a656d1/attachment.bin>


More information about the libcxx-commits mailing list