This is the mail archive of the libc-alpha@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] Ensure __libc_message does not blindly write toSTDERR_FILENO.


[BZ #13983]
* sysdeps/posix/libc_fatal.c (__libc_message): In the event that
  stderr has been closed using fclose(), we should not try to use
  STDERR_FILENO.
  Doing so may result in blind private information leaks.
* sysdeps/unix/sysv/linux/libc_fatal.c (__libc_message): Likewise.

Signed-off-by: William Pitcock <nenolod@dereferenced.org>
---
 ChangeLog                            |    9 +++++++++
 sysdeps/posix/libc_fatal.c           |   11 +++++++++--
 sysdeps/unix/sysv/linux/libc_fatal.c |   11 +++++++++--
 3 files changed, 27 insertions(+), 4 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 95c737f..dec88f7 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+2012-04-16  William Pitcock  <nenolod@dereferenced.org>
+
+	[BZ #13983]
+	* sysdeps/posix/libc_fatal.c (__libc_message): In the event that
+	  stderr has been closed using fclose(), we should not try to use
+	  STDERR_FILENO.
+	  Doing so may result in blind private information leaks.
+	* sysdeps/unix/sysv/linux/libc_fatal.c (__libc_message): Likewise.
+
 2012-04-16  Marek Polacek  <polacek@redhat.com>
 
 	* sysdeps/i386/fpu/bits/fenv.h (feraiseexcept): Reverse the
diff --git a/sysdeps/posix/libc_fatal.c b/sysdeps/posix/libc_fatal.c
index 62acb9b..863d978 100644
--- a/sysdeps/posix/libc_fatal.c
+++ b/sysdeps/posix/libc_fatal.c
@@ -65,8 +65,14 @@ __libc_message (int do_abort, const char *fmt, ...)
   if (on_2 == NULL || *on_2 == '\0')
     fd = open_not_cancel_2 (_PATH_TTY, O_RDWR | O_NOCTTY | O_NDELAY);
 
-  if (fd == -1)
-    fd = STDERR_FILENO;
+  /* _IO_stderr stays around forever even through fclose(), use it to learn
+     if stderr is still opened or not.  if stderr is not opened, then _fileno
+     is -1.  We *must* use _IO_stderr and not stderr, as stderr can be overriden
+     by the application. */
+  if (fd == -1 && _IO_stderr->_fileno == STDERR_FILENO)
+    fd = _IO_stderr->_fileno;
+  else
+    goto do_vsyslog;
 
   struct str_list *list = NULL;
   int nlist = 0;
@@ -154,6 +160,7 @@ __libc_message (int do_abort, const char *fmt, ...)
 
   /* If we  had no success writing the message, use syslog.  */
   if (! written)
+do_vsyslog:
     vsyslog (LOG_ERR, fmt, ap_copy);
 
   va_end (ap_copy);
diff --git a/sysdeps/unix/sysv/linux/libc_fatal.c b/sysdeps/unix/sysv/linux/libc_fatal.c
index 58a5a7f8..5df7031 100644
--- a/sysdeps/unix/sysv/linux/libc_fatal.c
+++ b/sysdeps/unix/sysv/linux/libc_fatal.c
@@ -68,8 +68,14 @@ __libc_message (int do_abort, const char *fmt, ...)
   if (on_2 == NULL || *on_2 == '\0')
     fd = open_not_cancel_2 (_PATH_TTY, O_RDWR | O_NOCTTY | O_NDELAY);
 
-  if (fd == -1)
-    fd = STDERR_FILENO;
+  /* _IO_stderr stays around forever even through fclose(), use it to learn
+     if stderr is still opened or not.  if stderr is not opened, then _fileno
+     is -1.  We *must* use _IO_stderr and not stderr, as stderr can be overriden
+     by the application. */
+  if (fd == -1 && _IO_stderr->_fileno == STDERR_FILENO)
+    fd = _IO_stderr->_fileno;
+  else
+    goto do_vsyslog;
 
   struct str_list *list = NULL;
   int nlist = 0;
@@ -164,6 +170,7 @@ __libc_message (int do_abort, const char *fmt, ...)
 
   /* If we  had no success writing the message, use syslog.  */
   if (! written)
+do_vsyslog:
     vsyslog (LOG_ERR, fmt, ap_copy);
 
   va_end (ap_copy);
-- 
1.7.9.5


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]