OSDN Git Service

Close security hole in tmpfile.
authorericb <ericb>
Wed, 16 May 2007 20:06:07 +0000 (20:06 +0000)
committerericb <ericb>
Wed, 16 May 2007 20:06:07 +0000 (20:06 +0000)
* libc/stdio/tmpfile.c (_tmpfile_r): Avoid window between filename
generation and opening the fd.
* libc/stdio64/tmpfile64.c (_tmpfile64_r): Likewise.

newlib/ChangeLog
newlib/libc/stdio/tmpfile.c
newlib/libc/stdio64/tmpfile64.c

index 699dbd4..17a8a42 100644 (file)
@@ -1,5 +1,10 @@
 2007-05-16  Eric Blake  <ebb9@byu.net>
 
+       Close security hole in tmpfile.
+       * libc/stdio/tmpfile.c (_tmpfile_r): Avoid window between filename
+       generation and opening the fd.
+       * libc/stdio64/tmpfile64.c (_tmpfile64_r): Likewise.
+
        * libc/include/math.h (INFINITY, NAN, FP_ILOGB0, FP_ILOGBNAN)
        (MATH_ERRNO, MATH_ERREXCEPT, math_errhandling): Add macros
        required by POSIX.
index a6c2c91..902ef0b 100644 (file)
@@ -49,6 +49,11 @@ Supporting OS subroutines required: <<close>>, <<fstat>>, <<getpid>>,
 #include <reent.h>
 #include <stdio.h>
 #include <errno.h>
+#include <fcntl.h>
+
+#ifndef O_BINARY
+# define O_BINARY 0
+#endif
 
 FILE *
 _DEFUN(_tmpfile_r, (ptr),
@@ -58,11 +63,22 @@ _DEFUN(_tmpfile_r, (ptr),
   int e;
   char *f;
   char buf[L_tmpnam];
-
-  if ((f = _tmpnam_r (ptr, buf)) == NULL)
+  int fd;
+
+  do
+    {
+      if ((f = _tmpnam_r (ptr, buf)) == NULL)
+       return NULL;
+      fd = _open_r (ptr, f, O_RDWR | O_CREAT | O_EXCL | O_BINARY,
+                   S_IRUSR | S_IWUSR);
+    }
+  while (fd < 0 && ptr->_errno == EEXIST);
+  if (fd < 0)
     return NULL;
-  fp = _fopen_r (ptr, f, "wb+");
+  fp = _fdopen_r (ptr, fd, "wb+");
   e = ptr->_errno;
+  if (!fp)
+    _close_r (ptr, fd);
   _CAST_VOID _remove_r (ptr, f);
   ptr->_errno = e;
   return fp;
index 9868963..e15f1c6 100644 (file)
@@ -49,6 +49,11 @@ Supporting OS subroutines required: <<close>>, <<fstat>>, <<getpid>>,
 
 #include <stdio.h>
 #include <errno.h>
+#include <fcntl.h>
+
+#ifndef O_BINARY
+# define O_BINARY 0
+#endif
 
 #ifdef __LARGE64_FILES
 
@@ -60,11 +65,22 @@ _DEFUN (_tmpfile64_r, (ptr),
   int e;
   char *f;
   char buf[L_tmpnam];
-
-  if ((f = _tmpnam_r (ptr, buf)) == NULL)
+  int fd;
+
+  do
+  {
+     if ((f = _tmpnam_r (ptr, buf)) == NULL)
+       return NULL;
+      fd = _open64_r (ptr, f, O_RDWR | O_CREAT | O_EXCL | O_BINARY,
+                     S_IRUSR | S_IWUSR);
+  }
+  while (fd < 0 && ptr->_errno == EEXIST);
+  if (fd < 0)
     return NULL;
-  fp = _fopen64_r (ptr, (const char *)f, "wb+");
+  fp = _fdopen64_r (ptr, fd, "wb+");
   e = ptr->_errno;
+  if (!fp)
+    _close_r (ptr, fd);
   _CAST_VOID _remove_r (ptr, f);
   ptr->_errno = e;
   return fp;
@@ -81,4 +97,3 @@ _DEFUN_VOID (tmpfile64)
 #endif
 
 #endif /* __LARGE64_FILES */
-