aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJunio C Hamano <gitster@pobox.com>2025-12-16 11:08:34 +0900
committerJunio C Hamano <gitster@pobox.com>2025-12-16 11:08:35 +0900
commit91bfbf49b6566d2b412d12240336027e351a631c (patch)
treefb6f10e6d9e0565d3d3dfe83e10652c4325239b6
parent72154ce4147e971b59e10d79648b114481703607 (diff)
parent10bba537c4c23e713af05be700748c6a3c25bf68 (diff)
downloadgit-91bfbf49b6566d2b412d12240336027e351a631c.tar.gz
Merge branch 'rs/ban-mktemp'
Rewrite the only use of "mktemp()" that is subject to TOCTOU race and Stop using the insecure "mktemp()" function. * rs/ban-mktemp: compat: remove gitmkdtemp() banned.h: ban mktemp(3) compat: remove mingw_mktemp() compat: use git_mkdtemp() wrapper: add git_mkdtemp()
-rw-r--r--Makefile1
-rw-r--r--banned.h3
-rw-r--r--compat/mingw-posix.h3
-rw-r--r--compat/mingw.c12
-rw-r--r--compat/mkdtemp.c8
-rw-r--r--compat/posix.h3
-rw-r--r--contrib/buildsystems/CMakeLists.txt4
-rw-r--r--meson.build2
-rw-r--r--wrapper.c21
-rw-r--r--wrapper.h2
10 files changed, 26 insertions, 33 deletions
diff --git a/Makefile b/Makefile
index 291e4a7219..cf3f4b585f 100644
--- a/Makefile
+++ b/Makefile
@@ -1919,7 +1919,6 @@ ifdef NO_SETENV
endif
ifdef NO_MKDTEMP
COMPAT_CFLAGS += -DNO_MKDTEMP
- COMPAT_OBJS += compat/mkdtemp.o
endif
ifdef MKDIR_WO_TRAILING_SLASH
COMPAT_CFLAGS += -DMKDIR_WO_TRAILING_SLASH
diff --git a/banned.h b/banned.h
index 44e76bd90a..2b934c8c43 100644
--- a/banned.h
+++ b/banned.h
@@ -41,4 +41,7 @@
#undef asctime_r
#define asctime_r(t, buf) BANNED(asctime_r)
+#undef mktemp
+#define mktemp(x) BANNED(mktemp)
+
#endif /* BANNED_H */
diff --git a/compat/mingw-posix.h b/compat/mingw-posix.h
index 631a208684..0939feff27 100644
--- a/compat/mingw-posix.h
+++ b/compat/mingw-posix.h
@@ -241,9 +241,6 @@ int mingw_chdir(const char *dirname);
int mingw_chmod(const char *filename, int mode);
#define chmod mingw_chmod
-char *mingw_mktemp(char *template);
-#define mktemp mingw_mktemp
-
char *mingw_getcwd(char *pointer, int len);
#define getcwd mingw_getcwd
diff --git a/compat/mingw.c b/compat/mingw.c
index 90ba5cea9d..939f938fe2 100644
--- a/compat/mingw.c
+++ b/compat/mingw.c
@@ -1164,18 +1164,6 @@ unsigned int sleep (unsigned int seconds)
return 0;
}
-char *mingw_mktemp(char *template)
-{
- wchar_t wtemplate[MAX_PATH];
- if (xutftowcs_path(wtemplate, template) < 0)
- return NULL;
- if (!_wmktemp(wtemplate))
- return NULL;
- if (xwcstoutf(template, wtemplate, strlen(template) + 1) < 0)
- return NULL;
- return template;
-}
-
int mkstemp(char *template)
{
return git_mkstemp_mode(template, 0600);
diff --git a/compat/mkdtemp.c b/compat/mkdtemp.c
deleted file mode 100644
index 1136119592..0000000000
--- a/compat/mkdtemp.c
+++ /dev/null
@@ -1,8 +0,0 @@
-#include "../git-compat-util.h"
-
-char *gitmkdtemp(char *template)
-{
- if (!*mktemp(template) || mkdir(template, 0700))
- return NULL;
- return template;
-}
diff --git a/compat/posix.h b/compat/posix.h
index 067a00f33b..245386fa4a 100644
--- a/compat/posix.h
+++ b/compat/posix.h
@@ -329,8 +329,7 @@ int gitsetenv(const char *, const char *, int);
#endif
#ifdef NO_MKDTEMP
-#define mkdtemp gitmkdtemp
-char *gitmkdtemp(char *);
+#define mkdtemp git_mkdtemp
#endif
#ifdef NO_UNSETENV
diff --git a/contrib/buildsystems/CMakeLists.txt b/contrib/buildsystems/CMakeLists.txt
index 479163ab5c..28877feb9d 100644
--- a/contrib/buildsystems/CMakeLists.txt
+++ b/contrib/buildsystems/CMakeLists.txt
@@ -411,10 +411,6 @@ if(NOT HAVE_SETENV)
list(APPEND compat_SOURCES compat/setenv.c)
endif()
-if(NOT HAVE_MKDTEMP)
- list(APPEND compat_SOURCES compat/mkdtemp.c)
-endif()
-
if(NOT HAVE_PREAD)
list(APPEND compat_SOURCES compat/pread.c)
endif()
diff --git a/meson.build b/meson.build
index 95f4c5ee95..dd52efd1c8 100644
--- a/meson.build
+++ b/meson.build
@@ -1401,7 +1401,7 @@ checkfuncs = {
'strlcpy' : ['strlcpy.c'],
'strtoull' : [],
'setenv' : ['setenv.c'],
- 'mkdtemp' : ['mkdtemp.c'],
+ 'mkdtemp' : [],
'initgroups' : [],
'strtoumax' : ['strtoumax.c', 'strtoimax.c'],
'pread' : ['pread.c'],
diff --git a/wrapper.c b/wrapper.c
index d5976b3e7e..b794fb20e7 100644
--- a/wrapper.c
+++ b/wrapper.c
@@ -429,7 +429,11 @@ int xmkstemp(char *filename_template)
#undef TMP_MAX
#define TMP_MAX 16384
-int git_mkstemps_mode(char *pattern, int suffix_len, int mode)
+/*
+ * Returns -1 on error, 0 if it created a directory, or an open file
+ * descriptor to the created regular file.
+ */
+static int git_mkdstemps_mode(char *pattern, int suffix_len, int mode, bool dir)
{
static const char letters[] =
"abcdefghijklmnopqrstuvwxyz"
@@ -471,7 +475,10 @@ int git_mkstemps_mode(char *pattern, int suffix_len, int mode)
v /= num_letters;
}
- fd = open(pattern, O_CREAT | O_EXCL | O_RDWR, mode);
+ if (dir)
+ fd = mkdir(pattern, mode);
+ else
+ fd = open(pattern, O_CREAT | O_EXCL | O_RDWR, mode);
if (fd >= 0)
return fd;
/*
@@ -486,6 +493,16 @@ int git_mkstemps_mode(char *pattern, int suffix_len, int mode)
return -1;
}
+char *git_mkdtemp(char *pattern)
+{
+ return git_mkdstemps_mode(pattern, 0, 0700, true) ? NULL : pattern;
+}
+
+int git_mkstemps_mode(char *pattern, int suffix_len, int mode)
+{
+ return git_mkdstemps_mode(pattern, suffix_len, mode, false);
+}
+
int git_mkstemp_mode(char *pattern, int mode)
{
/* mkstemp is just mkstemps with no suffix */
diff --git a/wrapper.h b/wrapper.h
index 44a8597ac3..15ac3bab6e 100644
--- a/wrapper.h
+++ b/wrapper.h
@@ -37,6 +37,8 @@ int xsnprintf(char *dst, size_t max, const char *fmt, ...);
int xgethostname(char *buf, size_t len);
+char *git_mkdtemp(char *pattern);
+
/* set default permissions by passing mode arguments to open(2) */
int git_mkstemps_mode(char *pattern, int suffix_len, int mode);
int git_mkstemp_mode(char *pattern, int mode);