git/list[1] front-page[2] threads[3] people[4] search[5] about
 

Re: [PATCH 2/4] compat: use git_mkdtemp()

From
Jeff King <peff@peff.net>
Date
Dec 3, 2025, 16:11 UTC
Message-ID
<20251203161154.GA44940@coredump.intra.peff.net>
In-Reply-To
<4c70b527-9c40-4396-8c8c-95177c5d92f0@web.de>
On Wed, Dec 03, 2025 at 11:52:30AM +0100, René Scharfe wrote:
> A file might appear at the path returned by mktemp(3) before we call
> mkdir(2).  Use the more robust git_mkdtemp() instead, which retries a
> number of times and doesn't need to call lstat(2).

This seems like a good idea. At least one of the mkdtemp() callers was using $TMPDIR, so this was a potential security-sensitive race.

Show 13 quoted lines
> diff --git a/compat/mkdtemp.c b/compat/mkdtemp.c
> index 1136119592..fcdd4e01e1 100644
> --- a/compat/mkdtemp.c
> +++ b/compat/mkdtemp.c
> @@ -2,7 +2,5 @@
>  
>  char *gitmkdtemp(char *template)
>  {
> -	if (!*mktemp(template) || mkdir(template, 0700))
> -		return NULL;
> -	return template;
> +	return git_mkdtemp(template);
>  }

OK, so now we have gitmkdtemp() and git_mkdtemp(), which are also now the exact same thing. That seems overly complicated. ;)

This one is a conditionally-compiled wrapper for NO_MKDTEMP. But since we always have git_mkdtemp() available (as of your first patch), can't we just point at it directly with the macro?

Like this:
diff --git a/Makefile b/Makefile
index 237b56fc9d..8226aed443 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/compat/mkdtemp.c b/compat/mkdtemp.c
deleted file mode 100644
index fcdd4e01e1..0000000000
--- a/compat/mkdtemp.c
+++ /dev/null
@@ -1,6 +0,0 @@
-#include "../git-compat-util.h"
-
-char *gitmkdtemp(char *template)
-{
-	return git_mkdtemp(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/meson.build b/meson.build
index f1b3615659..090b1911ca 100644
--- a/meson.build
+++ b/meson.build
@@ -1401,7 +1401,6 @@ checkfuncs = {
   'strlcpy' : ['strlcpy.c'],
   'strtoull' : [],
   'setenv' : ['setenv.c'],
-  'mkdtemp' : ['mkdtemp.c'],
   'initgroups' : [],
   'strtoumax' : ['strtoumax.c', 'strtoimax.c'],
   'pread' : ['pread.c'],


We could even take it a step further and just always use git_mkdtemp(),
like we were discussing elsewhere for mkstemp(). And then the makefile
knobs can go away, too, like:

diff --git a/Makefile b/Makefile
index 8226aed443..8ef5497c10 100644
--- a/Makefile
+++ b/Makefile
@@ -68,8 +68,6 @@ include shared.mak
 #
 # Define NO_UNSETENV if you don't have unsetenv in the C library.
 #
-# Define NO_MKDTEMP if you don't have mkdtemp in the C library.
-#
 # Define MKDIR_WO_TRAILING_SLASH if your mkdir() can't deal with trailing slash.
 #
 # Define NO_GECOS_IN_PWENT if you don't have pw_gecos in struct passwd
diff --git a/compat/posix.h b/compat/posix.h
index 245386fa4a..c49d67e653 100644
--- a/compat/posix.h
+++ b/compat/posix.h
@@ -328,9 +328,7 @@ ssize_t git_pread(int fd, void *buf, size_t count, off_t offset);
 int gitsetenv(const char *, const char *, int);
 #endif
 
-#ifdef NO_MKDTEMP
 #define mkdtemp git_mkdtemp
-#endif
 
 #ifdef NO_UNSETENV
 #define unsetenv gitunsetenv
diff --git a/configure.ac b/configure.ac
index cfb50112bf..8e61186f18 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1140,12 +1140,6 @@ GIT_CHECK_FUNC(unsetenv,
 [NO_UNSETENV=YesPlease])
 GIT_CONF_SUBST([NO_UNSETENV])
 #
-# Define NO_MKDTEMP if you don't have mkdtemp in the C library.
-GIT_CHECK_FUNC(mkdtemp,
-[NO_MKDTEMP=],
-[NO_MKDTEMP=YesPlease])
-GIT_CONF_SUBST([NO_MKDTEMP])
-#
 # Define NO_INITGROUPS if you don't have initgroups in the C library.
 GIT_CHECK_FUNC(initgroups,
 [NO_INITGROUPS=],
diff --git a/contrib/buildsystems/CMakeLists.txt b/contrib/buildsystems/CMakeLists.txt
index 479163ab5c..d28de227f5 100644
--- a/contrib/buildsystems/CMakeLists.txt
+++ b/contrib/buildsystems/CMakeLists.txt
@@ -374,7 +374,7 @@ endif()
 #function checks
 set(function_checks
 	strcasestr memmem strlcpy strtoimax strtoumax strtoull
-	setenv mkdtemp poll pread memmem)
+	setenv poll pread memmem)
 
 #unsetenv,hstrerror are incompatible with windows build
 if(NOT WIN32)
@@ -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()

-Peff
Previous: René ScharfeNext: René Scharfe
Message 6 of 19 in “ban mktemp(3)”
  1. 0/4 ban mktemp(3)René Scharfe, Dec 3, 2025
  2. 1/4 wrapper: add git_mkdtemp()René Scharfe, Dec 3, 2025
  3. Chris TorekDec 4, 2025
  4. Junio C HamanoDec 5, 2025
  5. 2/4 compat: use git_mkdtemp()René Scharfe, Dec 3, 2025
  6. Jeff KingDec 3, 2025
  7. René ScharfeDec 5, 2025
  8. Jeff KingDec 6, 2025
  9. Junio C HamanoDec 5, 2025
  10. 3/4 compat: remove mingw_mktemp()René Scharfe, Dec 3, 2025
  11. 4/4 banned.h: ban mktemp(3)René Scharfe, Dec 3, 2025
  12. Jeff KingDec 3, 2025
  13. 0/5 ban mktemp(3)René Scharfe, Dec 6, 2025
  14. 1/5 wrapper: add git_mkdtemp()René Scharfe, Dec 6, 2025
  15. 2/5 compat: use git_mkdtemp()René Scharfe, Dec 6, 2025
  16. 3/5 compat: remove mingw_mktemp()René Scharfe, Dec 6, 2025
  17. 4/5 banned.h: ban mktemp(3)René Scharfe, Dec 6, 2025
  18. 5/5 compat: remove gitmkdtemp()René Scharfe, Dec 6, 2025
  19. Jeff KingDec 8, 2025

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.