Subject: bug#28023: fix make-temp-file race on local host

From: Paul Eggert <[email-masked]>
Date: Wed, 9 Aug 2017 11:47:36 -0700

On 08/09/2017 09:05 AM, Eli Zaretskii wrote:
> We could resolve this problem by providing a way for the Windows build
> to specify its own replacements for 'open', 'mkdir', and 'lstat'
> (Emacs already have such replacements in w32.c), which tempname.c
> calls, but that would require minor changes in Gnulib's tempname.c.

This sounds like a better way to go. What minor changes would be needed? 
tempname.c already includes config.h, which includes ms-w32.h, which 
redefines open, mkdir, and lstat, so I thought it would work as-is.

> This seems to say that we will sometimes use secure_getenv, but the
> relevant code in tempname.c is conditioned on _LIBC, which AFAIU is
> only true when building glibc, so why do we need that?  Or did I miss
> something?
No, good catch, Emacs never needs secure_getenv. I fixed Gnulib, 
installed the attached patch to propagate that fix, and will adjust the 
proposed make-temp-file patch accordingly.

>From 8daab9f4a0ff6dbcfbd0c6f9262e41753de3484b Mon Sep 17 00:00:00 2001
From: Paul Eggert <[email-masked]>
Date: Wed, 9 Aug 2017 11:38:04 -0700
Subject: [PATCH] Merge from gnulib

This incorporates:
2017-08-09 tempname: do not depend on secure_getenv
2017-08-08 extensions: add _OPENBSD_SOURCE
2017-08-06 manywarnings: Add support for C++
2017-08-06 warnings, manywarnings: Add support for multiple languages
* admin/merge-gnulib: Don't use m4/manywarnings-c++.m4.
* lib/gnulib.mk.in, m4/gnulib-comp.m4: Regenerate.
* lib/secure_getenv.c, m4/secure_getenv.m4: Remove.
* lib/tempname.c, m4/extensions.m4, m4/manywarnings.m4, m4/warnings.m4:
Copy from gnulib.
---
 admin/merge-gnulib  |  1 +
 lib/gnulib.mk.in    | 14 --------------
 lib/secure_getenv.c | 54 -----------------------------------------------------
 lib/tempname.c      |  1 -
 m4/extensions.m4    |  7 ++++++-
 m4/gnulib-comp.m4   | 19 +------------------
 m4/manywarnings.m4  | 18 +++++++++++++++++-
 m4/secure_getenv.m4 | 26 --------------------------
 m4/warnings.m4      | 47 +++++++++++++++++++++++++++++++++++-----------
 9 files changed, 61 insertions(+), 126 deletions(-)
 delete mode 100644 lib/secure_getenv.c
 delete mode 100644 m4/secure_getenv.m4

diff --git a/admin/merge-gnulib b/admin/merge-gnulib
index c23e8a40ea..a16d7fa53e 100755
--- a/admin/merge-gnulib
+++ b/admin/merge-gnulib
@@ -106,6 +106,7 @@ avoided_flags=
 rm -- "$src"lib/gl_openssl.h "$src"m4/fcntl-o.m4 \
       "$src"m4/gl-openssl.m4 \
       "$src"m4/gnulib-cache.m4 "$src"m4/gnulib-tool.m4 \
+      "$src"m4/manywarnings-c++.m4 \
       "$src"m4/warn-on-use.m4 "$src"m4/wint_t.m4 &&
 cp -- "$gnulib_srcdir"/build-aux/texinfo.tex "$src"doc/misc &&
 cp -- "$gnulib_srcdir"/build-aux/config.guess \
diff --git a/lib/gnulib.mk.in b/lib/gnulib.mk.in
index a385c8c838..c5df3f42e4 100644
--- a/lib/gnulib.mk.in
+++ b/lib/gnulib.mk.in
@@ -903,7 +903,6 @@ gl_GNULIB_ENABLED_dosname = @gl_GNULIB_ENABLED_dosname@
 gl_GNULIB_ENABLED_euidaccess = @gl_GNULIB_ENABLED_euidaccess@
 gl_GNULIB_ENABLED_getdtablesize = @gl_GNULIB_ENABLED_getdtablesize@
 gl_GNULIB_ENABLED_getgroups = @gl_GNULIB_ENABLED_getgroups@
