This is the mail archive of the libc-alpha@sources.redhat.com 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]

A new patch for ld.so (Re: A ld.so bug)


On Fri, May 04, 2001 at 10:45:29PM -0700, H . J . Lu wrote:
> On Fri, May 04, 2001 at 04:36:30PM -0700, H . J . Lu wrote:
> > # gcc d.c -ldl -D_GNU_SOURCE
> > # a.out
> > zsh: 5484 segmentation fault  ./a.out
> > 
> > The problem is _dl_signal_error is called with (xxx, NULL, xxx) in
> > quite a few places. But _dl_signal_error does strlen (objname) without
> > checking if objname is NULL.
> > 
> > BTW, there is anther problem. I don't think _dlerror_run can use
> > calloc for error reporting. I got a testcase with
> > 
> 
> # cc -o d d.c -ldl
> # ./d
> zsh: 5238 segmentation fault  ./d
> 
> Here is a patch and a testcase.
> 
> 

My last patch has a bug. I think this one is ok.


H.J.
----
2001-05-04  H.J. Lu  <hjl@gnu.org>

	* elf/dl-error.c (catch): Add a new field, fatal.
	(_dl_signal_error): Check if objname is NULL and prepare for
	malloc failure.
	(_dl_catch_error): Copy the "fatal" field from the old catch to
	the new one.

--- libc/elf/dl-error.c.fatal	Tue Feb 27 22:22:09 2001
+++ libc/elf/dl-error.c	Fri May  4 22:26:59 2001
@@ -31,6 +31,7 @@ struct catch
   {
     const char *objname;	/* Object/File name.  */
     const char *errstring;	/* Error detail filled in here.  */
+    int fatal;			/* If any error is fatal.  */
     jmp_buf env;		/* longjmp here on error.  */
   };
 
@@ -71,29 +72,50 @@ _dl_signal_error (int errcode, const cha
     errstring = N_("DYNAMIC LINKER BUG!!!");
 
   lcatch = tsd_getspecific ();
-  if (lcatch != NULL)
+  if (lcatch != NULL && lcatch->fatal == 0)
     {
       /* We are inside _dl_catch_error.  Return to it.  We have to
 	 duplicate the error string since it might be allocated on the
 	 stack.  The object name is always a string constant.  */
-      size_t len_objname = strlen (objname) + 1;
-      size_t len_errstring = strlen (errstring) + 1;
+      size_t len_objname;
+      size_t len_errstring;
+      struct catch new_catch;
+      int result;
+
+      if (objname == NULL)
+	objname = _dl_argv[0] ?: "<main program>";
 
-      lcatch->errstring = (char *) malloc (len_objname + len_errstring);
-      if (lcatch->errstring != NULL)
-	/* Make a copy of the object file name and the error string.  */
-	lcatch->objname = memcpy (__mempcpy ((char *) lcatch->errstring,
-					     errstring, len_errstring),
-				  objname, len_objname);
-      else
+      len_objname = strlen (objname) + 1;
+      len_errstring = strlen (errstring) + 1;
+
+      /* We have to prepare for any possible errors. */
+      new_catch.fatal = 1;
+
+      result = setjmp (new_catch.env);
+      if (__builtin_expect (result, 0) == 0)
 	{
-	  /* This is better than nothing.  */
-	  lcatch->objname = "";
-	  lcatch->errstring = _dl_out_of_memory;
+	  tsd_setspecific (&new_catch);
+	  lcatch->errstring = (char *) malloc (len_objname
+					       + len_errstring);
+	  if (lcatch->errstring != NULL)
+	    /* Make a copy of the object file name and the error
+	       string.  */
+	    lcatch->objname = memcpy (__mempcpy ((char *) lcatch->errstring,
+						 errstring,
+						 len_errstring),
+				      objname, len_objname);
+	  else
+	    {
+	      /* This is better than nothing.  */
+	      lcatch->objname = "";
+	      lcatch->errstring = _dl_out_of_memory;
+	    }
+	  tsd_setspecific (lcatch);
+	  longjmp (lcatch->env, errcode ?: -1);
 	}
-      longjmp (lcatch->env, errcode ?: -1);
+      /* When we get here via longjmp, something must be worng.  */
+      tsd_setspecific (lcatch);
     }
-  else
     {
       /* Lossage while resolving the program's own symbols is always fatal.  */
       char buffer[1024];
@@ -143,6 +165,8 @@ _dl_catch_error (const char **objname, c
   c.errstring = NULL;
 
   old = tsd_getspecific ();
+  c.fatal = old ? old->fatal : 0;
+
   errcode = setjmp (c.env);
   if (__builtin_expect (errcode, 0) == 0)
     {


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