Description
v1.3.0 introduced the EnableRandPool
and DisableRandPool
functions as a means of optimizing UUID generation at the expense of security. However, there are two main issues with this.
First, as documented, neither of these are thread-safe. However, the described solution is not feasible:
// Both EnableRandPool and DisableRandPool are not thread-safe and should
// only be called when there is no possibility that New or any other
// UUID Version 4 generation function will be called concurrently.
I cannot in general easily account for what all the package initializers of all of my transitive dependencies are doing. Instead of a function called a runtime, this opt-in behavior should be controlled by a build tag, so the pool can be enabled at compile time. Then there is no race condition. (You could also replace the poolEnabled
bool with an atomically read/written uint32, which at least resolves the race condition. But the build tag is more air tight.)
Second, as documented, the optimization is not suitable for security sensitive applications. However, again, I cannot account for what all of my transitive dependencies are doing. And in general, only having a global flag that effectively disables security seems like a rather poor design choice. It would be preferable if the decision could be made by the client on a case-by-case basis.
Going forward, it probably makes sense to deprecate the various global constructor functions and replace them with a factory object, similar to net.Dialer
. Then this factory can easily be configured with various options that accumulate over time without needing to make new constructor functions.