-gl_GNULIB_ENABLED_secure_getenv = @gl_GNULIB_ENABLED_secure_getenv@
 gl_GNULIB_ENABLED_strtoll = @gl_GNULIB_ENABLED_strtoll@
 gl_GNULIB_ENABLED_tempname = @gl_GNULIB_ENABLED_tempname@
 gl_LIBOBJS = @gl_LIBOBJS@
@@ -1912,19 +1911,6 @@ EXTRA_DIST += root-uid.h
 endif
 ## end   gnulib module root-uid
 
-## begin gnulib module secure_getenv
-ifeq (,$(OMIT_GNULIB_MODULE_secure_getenv))
-
-ifneq (,$(gl_GNULIB_ENABLED_secure_getenv))
-
-endif
-EXTRA_DIST += secure_getenv.c
-
-EXTRA_libgnu_a_SOURCES += secure_getenv.c
-
-endif
-## end   gnulib module secure_getenv
-
 ## begin gnulib module sig2str
 ifeq (,$(OMIT_GNULIB_MODULE_sig2str))
 
diff --git a/lib/secure_getenv.c b/lib/secure_getenv.c
deleted file mode 100644
index df53dea0b2..0000000000
--- a/lib/secure_getenv.c
+++ /dev/null
@@ -1,54 +0,0 @@
-/* Look up an environment variable, returning NULL in insecure situations.
-
-   Copyright 2013-2017 Free Software Foundation, Inc.
-
-   This program is free software: you can redistribute it and/or modify it
-   under the terms of the GNU General Public License as published
-   by the Free Software Foundation; either version 3 of the License, or
-   (at your option) any later version.
-
-   This program is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   General Public License for more details.
-
-   You should have received a copy of the GNU General Public License
-   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
-
-#include <config.h>
-
-#include <stdlib.h>
-
-#if !HAVE___SECURE_GETENV
-# if HAVE_ISSETUGID || (HAVE_GETUID && HAVE_GETEUID && HAVE_GETGID && HAVE_GETEGID)
-#  include <unistd.h>
-# endif
-#endif
-
-char *
-secure_getenv (char const *name)
-{
-#if HAVE___SECURE_GETENV /* glibc */
-  return __secure_getenv (name);
-#elif HAVE_ISSETUGID /* OS X, FreeBSD, NetBSD, OpenBSD */
-  if (issetugid ())
-    return NULL;
-  return getenv (name);
-#elif HAVE_GETUID && HAVE_GETEUID && HAVE_GETGID && HAVE_GETEGID /* other Unix */
-  if (geteuid () != getuid () || getegid () != getgid ())
-    return NULL;
-  return getenv (name);
-#elif (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__ /* native Windows */
-  /* On native Windows, there is no such concept as setuid or setgid binaries.
-     - Programs launched as system services have high privileges, but they don't
-       inherit environment variables from a user.
-     - Programs launched by a user with "Run as Administrator" have high
-       privileges and use the environment variables, but the user has been asked
-       whether he agrees.
-     - Programs launched by a user without "Run as Administrator" cannot gain
-       high privileges, therefore there is no risk. */
-  return getenv (name);
-#else
-  return NULL;
-#endif
-}
diff --git a/lib/tempname.c b/lib/tempname.c
index 9c4a3c2a54..c274b8dd4e 100644
--- a/lib/tempname.c
+++ b/lib/tempname.c
@@ -69,7 +69,6 @@
 # define __mkdir mkdir
 # define __open open
 # define __lxstat64(version, file, buf) lstat (file, buf)
-# define __secure_getenv secure_getenv
 #endif
 
 #ifdef _LIBC
diff --git a/m4/extensions.m4 b/m4/extensions.m4
index c60f537db1..0c16bb832f 100644
--- a/m4/extensions.m4
+++ b/m4/extensions.m4
@@ -1,4 +1,4 @@
-# serial 15  -*- Autoconf -*-
+# serial 16  -*- Autoconf -*-
 # Enable extensions on systems that normally disable them.
 
 # Copyright (C) 2003, 2006-2017 Free Software Foundation, Inc.
@@ -68,6 +68,10 @@ AC_DEFUN_ONCE
 #ifndef _GNU_SOURCE
 # undef _GNU_SOURCE
 #endif
+/* Enable OpenBSD extensions on NetBSD.  */
+#ifndef _OPENBSD_SOURCE
+# undef _OPENBSD_SOURCE
+#endif
 /* Enable threading extensions on Solaris.  */
 #ifndef _POSIX_PTHREAD_SEMANTICS
 # undef _POSIX_PTHREAD_SEMANTICS
