Skip to content

Commit 53063e7

Browse files
ethomsonEdward Thomson
authored andcommitted
futils: use our random function for mktemp
`mktemp` on mingw is exceedingly deficient, using a single monotonically increasing alphabetic character and the pid. We need to use our own random number generator for temporary filenames.
1 parent 86c58a5 commit 53063e7

File tree

2 files changed

+14
-14
lines changed

2 files changed

+14
-14
lines changed

src/futils.c

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@
1010
#include "runtime.h"
1111
#include "strmap.h"
1212
#include "hash.h"
13+
#include "rand.h"
14+
1315
#include <ctype.h>
1416
#if GIT_WIN32
1517
#include "win32/findfile.h"
@@ -27,23 +29,20 @@ int git_futils_mkpath2file(const char *file_path, const mode_t mode)
2729
int git_futils_mktmp(git_str *path_out, const char *filename, mode_t mode)
2830
{
2931
const int open_flags = O_RDWR | O_CREAT | O_EXCL | O_BINARY | O_CLOEXEC;
30-
/* TMP_MAX is unrelated to mktemp but should provide a reasonable amount */
31-
unsigned int tries = TMP_MAX;
32+
unsigned int tries = 32;
3233
int fd;
3334

3435
while (tries--) {
36+
uint64_t rand = git_rand_next();
37+
3538
git_str_sets(path_out, filename);
36-
git_str_puts(path_out, "_git2_XXXXXX");
39+
git_str_puts(path_out, "_git2_");
40+
git_str_encode_hexstr(path_out, (void *)&rand, sizeof(uint64_t));
3741

3842
if (git_str_oom(path_out))
3943
return -1;
4044

41-
/* Using mktemp is safe when we open with O_CREAT | O_EXCL */
42-
p_mktemp(path_out->ptr);
43-
/* mktemp sets template to empty string on failure */
44-
if (path_out->ptr[0] == '\0')
45-
break;
46-
45+
/* Note that we open with O_CREAT | O_EXCL */
4746
if ((fd = p_open(path_out->ptr, open_flags, mode)) >= 0)
4847
return fd;
4948
}

src/futils.h

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -177,11 +177,12 @@ extern int git_futils_rmdir_r(const char *path, const char *base, uint32_t flags
177177
* protected directory; the file created will created will honor
178178
* the current `umask`. Writes the filename into path_out.
179179
*
180-
* This function is *NOT* suitable for use in temporary directories
181-
* that are world writable. It uses `mktemp` (for portability) and
182-
* many `mktemp` implementations use weak random characters. It
183-
* should only be assumed to be suitable for atomically writing
184-
* a new file in a directory that you control.
180+
* This function uses a high-quality PRNG seeded by the system's
181+
* entropy pool _where available_ and falls back to a simple seed
182+
* (time plus system information) when not. This is suitable for
183+
* writing within a protected directory, but the system's safe
184+
* temporary file creation functions should be preferred where
185+
* available when writing into world-writable (temp) directories.
185186
*
186187
* @return On success, an open file descriptor, else an error code < 0.
187188
*/

0 commit comments

Comments
 (0)