diff options
author | Eric Blake <eblake@redhat.com> | 2007-05-16 20:06:08 +0000 |
---|---|---|
committer | Eric Blake <eblake@redhat.com> | 2007-05-16 20:06:08 +0000 |
commit | d009633d30f746b0f5c53442e5f37743653deb9d (patch) | |
tree | f1d00e10cb343e0868eb8e7528beda87fac7908e /newlib/libc/stdio64 | |
parent | 895d76fed6448bb19559f57195a60ae311d0cac0 (diff) | |
download | newlib-d009633d30f746b0f5c53442e5f37743653deb9d.zip newlib-d009633d30f746b0f5c53442e5f37743653deb9d.tar.gz newlib-d009633d30f746b0f5c53442e5f37743653deb9d.tar.bz2 |
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.
Diffstat (limited to 'newlib/libc/stdio64')
-rw-r--r-- | newlib/libc/stdio64/tmpfile64.c | 23 |
1 files changed, 19 insertions, 4 deletions
diff --git a/newlib/libc/stdio64/tmpfile64.c b/newlib/libc/stdio64/tmpfile64.c index 9868963..e15f1c6 100644 --- a/newlib/libc/stdio64/tmpfile64.c +++ b/newlib/libc/stdio64/tmpfile64.c @@ -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 */ - |