Mirror of the lttng-dev mailing list
 help / color / mirror / Atom feed
From: stefan_seefeld@mentor.com (Stefan Seefeld)
Subject: [lttng-dev] RFC: Fix crash in dlerror()
Date: Sat, 8 Feb 2014 11:53:44 -0500	[thread overview]
Message-ID: <52F66118.5010003@mentor.com> (raw)
In-Reply-To: <1380151240.21051.1391875592403.JavaMail.zimbra@efficios.com>

On 02/08/2014 11:06 AM, Mathieu Desnoyers wrote:
> 
> 
> ----- Original Message -----
>> From: "Stefan Seefeld" <stefan_seefeld@mentor.com>
>> To: lttng-dev at lists.lttng.org
>> Sent: Friday, February 7, 2014 4:50:09 PM
>> Subject: [lttng-dev] RFC: Fix crash in dlerror()
>>
>> I have been looking into an issue with the malloc wrapper, where an
>> unsuccessful call to dlopen(), followed by a call to dlerror(), would
>> result in a segmentation fault when the malloc wrapper is being used.
>>
>> The problem is the following:
>>
>> The functions dlopen() and dlsym() make use of a global (though
>> thread-local) "result" structure to hold the error state, to allow a
>> subsequent call to dlerror() to report it.
>>
>> As it turns out, dlerror() itself may implicitly call realloc(), which,
>> if it hasn't been used before, triggers our wrapper to call dlsym(). So,
>> while dlerror() inspects said result structure, dlsym() re-initializes
>> it, causing the crash...
>>
>> This is arguably a bug in the dlfcn functions. The attached patch
>> attempts to fix this by moving the initialization of the realloc()
>> wrapper (i.e., the loading of the symbol) into the constructor. This
>> fixes the crash that I'm observing, but since none of these dependencies
>> are specified or documented, this change may cause other issues elsewhere.
>>
>> Are there any objections to this approach ? If not, I'll submit a formal
>> patch for this.
> 
> The issue I see with the approach you propose is if dlsym() is used
> within another constructor (from anoter lib for instance). Given that
> the order of constructor execution should be assumed to be random, we can
> run into the same error scenario you describe here.

Yes, I was worried about the same. In general there really isn't
anything we can do short of submitting a patch to glibc, as the only way
to address this correctly is to record whether we are inside a dlerror()
call. So, anything I can think of is merely heuristic.

Here is a slightly different approach: We know that the calloc symbol is
looked up very early (see the trick we use with the temporary static
calloc function to avoid the infinite recursion), and we may safely
assume that the calloc lookup won't fail (if it does, the user has more
important things to worry about). Thus, right after the calloc lookup
completed seems a good time to force the realloc lookup.

That's what this follow-up patch does (which still works for my test).

How does that look ?

	Stefan

-- 
Stefan Seefeld
CodeSourcery / Mentor Graphics
http://www.mentor.com/embedded-software/
-------------- next part --------------
diff --git a/liblttng-ust-libc-wrapper/lttng-ust-malloc.c b/liblttng-ust-libc-wrapper/lttng-ust-malloc.c
index 33ed18b..8413f31 100644
--- a/liblttng-ust-libc-wrapper/lttng-ust-malloc.c
+++ b/liblttng-ust-libc-wrapper/lttng-ust-malloc.c
@@ -54,6 +54,8 @@ static void *static_calloc(size_t nmemb, size_t size)
 	return &static_calloc_buf[prev_offset];
 }
 
+static void *(*plibc_realloc)(void *ptr, size_t size);
+
 void *malloc(size_t size)
 {
 	static void *(*plibc_malloc)(size_t size);
@@ -111,6 +113,16 @@ void *calloc(size_t nmemb, size_t size)
 			fprintf(stderr, "callocwrap: unable to find calloc\n");
 			return NULL;
 		}
+		/*
+		 * Now seems a good time to also initialize the realloc symbol.
+		 * (Doing that just-in-time won't work as it would corrupt some
+		 * dlfcn-internal state.)
+		 */
+		plibc_realloc = dlsym(RTLD_NEXT, "realloc");
+		if (plibc_calloc == NULL) {
+			fprintf(stderr, "callocwrap: unable to find realloc\n");
+			return NULL;
+		}
 	}
 	retval = plibc_calloc(nmemb, size);
 	tracepoint(ust_libc, calloc, nmemb, size, retval);
@@ -119,7 +131,6 @@ void *calloc(size_t nmemb, size_t size)
 
 void *realloc(void *ptr, size_t size)
 {
-	static void *(*plibc_realloc)(void *ptr, size_t size);
 	void *retval;
 
 	if (plibc_realloc == NULL) {


  reply	other threads:[~2014-02-08 16:53 UTC|newest]

Thread overview: 28+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-02-07 21:50 Stefan Seefeld
2014-02-08 16:06 ` Mathieu Desnoyers
2014-02-08 16:53   ` Stefan Seefeld [this message]
2014-02-08 22:22     ` Mathieu Desnoyers
2014-02-09 16:28       ` Stefan Seefeld
2014-02-11  0:31         ` Mathieu Desnoyers
2014-02-11  0:53       ` Stefan Seefeld
2014-02-11 20:51         ` Mathieu Desnoyers
2014-02-11 20:55           ` Stefan Seefeld
2014-02-12  3:39             ` Mathieu Desnoyers
2014-02-12 14:35               ` Mathieu Desnoyers
2014-02-12 21:59                 ` Mathieu Desnoyers
     [not found] ` <52FCAA28.6020708@mentor.com>
     [not found]   ` <1026072798.24303.1392297452496.JavaMail.zimbra@efficios.com>
     [not found]     ` <52FCCCD2.9050302@mentor.com>
     [not found]       ` <610029715.24333.1392300717731.JavaMail.zimbra@efficios.com>
     [not found]         ` <1692042945.24342.1392301795996.JavaMail.zimbra@efficios.com>
     [not found]           ` <1119459836.24348.1392302831554.JavaMail.zimbra@efficios.com>
     [not found]             ` <52FCE732.9090508@mentor.com>
2014-02-13 16:40               ` Mathieu Desnoyers
2014-02-13 16:51                 ` Woegerer, Paul
2014-02-13 18:52                   ` Mathieu Desnoyers
2014-02-13 19:44                     ` Woegerer, Paul
2014-02-13 22:06                       ` Woegerer, Paul
2014-02-13 22:44                         ` Stefan Seefeld
2014-02-14  6:59                           ` Woegerer, Paul
2014-02-14 10:30                           ` Alexander Monakov
2014-02-14 11:35                             ` Woegerer, Paul
2014-02-14 11:54                             ` Woegerer, Paul
2014-02-14 13:45                             ` [lttng-dev] [PATCH] Force static_alloc setup to be written into memory Paul Woegerer
2014-02-14 14:08                               ` Mathieu Desnoyers
2014-02-14 14:23                               ` Alexander Monakov
2014-02-14 14:39                                 ` Woegerer, Paul
2014-02-14 14:46                                 ` Stefan Seefeld
2014-02-14 15:12                                 ` Mathieu Desnoyers

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=52F66118.5010003@mentor.com \
    --to=stefan_seefeld@mentor.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox