12d24f1120
Signed-off-by: Jürgen Buchmüller <pullmoll@t-online.de>
206 lines
6.7 KiB
Diff
206 lines
6.7 KiB
Diff
From dcd2b97dd1d695445d45beb4daa815cfe06691dd Mon Sep 17 00:00:00 2001
|
|
From: Carlos O'Donell <carlos@redhat.com>
|
|
Date: Mon, 15 Apr 2019 20:49:32 +0200
|
|
Subject: [PATCH 13] malloc: Set and reset all hooks for tracing (Bug 16573)
|
|
|
|
If an error occurs during the tracing operation, particularly during a
|
|
call to lock_and_info() which calls _dl_addr, we may end up calling back
|
|
into the malloc-subsystem and relock the loader lock and deadlock. For
|
|
all intents and purposes the call to _dl_addr can call any of the malloc
|
|
family API functions and so we should disable all tracing before calling
|
|
such loader functions. This is similar to the strategy that the new
|
|
malloc tracer takes when calling the real malloc, namely that all
|
|
tracing ceases at the boundary to the real function and any faults at
|
|
that point are the purvue of the library (though the new tracer does
|
|
this on a per-thread basis in an MT-safe fashion). Since the new tracer
|
|
and the hook deprecation are not yet complete we must fix these issues
|
|
where we can.
|
|
|
|
Tested on x86_64 with no regressions.
|
|
|
|
Co-authored-by: Kwok Cheung Yeung <kcy@codesourcery.com>
|
|
Reviewed-by: DJ Delorie <dj@redhat.com>
|
|
(cherry picked from commit e621246ec6393ea08ae50310f9d5e72500f8c9bc)
|
|
---
|
|
ChangeLog | 15 +++++++++++
|
|
NEWS | 1 +
|
|
malloc/mtrace.c | 72 +++++++++++++++++++++++++++++++------------------
|
|
3 files changed, 62 insertions(+), 26 deletions(-)
|
|
|
|
diff --git a/ChangeLog b/ChangeLog
|
|
index 3b5d24cf67..077d0dae29 100644
|
|
--- a/ChangeLog
|
|
+++ b/ChangeLog
|
|
@@ -1,3 +1,18 @@
|
|
+2019-04-09 Carlos O'Donell <carlos@redhat.com>
|
|
+ Kwok Cheung Yeung <kcy@codesourcery.com>
|
|
+
|
|
+ [BZ #16573]
|
|
+ * malloc/mtrace.c: Define prototypes for all hooks.
|
|
+ (set_default_hooks): New function.
|
|
+ (set_trace_hooks): Likewise.
|
|
+ (save_default_hooks): Likewise.
|
|
+ (tr_freehook): Use new s*_hooks functions.
|
|
+ (tr_mallochook): Likewise.
|
|
+ (tr_reallochook): Likewise.
|
|
+ (tr_memalignhook): Likewise.
|
|
+ (mtrace): Likewise.
|
|
+ (muntrace): Likewise.
|
|
+
|
|
2019-04-02 TAMUKI Shoichi <tamuki@linet.gr.jp>
|
|
|
|
[BZ #22964]
|
|
diff --git a/NEWS b/NEWS
|
|
index 703864ac75..117646df7b 100644
|
|
--- a/NEWS
|
|
+++ b/NEWS
|
|
@@ -13,6 +13,7 @@ Major new features:
|
|
|
|
The following bugs are resolved with this release:
|
|
|
|
+ [16573] malloc: Set and reset all hooks for tracing
|
|
[24155] x32 memcmp can treat positive length as 0 (if sign bit in RDX is set) (CVE-2019-7309)
|
|
[24164] Systemtap probes need to use "nr" constraint on 32-bit Arm
|
|
[24161] __run_fork_handlers self-deadlocks in malloc/tst-mallocfork2
|
|
diff --git a/malloc/mtrace.c b/malloc/mtrace.c
|
|
index a2facf65ea..2fda262508 100644
|
|
--- a/malloc/mtrace.c
|
|
+++ b/malloc/mtrace.c
|
|
@@ -121,6 +121,41 @@ lock_and_info (const void *caller, Dl_info *mem)
|
|
return res;
|
|
}
|
|
|
|
+static void tr_freehook (void *, const void *);
|
|
+static void * tr_mallochook (size_t, const void *);
|
|
+static void * tr_reallochook (void *, size_t, const void *);
|
|
+static void * tr_memalignhook (size_t, size_t, const void *);
|
|
+
|
|
+/* Set all the default non-trace hooks. */
|
|
+static __always_inline void
|
|
+set_default_hooks (void)
|
|
+{
|
|
+ __free_hook = tr_old_free_hook;
|
|
+ __malloc_hook = tr_old_malloc_hook;
|
|
+ __realloc_hook = tr_old_realloc_hook;
|
|
+ __memalign_hook = tr_old_memalign_hook;
|
|
+}
|
|
+
|
|
+/* Set all of the tracing hooks used for mtrace. */
|
|
+static __always_inline void
|
|
+set_trace_hooks (void)
|
|
+{
|
|
+ __free_hook = tr_freehook;
|
|
+ __malloc_hook = tr_mallochook;
|
|
+ __realloc_hook = tr_reallochook;
|
|
+ __memalign_hook = tr_memalignhook;
|
|
+}
|
|
+
|
|
+/* Save the current set of hooks as the default hooks. */
|
|
+static __always_inline void
|
|
+save_default_hooks (void)
|
|
+{
|
|
+ tr_old_free_hook = __free_hook;
|
|
+ tr_old_malloc_hook = __malloc_hook;
|
|
+ tr_old_realloc_hook = __realloc_hook;
|
|
+ tr_old_memalign_hook = __memalign_hook;
|
|
+}
|
|
+
|
|
static void
|
|
tr_freehook (void *ptr, const void *caller)
|
|
{
|
|
@@ -138,12 +173,12 @@ tr_freehook (void *ptr, const void *caller)
|
|
tr_break ();
|
|
__libc_lock_lock (lock);
|
|
}
|
|
- __free_hook = tr_old_free_hook;
|
|
+ set_default_hooks ();
|
|
if (tr_old_free_hook != NULL)
|
|
(*tr_old_free_hook)(ptr, caller);
|
|
else
|
|
free (ptr);
|
|
- __free_hook = tr_freehook;
|
|
+ set_trace_hooks ();
|
|
__libc_lock_unlock (lock);
|
|
}
|
|
|
|
@@ -155,12 +190,12 @@ tr_mallochook (size_t size, const void *caller)
|
|
Dl_info mem;
|
|
Dl_info *info = lock_and_info (caller, &mem);
|
|
|
|
- __malloc_hook = tr_old_malloc_hook;
|
|
+ set_default_hooks ();
|
|
if (tr_old_malloc_hook != NULL)
|
|
hdr = (void *) (*tr_old_malloc_hook)(size, caller);
|
|
else
|
|
hdr = (void *) malloc (size);
|
|
- __malloc_hook = tr_mallochook;
|
|
+ set_trace_hooks ();
|
|
|
|
tr_where (caller, info);
|
|
/* We could be printing a NULL here; that's OK. */
|
|
@@ -185,16 +220,12 @@ tr_reallochook (void *ptr, size_t size, const void *caller)
|
|
Dl_info mem;
|
|
Dl_info *info = lock_and_info (caller, &mem);
|
|
|
|
- __free_hook = tr_old_free_hook;
|
|
- __malloc_hook = tr_old_malloc_hook;
|
|
- __realloc_hook = tr_old_realloc_hook;
|
|
+ set_default_hooks ();
|
|
if (tr_old_realloc_hook != NULL)
|
|
hdr = (void *) (*tr_old_realloc_hook)(ptr, size, caller);
|
|
else
|
|
hdr = (void *) realloc (ptr, size);
|
|
- __free_hook = tr_freehook;
|
|
- __malloc_hook = tr_mallochook;
|
|
- __realloc_hook = tr_reallochook;
|
|
+ set_trace_hooks ();
|
|
|
|
tr_where (caller, info);
|
|
if (hdr == NULL)
|
|
@@ -230,14 +261,12 @@ tr_memalignhook (size_t alignment, size_t size, const void *caller)
|
|
Dl_info mem;
|
|
Dl_info *info = lock_and_info (caller, &mem);
|
|
|
|
- __memalign_hook = tr_old_memalign_hook;
|
|
- __malloc_hook = tr_old_malloc_hook;
|
|
+ set_default_hooks ();
|
|
if (tr_old_memalign_hook != NULL)
|
|
hdr = (void *) (*tr_old_memalign_hook)(alignment, size, caller);
|
|
else
|
|
hdr = (void *) memalign (alignment, size);
|
|
- __memalign_hook = tr_memalignhook;
|
|
- __malloc_hook = tr_mallochook;
|
|
+ set_trace_hooks ();
|
|
|
|
tr_where (caller, info);
|
|
/* We could be printing a NULL here; that's OK. */
|
|
@@ -305,14 +334,8 @@ mtrace (void)
|
|
malloc_trace_buffer = mtb;
|
|
setvbuf (mallstream, malloc_trace_buffer, _IOFBF, TRACE_BUFFER_SIZE);
|
|
fprintf (mallstream, "= Start\n");
|
|
- tr_old_free_hook = __free_hook;
|
|
- __free_hook = tr_freehook;
|
|
- tr_old_malloc_hook = __malloc_hook;
|
|
- __malloc_hook = tr_mallochook;
|
|
- tr_old_realloc_hook = __realloc_hook;
|
|
- __realloc_hook = tr_reallochook;
|
|
- tr_old_memalign_hook = __memalign_hook;
|
|
- __memalign_hook = tr_memalignhook;
|
|
+ save_default_hooks ();
|
|
+ set_trace_hooks ();
|
|
#ifdef _LIBC
|
|
if (!added_atexit_handler)
|
|
{
|
|
@@ -338,10 +361,7 @@ muntrace (void)
|
|
file. */
|
|
FILE *f = mallstream;
|
|
mallstream = NULL;
|
|
- __free_hook = tr_old_free_hook;
|
|
- __malloc_hook = tr_old_malloc_hook;
|
|
- __realloc_hook = tr_old_realloc_hook;
|
|
- __memalign_hook = tr_old_memalign_hook;
|
|
+ set_default_hooks ();
|
|
|
|
fprintf (f, "= End\n");
|
|
fclose (f);
|
|
|