@@ -128,6 +132,7 @@ AC_DEFUN_ONCE
   AC_DEFINE([_ALL_SOURCE])
   AC_DEFINE([_DARWIN_C_SOURCE])
   AC_DEFINE([_GNU_SOURCE])
+  AC_DEFINE([_OPENBSD_SOURCE])
   AC_DEFINE([_POSIX_PTHREAD_SEMANTICS])
   AC_DEFINE([__STDC_WANT_IEC_60559_ATTRIBS_EXT__])
   AC_DEFINE([__STDC_WANT_IEC_60559_BFP_EXT__])
diff --git a/m4/gnulib-comp.m4 b/m4/gnulib-comp.m4
index 188c116c85..69d77229bf 100644
--- a/m4/gnulib-comp.m4
+++ b/m4/gnulib-comp.m4
@@ -124,7 +124,6 @@ AC_DEFUN
   # Code from module readlink:
   # Code from module readlinkat:
   # Code from module root-uid:
-  # Code from module secure_getenv:
   # Code from module sig2str:
   # Code from module signal-h:
   # Code from module snippet/_Noreturn:
@@ -424,7 +423,6 @@ AC_DEFUN
   gl_gnulib_enabled_5264294aa0a5557541b53c8c741f7f31=false
   gl_gnulib_enabled_03e0aaad4cb89ca757653bd367a6ccb7=false
   gl_gnulib_enabled_6099e9737f757db36c47fa9d9f02e88c=false
-  gl_gnulib_enabled_secure_getenv=false
   gl_gnulib_enabled_strtoll=false
   gl_gnulib_enabled_tempname=false
   gl_gnulib_enabled_682e609604ccaac6be382e4ee3a4eaec=false
@@ -550,18 +548,6 @@ AC_DEFUN
       gl_gnulib_enabled_6099e9737f757db36c47fa9d9f02e88c=true
     fi
   }
-  func_gl_gnulib_m4code_secure_getenv ()
-  {
-    if ! $gl_gnulib_enabled_secure_getenv; then
-      gl_FUNC_SECURE_GETENV
-      if test $HAVE_SECURE_GETENV = 0; then
-        AC_LIBOBJ([secure_getenv])
-        gl_PREREQ_SECURE_GETENV
-      fi
-      gl_STDLIB_MODULE_INDICATOR([secure_getenv])
-      gl_gnulib_enabled_secure_getenv=true
-    fi
-  }
   func_gl_gnulib_m4code_strtoll ()
   {
     if ! $gl_gnulib_enabled_strtoll; then
@@ -579,7 +565,6 @@ AC_DEFUN
     if ! $gl_gnulib_enabled_tempname; then
       gl_FUNC_GEN_TEMPNAME
       gl_gnulib_enabled_tempname=true
-      func_gl_gnulib_m4code_secure_getenv
     fi
   }
   func_gl_gnulib_m4code_682e609604ccaac6be382e4ee3a4eaec ()
@@ -658,7 +643,6 @@ AC_DEFUN
   AM_CONDITIONAL([gl_GNULIB_ENABLED_5264294aa0a5557541b53c8c741f7f31], [$gl_gnulib_enabled_5264294aa0a5557541b53c8c741f7f31])
   AM_CONDITIONAL([gl_GNULIB_ENABLED_03e0aaad4cb89ca757653bd367a6ccb7], [$gl_gnulib_enabled_03e0aaad4cb89ca757653bd367a6ccb7])
   AM_CONDITIONAL([gl_GNULIB_ENABLED_6099e9737f757db36c47fa9d9f02e88c], [$gl_gnulib_enabled_6099e9737f757db36c47fa9d9f02e88c])
-  AM_CONDITIONAL([gl_GNULIB_ENABLED_secure_getenv], [$gl_gnulib_enabled_secure_getenv])
   AM_CONDITIONAL([gl_GNULIB_ENABLED_strtoll], [$gl_gnulib_enabled_strtoll])
   AM_CONDITIONAL([gl_GNULIB_ENABLED_tempname], [$gl_gnulib_enabled_tempname])
   AM_CONDITIONAL([gl_GNULIB_ENABLED_682e609604ccaac6be382e4ee3a4eaec], [$gl_gnulib_enabled_682e609604ccaac6be382e4ee3a4eaec])
@@ -907,7 +891,6 @@ AC_DEFUN
   lib/readlink.c
   lib/readlinkat.c
   lib/root-uid.h
