Currently, when we generate a temporary file name, we use the seconds, microseconds, and the PID to generate a unique value. The resulting value, while changing frequently, is actually predictable and on some systems, it may be possible to cause a DoS by creating all potential temporary files when the temporary file is being created in TMPDIR. The solution to this is to use the system CSPRNG to generate the temporary file name. This is the approach taken by FreeBSD, NetBSD, and OpenBSD, and glibc also recently switched to this approach from an approach that resembled ours in many ways. Even if this is not practically exploitable on many systems, it seems prudent to be at least as careful about temporary file generation as libc is. This issue was mentioned on the security list and it was decided that this was not sensitive enough to warrant a coordinated disclosure, a sentiment with which I agree. This is difficult to exploit on most systems, but I think it's still worth fixing. This series introduces two commits. The first implements a generic function which calls the system CSPRNG. A reasonably exhaustive attempt is made to pick from the options with a preference for performance. The second changes our temporary file code to use the CSPRNG. I have added a test helper that can emit bytes from the CSPRNG, as well as a self-test mode. The former is not used, but I anticipated it could find utility in the testsuite, and it was useful for testing by hand, so I included it. The careful reader will notice that the sole additional test is added to t0000. That's because temporary file generation is fundamental to how Git operates and if it fails, the entire testsuite is broken. Thus, a simple test to verify that it's working seems prudent as part of t0000. I was also unable to find a better place to put it, but am open to suggestions if folks have ideas. This passes our CI, including on Windows, and I have manually verified the correctness of the other four branches on Linux (the HAVE_ARC4RANDOM branch requiring a small patch which is not necessary on systems which have it in libc and which is therefore not included here). I am of course interested in hearing from anyone who lacks one of the CSPRNG interfaces we have here. Looking at the Go standard library, /dev/urandom should be available on at least AIX, Darwin (macOS), DragonflyBSD, FreeBSD, Linux, NetBSD, OpenBSD, and Solaris, and I believe it is available on most other Unix systems as well. RtlGenRandom is available on Windows back to XP, which we no longer support. The bizarre header contortion on Windows comes from Mozilla, but is widely used in other codebases with no substantial changes. For those who are interested, I computed the probability of spurious failure for the self-test mode like so: 256 * (255/256)^65536 This Ruby one-liner estimates the probability at approximately 10^-108: ruby -e 'a = 255 ** 65536; b = 256 ** 65536; puts b.to_s.length - a.to_s.length - 3' If I have made an error in the calculation, please do feel free to point it out. brian m. carlson (2): wrapper: add a helper to generate numbers from a CSPRNG wrapper: use a CSPRNG to generate random file names Makefile | 25 ++++++++++ compat/winansi.c | 6 +++ config.mak.uname | 9 ++++ contrib/buildsystems/CMakeLists.txt | 2 +- git-compat-util.h | 16 +++++++ t/helper/test-csprng.c | 63 +++++++++++++++++++++++++ t/helper/test-tool.c | 1 + t/helper/test-tool.h | 1 + t/t0000-basic.sh | 4 ++ wrapper.c | 71 ++++++++++++++++++++++++----- 10 files changed, 186 insertions(+), 12 deletions(-) create mode 100644 t/helper/test-csprng.c