Skip to content
This repository has been archived by the owner on Oct 12, 2022. It is now read-only.

Commit

Permalink
sections_elf_shared: Do not access TLS of dead thread in finiTLSRanges()
Browse files Browse the repository at this point in the history
finiTLSRanges() is called from the destructor of core.Thread. At this point,
the OS thread has already ceased to exist, so what was formerly a pointer
to _loadedDSOs is no longer valid.

In other words, `tdsos.reset()` was a use-after-free bug. It is unclear why
the issue didn't surface on Linux/FreeBSD yet; for example, glibc might not
actually re-use the TLS address range after a thread exits. On OS X, however,
this did quite frequently trigger a crash when running the Phobos unit tests,
since `tdsos` would have already been overwritten with unrelated contents.
  • Loading branch information
dnadlinger committed Sep 11, 2016
1 parent d6924a9 commit b22d813
Showing 1 changed file with 6 additions and 1 deletion.
7 changes: 6 additions & 1 deletion src/rt/sections_elf_shared.d
Expand Up @@ -149,7 +149,10 @@ version (Shared)

void finiTLSRanges(Array!(ThreadDSO)* tdsos)
{
tdsos.reset();
// Nothing to do here. tdsos used to point to the _loadedDSOs instance
// in the dying thread's TLS segment and as such is not valid anymore.
// The memory for the array contents was already reclaimed in
// cleanupLoadedLibraries().
}

void scanTLSRanges(Array!(ThreadDSO)* tdsos, scope ScanDG dg) nothrow
Expand Down Expand Up @@ -219,6 +222,8 @@ version (Shared)
for (; tdso._addCnt > 0; --tdso._addCnt)
.dlclose(handle);
}

// Free the memory for the array contents.
_loadedDSOs.reset();
}
}
Expand Down

0 comments on commit b22d813

Please sign in to comment.