-  lib/secure_getenv.c
   lib/set-permissions.c
   lib/sha1.c
   lib/sha1.h
@@ -1008,6 +991,7 @@ AC_DEFUN
   m4/localtime-buffer.m4
   m4/longlong.m4
   m4/lstat.m4
+  m4/manywarnings-c++.m4
   m4/manywarnings.m4
   m4/md5.m4
   m4/memrchr.m4
@@ -1024,7 +1008,6 @@ AC_DEFUN
   m4/putenv.m4
   m4/readlink.m4
   m4/readlinkat.m4
-  m4/secure_getenv.m4
   m4/sha1.m4
   m4/sha256.m4
   m4/sha512.m4
diff --git a/m4/manywarnings.m4 b/m4/manywarnings.m4
index 6a8939b2c1..a3d255a940 100644
--- a/m4/manywarnings.m4
+++ b/m4/manywarnings.m4
@@ -1,4 +1,4 @@
-# manywarnings.m4 serial 10
+# manywarnings.m4 serial 11
 dnl Copyright (C) 2008-2017 Free Software Foundation, Inc.
 dnl This file is free software; the Free Software Foundation
 dnl gives unlimited permission to copy and/or distribute it,
@@ -33,8 +33,16 @@ AC_DEFUN
 # Add all documented GCC warning parameters to variable VARIABLE.
 # Note that you need to test them using gl_WARN_ADD if you want to
 # make sure your gcc understands it.
+#
+# The effects of this macro depend on the current language (_AC_LANG).
 AC_DEFUN([gl_MANYWARN_ALL_GCC],
+[_AC_LANG_DISPATCH([$0], _AC_LANG, $@)])
+
+# Specialization for _AC_LANG = C.
+AC_DEFUN([gl_MANYWARN_ALL_GCC(C)],
 [
+  AC_LANG_PUSH([C])
+
   dnl First, check for some issues that only occur when combining multiple
   dnl gcc warning categories.
   AC_REQUIRE([AC_PROG_CC])
@@ -303,4 +311,12 @@ AC_DEFUN
   fi
 
   $1=$gl_manywarn_set
+
+  AC_LANG_POP([C])
+])
+
+# Specialization for _AC_LANG = C++.
+AC_DEFUN([gl_MANYWARN_ALL_GCC(C++)],
+[
+  gl_MANYWARN_ALL_GCC_CXX_IMPL([$1])
 ])
diff --git a/m4/secure_getenv.m4 b/m4/secure_getenv.m4
deleted file mode 100644
index 6bd4afd9c1..0000000000
--- a/m4/secure_getenv.m4
+++ /dev/null
@@ -1,26 +0,0 @@
-# Look up an environment variable more securely.
-dnl Copyright 2013-2017 Free Software Foundation, Inc.
-dnl This file is free software; the Free Software Foundation
-dnl gives unlimited permission to copy and/or distribute it,
-dnl with or without modifications, as long as this notice is preserved.
-
-AC_DEFUN([gl_FUNC_SECURE_GETENV],
-[
-  dnl Persuade glibc <stdlib.h> to declare secure_getenv().
-  AC_REQUIRE([AC_USE_SYSTEM_EXTENSIONS])
-
-  AC_REQUIRE([gl_STDLIB_H_DEFAULTS])
-  AC_CHECK_FUNCS_ONCE([secure_getenv])
-  if test $ac_cv_func_secure_getenv = no; then
-    HAVE_SECURE_GETENV=0
-  fi
-])
-
-# Prerequisites of lib/secure_getenv.c.
-AC_DEFUN([gl_PREREQ_SECURE_GETENV], [
-  AC_CHECK_FUNCS([__secure_getenv])
-  if test $ac_cv_func___secure_getenv = no; then
-    AC_CHECK_FUNCS([issetugid])
-  fi
-  AC_CHECK_FUNCS_ONCE([getuid geteuid getgid getegid])
-])
diff --git a/m4/warnings.m4 b/m4/warnings.m4
index e697174edd..aa2735b77f 100644
--- a/m4/warnings.m4
+++ b/m4/warnings.m4
@@ -1,4 +1,4 @@
-# warnings.m4 serial 11
+# warnings.m4 serial 12
 dnl Copyright (C) 2008-2017 Free Software Foundation, Inc.
 dnl This file is free software; the Free Software Foundation
 dnl gives unlimited permission to copy and/or distribute it,
@@ -20,10 +20,12 @@
 # -----------------------------------------------------------------
 # Check if the compiler supports OPTION when compiling PROGRAM.
 #
