Can you be more specific than this? I kind of doubt it.
For example, seems to me you could write a setenv() that uses a lock-free algorithm or writes in a strategic way that won't result in a fault if getenv() or reading environ(7) runs concurrently, then say all bets are off for thread safety if you write via environ(7). That's safer than the status quo and I don't foresee it breaking POSIX.
The XSI spec does state that the result of getenv() may be overwritten by putenv() but that's not a strict requirement either.
You still risk programs and libraries expecting getenv to always return a pointer to *environ failing (I believe Go has an issue like that on MUSL).
On the other hand, the POSIX standard explicitly states that getenv() does not need to be reentrant (and therefore doesn't need to be thread safe) so any program relying on thread-safe getenv is already violating the API contract.
The rationale also seems to assume you can't make this stuff thread safe because of the standard implementation:
> The getenv() function is inherently not reentrant because it returns a value pointing to static data.
It's important to note the difference between reentrant and thread safe. The most obvious implementation of getenv(), which would just loop through environ(7) and do a bunch of strncmp, can safely be re-entered, in that you could interrupt it and call it again and it would produce no ill effect. It just can't be overlapped with writes.
I'm pretty sure the Windows version of the environment calls has locking.
Historically you can access the environment via a global variable too, which would side-step locking schemes. But probably hardly anybody does that anymore.