dyld threadLocalVariables.c - calling _tlv_atexit during tlv_finalize is undefined behavior
Originator: | tyler.m.kopf | ||
Number: | rdar://47416656 | Date Originated: | January 20 2019 |
Status: | Open | Resolved: | |
Product: | macOS + SDK | Product Version: | |
Classification: | Reproducible: |
Area: Something not on this list Summary: Relevant source here: https://opensource.apple.com/source/dyld/dyld-635.2/src/threadLocalVariables.c.auto.html Discussion of how this issue affected rust here: https://github.com/rust-lang/rust/issues/57534 While tlv_finalize is iterating through the TLVTerminator list, more calls to _tlv_atexit can be triggered which can cause the list tlv_finalize is iterating through to be reallocated resulting in all sorts of memory corruption issues. A fix would be to change tlv_finalize to something like this: static void tlv_finalize(void* storage) { do { pthread_setspecific(tlv_terminators_key, NULL); struct TLVTerminatorList* list = (struct TLVTerminatorList*)storage; // destroy in reverse order of construction for(uint32_t i=list->useCount; i > 0 ; --i) { struct TLVTerminatorListEntry* entry = &list->entries[i-1]; if ( entry->termFunc != NULL ) { (*entry->termFunc)(entry->objAddr); } } free(storage); storage = pthread_getspecific(tlv_terminators_key); } while(storage != NULL); } Steps to Reproduce: Compile and run the attached source file using this command. clang++ --std=c++17 -fsanitize=address main.cpp && ./a.out Expected Results: No complaints from address sanitizer. Actual Results: ================================================================= ==87273==ERROR: AddressSanitizer: attempting double-free on 0x603000000310 in thread T0: #0 0x10b34310d in wrap_free (libclang_rt.asan_osx_dynamic.dylib:x86_64h+0x5710d) #1 0x7fff7f9af1d6 in exit (libsystem_c.dylib:x86_64+0x5d1d6) #2 0x7fff7f90608b in start (libdyld.dylib:x86_64+0x1708b) 0x603000000310 is located 0 bytes inside of 24-byte region [0x603000000310,0x603000000328) freed by thread T0 here: #0 0x10b34310d in wrap_free (libclang_rt.asan_osx_dynamic.dylib:x86_64h+0x5710d) #1 0x7fff7f905963 in _tlv_atexit (libdyld.dylib:x86_64+0x16963) #2 0x10b0dd3da in A::~A() (a.out:x86_64+0x1000013da) #3 0x10b0dd2f4 in A::~A() (a.out:x86_64+0x1000012f4) #4 0x7fff7f905d7e in tlv_finalize (libdyld.dylib:x86_64+0x16d7e) #5 0x7fff7f9af1d6 in exit (libsystem_c.dylib:x86_64+0x5d1d6) #6 0x7fff7f90608b in start (libdyld.dylib:x86_64+0x1708b) previously allocated by thread T0 here: #0 0x10b342f53 in wrap_malloc (libclang_rt.asan_osx_dynamic.dylib:x86_64h+0x56f53) #1 0x7fff7f905974 in _tlv_atexit (libdyld.dylib:x86_64+0x16974) #2 0x10b0df9a1 in __cxx_global_var_init (a.out:x86_64+0x1000039a1) #3 0x10b0df924 in __tls_init (a.out:x86_64+0x100003924) #4 0x10b0ddc78 in thread-local wrapper routine for thread_a (a.out:x86_64+0x100001c78) #5 0x10b0ddbe3 in main (a.out:x86_64+0x100001be3) #6 0x7fff7f906084 in start (libdyld.dylib:x86_64+0x17084) SUMMARY: AddressSanitizer: double-free (libclang_rt.asan_osx_dynamic.dylib:x86_64h+0x5710d) in wrap_free ==87273==ABORTING Abort trap: 6 Version/Build: OSX 10.14 Configuration:
Comments
Please note: Reports posted here will not necessarily be seen by Apple. All problems should be submitted at bugreport.apple.com before they are posted here. Please only post information for Radars that you have filed yourself, and please do not include Apple confidential information in your posts. Thank you!