malloc: Abort on heap corruption, without a backtrace [BZ #21754]

The stack trace printing caused deadlocks and has been itself been
targeted by code execution exploits.

(cherry-picked from ec2c1fcefb)
This commit is contained in:
Florian Weimer 2017-08-30 16:39:41 +02:00 committed by Siddhesh Poyarekar
parent aaa2eb83b8
commit 8788996793
5 changed files with 39 additions and 51 deletions

View File

@ -1,3 +1,12 @@
2017-08-30 Florian Weimer <fweimer@redhat.com>
[BZ #21754]
* malloc/malloc.c (malloc_printerr): Always terminate the process,
without printing a backtrace. Do not leak any information in the
error message.
* manual/memory.texi (Heap Consistency Checking): Update.
* manual/tunables.texi (Memory Allocation Tunables): Likewise.
2017-11-17 Tulio Magno Quites Machado Filho <tuliom@linux.vnet.ibm.com> 2017-11-17 Tulio Magno Quites Machado Filho <tuliom@linux.vnet.ibm.com>
* sysdeps/powerpc/bits/hwcap.h (PPC_FEATURE2_HTM_NO_SUSPEND): New * sysdeps/powerpc/bits/hwcap.h (PPC_FEATURE2_HTM_NO_SUSPEND): New

10
NEWS
View File

@ -7,6 +7,16 @@ using `glibc' in the "product" field.
Version 2.26.1 Version 2.26.1
Major new features:
* In order to support faster and safer process termination the malloc API
family of functions will no longer print a failure address and stack
backtrace after detecting heap corruption. The goal is to minimize the
amount of work done after corruption is detected and to avoid potential
security issues in continued process execution. Reducing shutdown time
leads to lower overall process restart latency, so there is benefit both
from a security and performance perspective.
Security related changes: Security related changes:
CVE-2009-5064: The ldd script would sometimes run the program under CVE-2009-5064: The ldd script would sometimes run the program under

View File

@ -1019,7 +1019,8 @@ static void* _int_realloc(mstate, mchunkptr, INTERNAL_SIZE_T,
static void* _int_memalign(mstate, size_t, size_t); static void* _int_memalign(mstate, size_t, size_t);
static void* _mid_memalign(size_t, size_t, void *); static void* _mid_memalign(size_t, size_t, void *);
static void malloc_printerr(int action, const char *str, void *ptr, mstate av); static void malloc_printerr(int action, const char *str, void *ptr, mstate av)
__attribute__ ((noreturn));
static void* internal_function mem2mem_check(void *p, size_t sz); static void* internal_function mem2mem_check(void *p, size_t sz);
static int internal_function top_check(void); static int internal_function top_check(void);
@ -5399,24 +5400,8 @@ malloc_printerr (int action, const char *str, void *ptr, mstate ar_ptr)
if (ar_ptr) if (ar_ptr)
set_arena_corrupt (ar_ptr); set_arena_corrupt (ar_ptr);
if ((action & 5) == 5) __libc_message (do_abort, "%s\n", str);
__libc_message ((action & 2) ? (do_abort | do_backtrace) : do_message, __builtin_unreachable ();
"%s\n", str);
else if (action & 1)
{
char buf[2 * sizeof (uintptr_t) + 1];
buf[sizeof (buf) - 1] = '\0';
char *cp = _itoa_word ((uintptr_t) ptr, &buf[sizeof (buf) - 1], 16, 0);
while (cp > buf)
*--cp = '0';
__libc_message ((action & 2) ? (do_abort | do_backtrace) : do_message,
"*** Error in `%s': %s: 0x%s ***\n",
__libc_argv[0] ? : "<unknown>", str, cp);
}
else if (action & 2)
abort ();
} }
/* We need a wrapper function for one of the additions of POSIX. */ /* We need a wrapper function for one of the additions of POSIX. */

View File

@ -1309,17 +1309,15 @@ The block was already freed.
Another possibility to check for and guard against bugs in the use of Another possibility to check for and guard against bugs in the use of
@code{malloc}, @code{realloc} and @code{free} is to set the environment @code{malloc}, @code{realloc} and @code{free} is to set the environment
variable @code{MALLOC_CHECK_}. When @code{MALLOC_CHECK_} is set, a variable @code{MALLOC_CHECK_}. When @code{MALLOC_CHECK_} is set to a
special (less efficient) implementation is used which is designed to be non-zero value, a special (less efficient) implementation is used which
tolerant against simple errors, such as double calls of @code{free} with is designed to be tolerant against simple errors, such as double calls
the same argument, or overruns of a single byte (off-by-one bugs). Not of @code{free} with the same argument, or overruns of a single byte
all such errors can be protected against, however, and memory leaks can (off-by-one bugs). Not all such errors can be protected against,
result. If @code{MALLOC_CHECK_} is set to @code{0}, any detected heap however, and memory leaks can result.
corruption is silently ignored; if set to @code{1}, a diagnostic is
printed on @code{stderr}; if set to @code{2}, @code{abort} is called Any detected heap corruption results in immediate termination of the
immediately. This can be useful because otherwise a crash may happen process.
much later, and the true cause for the problem is then very hard to
track down.
There is one problem with @code{MALLOC_CHECK_}: in SUID or SGID binaries There is one problem with @code{MALLOC_CHECK_}: in SUID or SGID binaries
it could possibly be exploited since diverging from the normal programs it could possibly be exploited since diverging from the normal programs

View File

@ -71,27 +71,13 @@ following tunables in the @code{malloc} namespace:
This tunable supersedes the @env{MALLOC_CHECK_} environment variable and is This tunable supersedes the @env{MALLOC_CHECK_} environment variable and is
identical in features. identical in features.
Setting this tunable enables a special (less efficient) memory allocator for Setting this tunable to a non-zero value enables a special (less
the malloc family of functions that is designed to be tolerant against simple efficient) memory allocator for the malloc family of functions that is
errors such as double calls of free with the same argument, or overruns of a designed to be tolerant against simple errors such as double calls of
single byte (off-by-one bugs). Not all such errors can be protected against, free with the same argument, or overruns of a single byte (off-by-one
however, and memory leaks can result. The following list describes the values bugs). Not all such errors can be protected against, however, and memory
that this tunable can take and the effect they have on malloc functionality: leaks can result. Any detected heap corruption results in immediate
termination of the process.
@itemize @bullet
@item @code{0} Ignore all errors. The default allocator continues to be in
use, but all errors are silently ignored.
@item @code{1} Report errors. The alternate allocator is selected and heap
corruption, if detected, is reported as diagnostic messages to @code{stderr}
and the program continues execution.
@item @code{2} Abort on errors. The alternate allocator is selected and if
heap corruption is detected, the program is ended immediately by calling
@code{abort}.
@item @code{3} Fully enabled. The alternate allocator is selected and is fully
functional. That is, if heap corruption is detected, a verbose diagnostic
message is printed to @code{stderr} and the program is ended by calling
@code{abort}.
@end itemize
Like @env{MALLOC_CHECK_}, @code{glibc.malloc.check} has a problem in that it Like @env{MALLOC_CHECK_}, @code{glibc.malloc.check} has a problem in that it
diverges from normal program behavior by writing to @code{stderr}, which could diverges from normal program behavior by writing to @code{stderr}, which could