libc crash
H . J . Lu
hjl@valinux.com
Wed Dec 27 17:40:00 GMT 2000
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
More information about the Libc-alpha
mailing list