This is the mail archive of the
libc-alpha@sources.redhat.com
mailing list for the glibc project.
Re: libc crash
- To: Sparky Markowitz <amarkowitz at inprise dot com>
- Subject: Re: libc crash
- From: "H . J . Lu" <hjl at valinux dot com>
- Date: Wed, 27 Dec 2000 17:40:22 -0800
- Cc: libc-alpha at sources dot redhat dot com
- References: <3A4A64C0.C21C3379@inprise.com>
On Wed, Dec 27, 2000 at 01:53:04PM -0800, Sparky Markowitz wrote:
> Hello,
> I've run across what appears to be a fairly evil bug in libc when
> working with shared objects. I have attached a very simplified example
> which causes libc to segfault in dlopen(). To see the problem, bunzip2
> and untar the attachment and run make. Once it finishes building, run
> ./libcbug. Make sure that the built modules can be found on
> LD_LIBRARY_PATH.
>
I can see the problem. There are 2 kinds of errors the dynamic linker
has to deal with:
1. Fatal error. The dynamic linker reports it and aborts.
2. Non-fatal error. The dynamic linker reports it and cleans it up.
Unfortunately, the dynamic linker doesn't work very well with the #2
case. The relevant code in elf/dl-open.c is
/* Remove the object from memory. It may be in an inconsistent
state if relocation failed, for example. */
if (args.map)
_dl_close (args.map);
The problem is _dl_close is not prepared to deal with the inconsistent
state. It leads to many problems from, memory leak to core dump. I
don't know what the best fix. I think the best way to deal with it is
to make sure the state of a DSO is always consistent. We can provide
each _dl_map_object/_dl_map_object_fd call with a cleanup function. But
I am afraid it is easier said than be done.
BTW, I am enclosing a patch to fix "objname" on error. It is similar to
http://sources.redhat.com/ml/libc-alpha/2000-12/msg00171.html
H.J.
----
2000-12-27 H.J. Lu <hjl@gnu.org>
* elf/dl-open.c (_dl_open): Fix "objname" on error.
Index: elf/dl-open.c
===================================================================
RCS file: /work/cvs/gnu/glibc/elf/dl-open.c,v
retrieving revision 1.1.1.11
diff -u -p -r1.1.1.11 dl-open.c
--- elf/dl-open.c 2000/12/09 02:18:50 1.1.1.11
+++ elf/dl-open.c 2000/12/28 01:21:52
@@ -403,9 +403,9 @@ _dl_open (const char *file, int mode, co
len_errstring = strlen (errstring) + 1;
if (objname == errstring + len_errstring)
{
- len_errstring += strlen (objname) + 1;
- local_errstring = alloca (len_errstring);
- memcpy (local_errstring, errstring, len_errstring);
+ size_t len_total = len_errstring + strlen (objname) + 1;
+ local_errstring = alloca (len_total);
+ memcpy (local_errstring, errstring, len_total);
objname = local_errstring + len_errstring;
}
else