This is the mail archive of the libc-alpha@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[RFC][PATCH] Avoid mempcpy/ifunc in __libc_message


Hi,

 I have been investigating an elf/ifuncmain5picstatic test case failure:

unexpected reloc type in static binarySegmentation fault

-- the immediate cause is I believe a bug in binutils that makes an empty 
(R_*_NONE) reloc to appear in the static binary, however what's concerned 
me is the segmentation fault that follows.  I don't think our code should 
ever crash even if supplied with unexpected/wrong data.

 I have tracked down the cause to be a call to mempcpy made in 
__libc_message -- mempcpy calls memcpy on this target and that happens to 
be an ifunc (as one of the usual suspects).  As the `reloc type' failure 
happens in ifunc processing the pointer to memcpy directs control to the 
ifunc resolver that would be used in the dynamic case rather than a memcpy 
implementation and the final address of the memcpy variant chosen is 
returned rather than the value of the `to' pointer (and memcpy executed).  
As a result further code in __libc_message that uses the pointer returned 
tries to poke at the read-only text segment and crashes.

 I have tried to address it with the change below that replaces the call 
to mempcpy with an equivalent handcoded sequence (I don't think 
performance is critical here), however that does not save the program from 
crashing later on, in raise (SIGABRT) that wants to access the TLS, that 
hasn't been initialised at that stage yet.  I see no immediate solution to 
this problem and will appreciate ideas.

 What can we do to avoid accessing bits that haven't been initialised this 
early on this failure path?  I think it's important that the failure path 
is robust so as to be usable for diagnostics, which means error reporting 
and process termination should not rely on anything that requires run-time 
initialisation.  Even the removal of this particular call to mempcpy I 
find fragile as there isn't really anything that could guarantee none of 
the other calls that occur in the failure path are not ifuncs on any 
target.

 Any thoughts?

2013-09-25  Maciej W. Rozycki  <macro@codesourcery.com>

	* sysdeps/posix/libc_fatal.c (__libc_message): Avoid a call to
	mempcpy.

  Maciej

glibc-libc-message-noifunc.diff
Index: glibc-fsf-trunk-quilt/sysdeps/posix/libc_fatal.c
===================================================================
--- glibc-fsf-trunk-quilt.orig/sysdeps/posix/libc_fatal.c	2013-04-19 23:05:52.467439498 +0100
+++ glibc-fsf-trunk-quilt/sysdeps/posix/libc_fatal.c	2013-09-25 15:35:36.927953246 +0100
@@ -151,8 +151,11 @@ __libc_message (int do_abort, const char
 	    {
 	      buf->size = total;
 	      char *wp = buf->msg;
+	      const char *rp;
+	      size_t i;
 	      for (int cnt = 0; cnt < nlist; ++cnt)
-		wp = mempcpy (wp, iov[cnt].iov_base, iov[cnt].iov_len);
+		for (i = iov[cnt].iov_len, rp = iov[cnt].iov_base; i--; )
+		  *wp++ = *rp++;
 	      *wp = '\0';
 
 	      /* We have to free the old buffer since the application might


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]