public inbox for git@vger.kernel.org 
 help / color / mirror / Atom feed
From: "René Scharfe" <l.s.r@web•de>
To: Jeff King <peff@peff•net>
Cc: Git List <git@vger•kernel.org>
Subject: Re: [PATCH 2/4] compat: use git_mkdtemp()
Date: Fri, 5 Dec 2025 13:11:40 +0100	[thread overview]
Message-ID: <aebd0ffe-7914-4731-8f79-830bd3b5a147@web.de> (raw)
In-Reply-To: <20251203161154.GA44940@coredump.intra.peff.net>

On 12/3/25 5:11 PM, Jeff King wrote:
> 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.
> 
>> 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?

A worthwhile cleanup if we stop at this point, but complicated by
targeting three build systems, the CMake build being broken on macOS and
me only knowing how to fake NO_MKDEMP for make, leaving half the build
space untestable for me.

> 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 need to keep that dictionary entry to still define NO_MKDTEMP, and
just empty the array of filenames.

contrib/buildsystems/CMakeLists.txt needs to be updated as well, like
you do below (keep in function_checks, remove from compat_SOURCES).

At the very least this cleanup should be done in a separated patch, as
it's harder than it looks.

> 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()

Right.  Dropping this dependency and then deep cleaning the compat code
is attractive and mostly sidesteps the build system complications.
That's for a later series.

Ultimately you'd prefer banning mkdtemp(3) instead of automatically
redirecting to git_mkdtemp(), though, no?

René


  reply	other threads:[~2025-12-05 12:11 UTC|newest]

Thread overview: 19+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-12-03 10:45 [PATCH 0/4] ban mktemp(3) René Scharfe
2025-12-03 10:51 ` [PATCH 1/4] wrapper: add git_mkdtemp() René Scharfe
2025-12-04 11:51   ` Chris Torek
2025-12-05 23:05   ` Junio C Hamano
2025-12-03 10:52 ` [PATCH 2/4] compat: use git_mkdtemp() René Scharfe
2025-12-03 16:11   ` Jeff King
2025-12-05 12:11     ` René Scharfe [this message]
2025-12-06  2:11       ` Jeff King
2025-12-05 23:05     ` Junio C Hamano
2025-12-03 10:52 ` [PATCH 3/4] compat: remove mingw_mktemp() René Scharfe
2025-12-03 10:53 ` [PATCH 4/4] banned.h: ban mktemp(3) René Scharfe
2025-12-03 16:12   ` Jeff King
2025-12-06 13:21 ` [PATCH v2 0/5] " René Scharfe
2025-12-06 13:27   ` [PATCH v2 1/5] wrapper: add git_mkdtemp() René Scharfe
2025-12-06 13:27   ` [PATCH v2 2/5] compat: use git_mkdtemp() René Scharfe
2025-12-06 13:28   ` [PATCH v2 3/5] compat: remove mingw_mktemp() René Scharfe
2025-12-06 13:29   ` [PATCH v2 4/5] banned.h: ban mktemp(3) René Scharfe
2025-12-06 13:35   ` [PATCH v2 5/5] compat: remove gitmkdtemp() René Scharfe
2025-12-08 20:33   ` [PATCH v2 0/5] ban mktemp(3) Jeff King

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=aebd0ffe-7914-4731-8f79-830bd3b5a147@web.de \
    --to=l.s.r@web$(echo .)de \
    --cc=git@vger$(echo .)kernel.org \
    --cc=peff@peff$(echo .)net \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox