bug-glibc
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

glibc 2.2.2 suggestion: mkstemp port for GNU apps on non-glibc hosts


From: Paul Eggert
Subject: glibc 2.2.2 suggestion: mkstemp port for GNU apps on non-glibc hosts
Date: Mon, 26 Feb 2001 15:18:15 -0800 (PST)

Recently I modified GNU diffutils to use mkstemp instead of its own
temp-file creator, to avoid the usual security problems.  I want
diffutils to continue to work properly even on older hosts that lack
mkstemp, so I plan to include a copy of glibc mkstemp in the diffutils
distribution, and use it those older hosts.

glibc mkstemp currently assumes it's being built with glibc, but it's
not hard to change it so that it's portable to non-glibc platforms.
Here is a proposed patch to do this.

2001-02-26  Paul Eggert  <address@hidden>

        Modify mkstemp.c and tempname.c so that they can be used by
        GNU applications on non-glibc platforms.

        * misc/mkstemp.c (__GT_FILE): Define to zero if not defined.
        (__gen_tempname): New decl.

        * sysdeps/posix/tempname.c:
        Include <config.h> if HAVE_CONFIG_H.
        Include <stddef.h>, <stdint.h>, <string.h> only if
        STDC_HEADERS || _LIBC.
        Include <fcntl.h> only if HAVE_FCNTL_H || _LIBC.
        Include <unistd.h> only if HAVE_UNISTD_H || _LIBC.
        Include <sys/time.h> only if HAVE_SYS_TIME_H || _LIBC.
        (__set_errno): Define this macro if <errno.h> doesn't.
        (P_tmpdir, TMP_MAX, __GT_FILE, __GT_BIGFILE, __GT_DIR, __GT_NOCREATE):
        Define these macros if <stdio.h> doesn't.
        (S_ISDIR, S_IRUSR, S_IWUSR, S_IXUSR):
        Define these macros if <sys/stat.h> doesn't.
        Ignore <sys/stat.h> S_ISDIR if STAT_MACROS_BROKEN.
        (stat64, __getpid, __gettimeofday, __mkdir, __open, __open64,
        lxstat64, __xstat64): Define if not _LIBC.
        (struct_stat64): New macro.
        (direxists, __gen_tempname): Use it, to avoid a
        portability problem with Solaris 8.
        (__secure_getenv): Define if ! (HAVE___SECURE_GETENV || _LIBC).
        (__gen_tempname): Invoke gettimeofday only if
        HAVE_GETTIMEOFDAY || _LIBC; otherwise, fall back on plain "time".
        Use portable macros like S_IRUSR | S_IWUSR rather than nonportable
        octal values like 0600.

--- misc/mkstemp.c      1999/07/06 15:26:07     2.2
+++ misc/mkstemp.c      2001/01/10 00:04:36     2.2.0.1
@@ -19,6 +19,12 @@
 #include <stdio.h>
 #include <stdlib.h>
 
+#ifndef __GT_FILE
+# define __GT_FILE 0
+#endif
+
+int __gen_tempname ();
+
 /* Generate a unique temporary file name from TEMPLATE.
    The last six characters of TEMPLATE must be "XXXXXX";
    they are replaced with a string that makes the filename unique.
--- sysdeps/posix/tempname.c    2000/09/11 16:05:16     2.2
+++ sysdeps/posix/tempname.c    2001/01/10 00:34:21     2.2.0.2
@@ -16,24 +16,102 @@
    write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
    Boston, MA 02111-1307, USA.  */
 
-#include <stddef.h>
-#include <stdint.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
+#if HAVE_CONFIG_H
+# include <config.h>
+#endif
+
 #include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <sys/time.h>
 #include <assert.h>
 
