Handling of TLS in shared objects can lead to application data corruption
The code for managing thread local storage memory in "libc" can cause data corruption that can even lead to application crashes. The issue happens if a shared object is loaded, then unloaded and finally another shared object is loaded. This can lead to a situation where a thread uses the TLS memory are previously allocated for the first shared object for the second shared object.
The attached example source (it can be build using GNU make) demonstrates the issue. If you run it under Linux (or macOS or NetBSD) it prints the correct output:
Under OmniOS however it prints this:
"lib3" is reusing the TLS segment of "lib1" in this case and therefore returns the wrong value. This kind of problem becomes fatal if an error previously occupied by a string is now used by a pointer variable.
The problem can be avoided by changing "ld.so.1" to never reuse module identifiers when loading and unloading shared objects that use TLS. The disadvantage of this solution is that the per thread tls_t array will keep growing in size. There is also still now garbage collection of now unused per thread TLS memory area after a shared object has been unloaded.
The TLS support in NetBSD could perhaps serve as an example. It mains a generation number which gets increased after a shared objects get loaded or unloaded. And threads update their TLS memory allocations when they detect a change of the generation number.