From: ericb Date: Wed, 16 May 2007 20:06:07 +0000 (+0000) Subject: Close security hole in tmpfile. X-Git-Url: http://git.osdn.net/view?a=commitdiff_plain;h=5ce887d4fdcf8380ef9b77b8520fb412f2fea92c;p=pf3gnuchains%2Fpf3gnuchains3x.git 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. --- diff --git a/newlib/ChangeLog b/newlib/ChangeLog index 699dbd4212..17a8a42c34 100644 --- a/newlib/ChangeLog +++ b/newlib/ChangeLog @@ -1,5 +1,10 @@ 2007-05-16 Eric Blake + 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. diff --git a/newlib/libc/stdio/tmpfile.c b/newlib/libc/stdio/tmpfile.c index a6c2c91362..902ef0b4df 100644 --- a/newlib/libc/stdio/tmpfile.c +++ b/newlib/libc/stdio/tmpfile.c @@ -49,6 +49,11 @@ Supporting OS subroutines required: <>, <>, <>, #include #include #include +#include + +#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; diff --git a/newlib/libc/stdio64/tmpfile64.c b/newlib/libc/stdio64/tmpfile64.c index 98689631fc..e15f1c653d 100644 --- a/newlib/libc/stdio64/tmpfile64.c +++ b/newlib/libc/stdio64/tmpfile64.c @@ -49,6 +49,11 @@ Supporting OS subroutines required: <>, <>, <>, #include #include +#include + +#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 */ -