Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

47416656: dyld threadLocalVariables.c - calling _tlv_atexit during tlv_finalize is undefined behavior #20926

Open
openradar-mirror opened this issue Jan 20, 2019 · 0 comments

Comments

@openradar-mirror
Copy link

Description

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: rust-lang/rust#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:

Product Version:
Created: 2019-01-20T20:06:34.141874
Originated: 2019-01-20T00:00:00
Open Radar Link: http://www.openradar.me/47416656

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Development

No branches or pull requests

1 participant