1
0
mirror of https://sourceware.org/git/glibc.git synced 2025-08-08 17:42:12 +03:00

Avoid backtrace from __stack_chk_fail [BZ #12189]

__stack_chk_fail is called on corrupted stack.  Stack backtrace is very
unreliable against corrupted stack.  __libc_message is changed to accept
enum __libc_message_action and call BEFORE_ABORT only if action includes
do_backtrace.  __fortify_fail_abort is added to avoid backtrace from
__stack_chk_fail.

	[BZ #12189]
	* debug/Makefile (CFLAGS-tst-ssp-1.c): New.
	(tests): Add tst-ssp-1 if -fstack-protector works.
	* debug/fortify_fail.c: Include <stdbool.h>.
	(_fortify_fail_abort): New function.
	(__fortify_fail): Call _fortify_fail_abort.
	(__fortify_fail_abort): Add a hidden definition.
	* debug/stack_chk_fail.c: Include <stdbool.h>.
	(__stack_chk_fail): Call __fortify_fail_abort, instead of
	__fortify_fail.
	* debug/tst-ssp-1.c: New file.
	* include/stdio.h (__libc_message_action): New enum.
	(__libc_message): Replace int with enum __libc_message_action.
	(__fortify_fail_abort): New hidden prototype.
	* malloc/malloc.c (malloc_printerr): Update __libc_message calls.
	* sysdeps/posix/libc_fatal.c (__libc_message): Replace int
	with enum __libc_message_action.  Call BEFORE_ABORT only if
	action includes do_backtrace.
	(__libc_fatal): Update __libc_message call.
This commit is contained in:
H.J. Lu
2017-07-11 07:44:01 -07:00
parent 94070f86c0
commit ed421fca42
8 changed files with 110 additions and 11 deletions

View File

@@ -64,7 +64,7 @@ struct str_list
/* Abort with an error message. */
void
__libc_message (int do_abort, const char *fmt, ...)
__libc_message (enum __libc_message_action action, const char *fmt, ...)
{
va_list ap;
int fd = -1;
@@ -140,7 +140,7 @@ __libc_message (int do_abort, const char *fmt, ...)
written = WRITEV_FOR_FATAL (fd, iov, nlist, total);
if (do_abort)
if ((action & do_abort))
{
total = ((total + 1 + GLRO(dl_pagesize) - 1)
& ~(GLRO(dl_pagesize) - 1));
@@ -167,9 +167,10 @@ __libc_message (int do_abort, const char *fmt, ...)
va_end (ap);
if (do_abort)
if ((action & do_abort))
{
BEFORE_ABORT (do_abort, written, fd);
if ((action & do_backtrace))
BEFORE_ABORT (do_abort, written, fd);
/* Kill the application. */
abort ();
@@ -182,6 +183,6 @@ __libc_fatal (const char *message)
{
/* The loop is added only to keep gcc happy. */
while (1)
__libc_message (1, "%s", message);
__libc_message (do_abort | do_backtrace, "%s", message);
}
libc_hidden_def (__libc_fatal)