1
0
mirror of https://sourceware.org/git/glibc.git synced 2025-08-07 06:43:00 +03:00

Do not print backtraces on fatal glibc errors

If the process is in a bad state, we used to print backtraces in
many cases.  This is problematic because doing so could involve
a lot of work, like loading libgcc_s using the dynamic linker,
and this could itself be targeted by exploit writers.  For example,
if the crashing process was forked from a long-lived process, the
addresses in the error message could be used to bypass ASLR.

Commit ed421fca42 ("Avoid backtrace from
__stack_chk_fail [BZ #12189]"), backtraces where no longer printed
because backtrace_and_maps was always called with do_abort == 1.

Rather than fixing this logic error, this change removes the backtrace
functionality from the sources.  With the prevalence of external crash
handlers, it does not appear to be particularly useful.  The crash
handler may also destroy useful information for debugging.

Reviewed-by: Carlos O'Donell <carlos@redhat.com>
This commit is contained in:
Florian Weimer
2019-08-19 15:41:29 +02:00
parent 1d714fd95d
commit a289ea09ea
6 changed files with 26 additions and 97 deletions

View File

@@ -45,16 +45,6 @@ writev_for_fatal (int fd, const struct iovec *iov, size_t niov, size_t total)
}
#endif
#ifndef BEFORE_ABORT
# define BEFORE_ABORT before_abort
static void
before_abort (int do_abort __attribute__ ((unused)),
bool written __attribute__ ((unused)),
int fd __attribute__ ((unused)))
{
}
#endif
struct str_list
{
const char *str;
@@ -75,17 +65,6 @@ __libc_message (enum __libc_message_action action, const char *fmt, ...)
FATAL_PREPARE;
#endif
/* Don't call __libc_secure_getenv if we aren't doing backtrace, which
may access the corrupted stack. */
if ((action & do_backtrace))
{
/* Open a descriptor for /dev/tty unless the user explicitly
requests errors on standard error. */
const char *on_2 = __libc_secure_getenv ("LIBC_FATAL_STDERR_");
if (on_2 == NULL || *on_2 == '\0')
fd = __open_nocancel (_PATH_TTY, O_RDWR | O_NOCTTY | O_NDELAY);
}
if (fd == -1)
fd = STDERR_FILENO;
@@ -129,7 +108,6 @@ __libc_message (enum __libc_message_action action, const char *fmt, ...)
++nlist;
}
bool written = false;
if (nlist > 0)
{
struct iovec *iov = alloca (nlist * sizeof (struct iovec));
@@ -143,7 +121,7 @@ __libc_message (enum __libc_message_action action, const char *fmt, ...)
list = list->next;
}
written = WRITEV_FOR_FATAL (fd, iov, nlist, total);
WRITEV_FOR_FATAL (fd, iov, nlist, total);
if ((action & do_abort))
{
@@ -173,13 +151,8 @@ __libc_message (enum __libc_message_action action, const char *fmt, ...)
va_end (ap);
if ((action & do_abort))
{
if ((action & do_backtrace))
BEFORE_ABORT (do_abort, written, fd);
/* Kill the application. */
abort ();
}
/* Kill the application. */
abort ();
}
@@ -188,6 +161,6 @@ __libc_fatal (const char *message)
{
/* The loop is added only to keep gcc happy. */
while (1)
__libc_message (do_abort | do_backtrace, "%s", message);
__libc_message (do_abort, "%s", message);
}
libc_hidden_def (__libc_fatal)