abort: Do not flush stdio streams [BZ #15436]

This commit is contained in:
Florian Weimer 2017-10-05 14:48:16 +02:00
parent 0c25125780
commit 91e7cf982d
3 changed files with 17 additions and 24 deletions

View File

@ -1,3 +1,10 @@
2017-10-05 Florian Weimer <fweimer@redhat.com>
[BZ #15436]
Do not flush stdio streams on abort.
* stdlib/abort.c (fflush): Remove macro definition.
(abort): Remove stages related to stdio flushing.
2017-10-05 Florian Weimer <fweimer@redhat.com>
* gmon/Makefile (CFLAGS-tst-gmon.c): Add -fno-omit-frame-pointer.

5
NEWS
View File

@ -24,6 +24,11 @@ Major new features:
leads to lower overall process restart latency, so there is benefit both
from a security and performance perspective.
* The abort function terminates the process immediately, without flushing
stdio streams. Previous glibc versions used to flush streams, resulting
in deadlocks and further data corruption. This change also affects
process aborts as the result of assertion failures.
Deprecated and removed features, and other changes affecting compatibility:
* On GNU/Linux, the obsolete Linux constant PTRACE_SEIZE_DEVEL is no longer

View File

@ -31,9 +31,6 @@
# define ABORT_INSTRUCTION
#endif
#include <libio/libioP.h>
#define fflush(s) _IO_flush_all_lockp (0)
/* Exported variable to locate abort message in core files etc. */
struct abort_msg_s *__abort_msg __attribute__ ((nocommon));
libc_hidden_def (__abort_msg)
@ -67,16 +64,8 @@ abort (void)
__sigprocmask (SIG_UNBLOCK, &sigs, 0);
}
/* Flush all streams. We cannot close them now because the user
might have registered a handler for SIGABRT. */
if (stage == 1)
{
++stage;
fflush (NULL);
}
/* Send signal which possibly calls a user handler. */
if (stage == 2)
if (stage == 1)
{
/* This stage is special: we must allow repeated calls of
`abort' when a user defined handler for SIGABRT is installed.
@ -94,7 +83,7 @@ abort (void)
}
/* There was a handler installed. Now remove it. */
if (stage == 3)
if (stage == 2)
{
++stage;
memset (&act, '\0', sizeof (struct sigaction));
@ -104,30 +93,22 @@ abort (void)
__sigaction (SIGABRT, &act, NULL);
}
/* Now close the streams which also flushes the output the user
defined handler might has produced. */
if (stage == 4)
{
++stage;
__fcloseall ();
}
/* Try again. */
if (stage == 5)
if (stage == 3)
{
++stage;
raise (SIGABRT);
}
/* Now try to abort using the system specific command. */
if (stage == 6)
if (stage == 4)
{
++stage;
ABORT_INSTRUCTION;
}
/* If we can't signal ourselves and the abort instruction failed, exit. */
if (stage == 7)
if (stage == 5)
{
++stage;
_exit (127);