about summary refs log tree commit diff
diff options
context:
space:
mode:
authorFlorian Weimer <fweimer@redhat.com>2017-08-30 16:39:41 +0200
committerSiddhesh Poyarekar <siddhesh@sourceware.org>2017-11-28 19:07:55 +0530
commit87889967934d237b11f98945a96c46f0015445e0 (patch)
tree6f70823d782d2963d3057f787fba173b843e3f1c
parentaaa2eb83b8b6623ddb9cea44445b5342f96100be (diff)
downloadglibc-87889967934d237b11f98945a96c46f0015445e0.tar.gz
glibc-87889967934d237b11f98945a96c46f0015445e0.tar.xz
glibc-87889967934d237b11f98945a96c46f0015445e0.zip
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 ec2c1fcefb200c6cb7e09553f3c6af8815013d83)
-rw-r--r--ChangeLog9
-rw-r--r--NEWS10
-rw-r--r--malloc/malloc.c23
-rw-r--r--manual/memory.texi20
-rw-r--r--manual/tunables.texi28
5 files changed, 39 insertions, 51 deletions
diff --git a/ChangeLog b/ChangeLog
index 812c5380f1..7a35bff06b 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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>
 
 	* sysdeps/powerpc/bits/hwcap.h (PPC_FEATURE2_HTM_NO_SUSPEND): New
diff --git a/NEWS b/NEWS
index e7b62a8d46..359465ff3e 100644
--- a/NEWS
+++ b/NEWS
@@ -7,6 +7,16 @@ using `glibc' in the "product" field.
 
 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:
 
   CVE-2009-5064: The ldd script would sometimes run the program under
diff --git a/malloc/malloc.c b/malloc/malloc.c
index dd9f699d97..c91fc099a7 100644
--- a/malloc/malloc.c
+++ b/malloc/malloc.c
@@ -1019,7 +1019,8 @@ static void*  _int_realloc(mstate, mchunkptr, INTERNAL_SIZE_T,
 static void*  _int_memalign(mstate, size_t, size_t);
 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 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)
     set_arena_corrupt (ar_ptr);
 
-  if ((action & 5) == 5)
-    __libc_message ((action & 2) ? (do_abort | do_backtrace) : do_message,
-		    "%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 ();
+  __libc_message (do_abort, "%s\n", str);
+  __builtin_unreachable ();
 }
 
 /* We need a wrapper function for one of the additions of POSIX.  */
diff --git a/manual/memory.texi b/manual/memory.texi
index 82f473806c..13cce7a750 100644
--- a/manual/memory.texi
+++ b/manual/memory.texi
@@ -1309,17 +1309,15 @@ The block was already freed.
 
 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
-variable @code{MALLOC_CHECK_}.  When @code{MALLOC_CHECK_} is set, a
-special (less efficient) implementation is used which is designed to be
-tolerant against simple errors, such as double calls of @code{free} with
-the same argument, or overruns of a single byte (off-by-one bugs).  Not
-all such errors can be protected against, however, and memory leaks can
-result.  If @code{MALLOC_CHECK_} is set to @code{0}, any detected heap
-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
-immediately.  This can be useful because otherwise a crash may happen
-much later, and the true cause for the problem is then very hard to
-track down.
+variable @code{MALLOC_CHECK_}.  When @code{MALLOC_CHECK_} is set to a
+non-zero value, a special (less efficient) implementation is used which
+is designed to be tolerant against simple errors, such as double calls
+of @code{free} with the same argument, or overruns of a single byte
+(off-by-one bugs).  Not all such errors can be protected against,
+however, and memory leaks can result.
+
+Any detected heap corruption results in immediate termination of the
+process.
 
 There is one problem with @code{MALLOC_CHECK_}: in SUID or SGID binaries
 it could possibly be exploited since diverging from the normal programs
diff --git a/manual/tunables.texi b/manual/tunables.texi
index 3c19567a28..b09e3fe791 100644
--- a/manual/tunables.texi
+++ b/manual/tunables.texi
@@ -71,27 +71,13 @@ following tunables in the @code{malloc} namespace:
 This tunable supersedes the @env{MALLOC_CHECK_} environment variable and is
 identical in features.
 
-Setting this tunable enables a special (less efficient) memory allocator for
-the malloc family of functions that is designed to be tolerant against simple
-errors such as double calls of free with the same argument, or overruns of a
-single byte (off-by-one bugs). Not all such errors can be protected against,
-however, and memory leaks can result.  The following list describes the values
-that this tunable can take and the effect they have on malloc functionality:
-
-@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
+Setting this tunable to a non-zero value enables a special (less
+efficient) memory allocator for the malloc family of functions that is
+designed to be tolerant against simple errors such as double calls of
+free with the same argument, or overruns of a single byte (off-by-one
+bugs). Not all such errors can be protected against, however, and memory
+leaks can result.  Any detected heap corruption results in immediate
+termination of the process.
 
 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