-# FIXME: gl_Warn must be used unquoted until we can assume Autoconf
-# 2.64 or newer.
+# The effects of this macro depend on the current language (_AC_LANG).
 AC_DEFUN([gl_COMPILER_OPTION_IF],
-[AS_VAR_PUSHDEF([gl_Warn], [gl_cv_warn_[]_AC_LANG_ABBREV[]_$1])dnl
+[
+dnl FIXME: gl_Warn must be used unquoted until we can assume Autoconf
+dnl 2.64 or newer.
+AS_VAR_PUSHDEF([gl_Warn], [gl_cv_warn_[]_AC_LANG_ABBREV[]_$1])dnl
 AS_VAR_PUSHDEF([gl_Flags], [_AC_LANG_PREFIX[]FLAGS])dnl
 AS_LITERAL_IF([$1],
   [m4_pushdef([gl_Positive], m4_bpatsubst([$1], [^-Wno-], [-W]))],
@@ -51,27 +53,50 @@ AC_DEFUN
 # ------------------------------
 # Clang doesn't complain about unknown warning options unless one also
 # specifies -Wunknown-warning-option -Werror.  Detect this.
+#
+# The effects of this macro depend on the current language (_AC_LANG).
 AC_DEFUN([gl_UNKNOWN_WARNINGS_ARE_ERRORS],
+[_AC_LANG_DISPATCH([$0], _AC_LANG, $@)])
+
+# Specialization for _AC_LANG = C. This macro can be AC_REQUIREd.
+AC_DEFUN([gl_UNKNOWN_WARNINGS_ARE_ERRORS(C)],
+[
+  AC_LANG_PUSH([C])
+  gl_UNKNOWN_WARNINGS_ARE_ERRORS_IMPL
+  AC_LANG_POP([C])
+])
+
+# Specialization for _AC_LANG = C++. This macro can be AC_REQUIREd.
+AC_DEFUN([gl_UNKNOWN_WARNINGS_ARE_ERRORS(C++)],
+[
+  AC_LANG_PUSH([C++])
+  gl_UNKNOWN_WARNINGS_ARE_ERRORS_IMPL
+  AC_LANG_POP([C++])
+])
+
+AC_DEFUN([gl_UNKNOWN_WARNINGS_ARE_ERRORS_IMPL],
 [gl_COMPILER_OPTION_IF([-Werror -Wunknown-warning-option],
    [gl_unknown_warnings_are_errors='-Wunknown-warning-option -Werror'],
    [gl_unknown_warnings_are_errors=])])
 
-# gl_WARN_ADD(OPTION, [VARIABLE = WARN_CFLAGS],
+# gl_WARN_ADD(OPTION, [VARIABLE = WARN_CFLAGS/WARN_CXXFLAGS],
 #             [PROGRAM = AC_LANG_PROGRAM()])
-# ---------------------------------------------
-# Adds parameter to WARN_CFLAGS if the compiler supports it when
-# compiling PROGRAM.  For example, gl_WARN_ADD([-Wparentheses]).
+# -----------------------------------------------------------
+# Adds parameter to WARN_CFLAGS/WARN_CXXFLAGS if the compiler supports it
+# when compiling PROGRAM.  For example, gl_WARN_ADD([-Wparentheses]).
 #
 # If VARIABLE is a variable name, AC_SUBST it.
+#
+# The effects of this macro depend on the current language (_AC_LANG).
 AC_DEFUN([gl_WARN_ADD],
-[AC_REQUIRE([gl_UNKNOWN_WARNINGS_ARE_ERRORS])
+[AC_REQUIRE([gl_UNKNOWN_WARNINGS_ARE_ERRORS(]_AC_LANG[)])
 gl_COMPILER_OPTION_IF([$1],
-  [gl_AS_VAR_APPEND(m4_if([$2], [], [[WARN_CFLAGS]], [[$2]]), [" $1"])],
+  [gl_AS_VAR_APPEND(m4_if([$2], [], [[WARN_]_AC_LANG_PREFIX[FLAGS]], [[$2]]), [" $1"])],
   [],
   [$3])
 m4_ifval([$2],
          [AS_LITERAL_IF([$2], [AC_SUBST([$2])])],
-         [AC_SUBST([WARN_CFLAGS])])dnl
+         [AC_SUBST([WARN_]_AC_LANG_PREFIX[FLAGS])])dnl
 ])
 
 # Local Variables:
-- 
2.13.4