+#include <errno.h>
+#ifndef __set_errno
+# define __set_errno(Val) errno = (Val)
+#endif
+
+#include <stdio.h>
+#ifndef P_tmpdir
+# define P_tmpdir "/tmp"
+#endif
+#ifndef TMP_MAX
+# define TMP_MAX 238328
+#endif
+#ifndef __GT_FILE
+# define __GT_FILE     0
+# define __GT_BIGFILE  1
+# define __GT_DIR      2
+# define __GT_NOCREATE 3
+#endif
+
+#if STDC_HEADERS || _LIBC
+# include <stddef.h>
+# include <stdlib.h>
+# include <string.h>
+#endif
+
+#if HAVE_FCNTL_H || _LIBC
+# include <fcntl.h>
+#endif
+
+#if HAVE_SYS_TIME_H || _LIBC
+# include <sys/time.h>
+#endif
+
+#if HAVE_STDINT_H || _LIBC
+# include <stdint.h>
+#endif
+
+#if HAVE_UNISTD_H || _LIBC
+# include <unistd.h>
+#endif
+
+#include <sys/stat.h>
+#if STAT_MACROS_BROKEN
+# undef S_ISDIR
+#endif
+#if !defined S_ISDIR && defined S_IFDIR
+# define S_ISDIR(mode) (((mode) & S_IFMT) == S_IFDIR)
+#endif
+#if !S_IRUSR && S_IREAD
+# define S_IRUSR S_IREAD
+#endif
+#if !S_IRUSR
+# define S_IRUSR 00400
+#endif
+#if !S_IWUSR && S_IWRITE
+# define S_IWUSR S_IWRITE
+#endif
+#if !S_IWUSR
+# define S_IWUSR 00200
+#endif
+#if !S_IXUSR && S_IEXEC
+# define S_IXUSR S_IEXEC
+#endif
+#if !S_IXUSR
+# define S_IXUSR 00100
+#endif
+
+#if _LIBC
+# define struct_stat64 struct stat64
+#else
+# define struct_stat64 struct stat
+# define __getpid getpid
+# define __gettimeofday gettimeofday
+# define __mkdir mkdir
+# define __open open
+# define __open64 open
+# define __lxstat64(version, path, buf) lstat (path, buf)
+# define __xstat64(version, path, buf) stat (path, buf)
+#endif
+
+#if ! (HAVE___SECURE_GETENV || _LIBC)
+# define __secure_getenv getenv
+#endif
+
 /* Return nonzero if DIR is an existent directory.  */
 static int
 direxists (const char *dir)
 {
-  struct stat64 buf;
+  struct_stat64 buf;
   return __xstat64 (_STAT_VER, dir, &buf) == 0 && S_ISDIR (buf.st_mode);
 }
 
@@ -124,10 +202,10 @@ __gen_tempname (char *tmpl, int kind)
   int len;
   char *XXXXXX;
   static uint64_t value;
-  struct timeval tv;
+  uint64_t random_time_bits;
   int count, fd = -1;
   int save_errno = errno;
-  struct stat64 st;
+  struct_stat64 st;
 
   len = strlen (tmpl);
   if (len < 6 || strcmp (&tmpl[len - 6], "XXXXXX"))
@@ -140,8 +218,16 @@ __gen_tempname (char *tmpl, int kind)
   XXXXXX = &tmpl[len - 6];
 
   /* Get some more or less random data.  */
-  __gettimeofday (&tv, NULL);
-  value += ((uint64_t) tv.tv_usec << 16) ^ tv.tv_sec ^ __getpid ();
+#if HAVE_GETTIMEOFDAY || _LIBC
+  {
+    struct timeval tv;
+    __gettimeofday (&tv, NULL);
+    random_time_bits = ((uint64_t) tv.tv_usec << 16) ^ tv.tv_sec;
+  }
+#else
+  random_time_bits = time (NULL);
+#endif
+  value += random_time_bits ^ __getpid ();
 
   for (count = 0; count < TMP_MAX; value += 7777, ++count)
     {
@@ -163,15 +249,15 @@ __gen_tempname (char *tmpl, int kind)
       switch (kind)
        {
        case __GT_FILE:
-         fd = __open (tmpl, O_RDWR | O_CREAT | O_EXCL, 0600);
+         fd = __open (tmpl, O_RDWR | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR);
          break;
 
        case __GT_BIGFILE:
-         fd = __open64 (tmpl, O_RDWR | O_CREAT | O_EXCL, 0600);
+         fd = __open64 (tmpl, O_RDWR | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR);
          break;
 
        case __GT_DIR:
-         fd = __mkdir (tmpl, 0700);
+         fd = __mkdir (tmpl, S_IRUSR | S_IWUSR | S_IXUSR);
          break;
 
        case __GT_NOCREATE:




reply via email to

[Prev in Thread] Current Thread [Next in Thread]