This is the mail archive of the libc-hacker@sourceware.cygnus.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]

Re: DL patch for glibc 2.0.7 and 2.1


> 
> > Hi,
> > 
> > While working on the DL bug, I found some bogus codes in dl-close.c
> > in both glibc 2.0.7 and 2.1. The code below is supposed to remove
> > a shared object if it is on the global scope list.
> > 
> >           if (imap->l_global)
> >             {
> >               /* This object is in the global scope list.  Remove it.  */       
> >               struct link_map **tail = _dl_global_scope_end;
> >               do                                                    
> >                 --tail; 
> >               while (*tail != imap);
> >               while (tail < _dl_global_scope_end)
> >                 {                                        
> >                   tail[0] = tail[1];
> >                   ++tail;
> >                 }                
> >               --_dl_global_scope_end;
> >             }
> > 
> > The problem is if we call dlopen () from a statically linked executable,
> > the shared object being loaded is always put on the global scope list
> > no matter what you do. Now when you call dlclose () on it, it is removed
> > from memory, but it is still on the global scope list if imap->l_global
> > is false. Now we get a problem. It gets even worse when we have
> > multiple calls to dlopen/dlclose at random order from a statically
> > linked executable. We should fix it for bothe 2.0.7 and 2.1.
> > 
> > 
> 
> This is the patch I came up with. The real bug is in dl-open.c. Once
> it is put on the global scope list. You have to keep it in memory by
> incrementing the open count. My patch corrects the open count. It
> should be applied to both 2.0.7 and 2.1.
> 
> One problem with dl-open.c is that the new shared object is put on the
> global scope list without even being asked to do so when dlopen () is
> called from the static binary. 
> 
> BTW, a test case is easy to create. I will provide several if necessary.
> 
> Thanks.
> 
> 
> -- 
> H.J. Lu (hjl@gnu.org)
> ----
> Fri May  1 00:07:08 1998  H.J. Lu  <hjl@gnu.org>
> 
> 	* elf/dl-open.c (_dl_open): Increment the open count if it is
> 	put on the global scope list.
> 
> Index: dl-open.c
> ===================================================================
> RCS file: /home/work/cvs/gnu/glibc/elf/dl-open.c,v
> retrieving revision 1.1.1.9
> diff -u -r1.1.1.9 dl-open.c
> --- dl-open.c	1998/04/04 16:27:09	1.1.1.9
> +++ dl-open.c	1998/05/01 06:59:36
> @@ -163,6 +163,11 @@
>  	}
>      }
>  
> +  if (new->l_global || _dl_loaded == new)
> +    /* We are put on the global scope list, one way or the other. We
> +       have to live with it. Increment the open count. */
> +    new->l_opencount++;
> +
>  
>    /* Notify the debugger we have added some objects.  We need to call
>       _dl_debug_initialize in a static program in case dynamic linking has
> 

Here is a revised patch such that

	handle = dlopen ("./libfoo.so", RTLD_GLOBAL);
	...
	dlclose (handle);

will have a chance to really remove ./libfoo.so from memory if it can
be safe to do so.


-- 
H.J. Lu (hjl@gnu.org)
-----
Fri May  1 08:47:01 1998  H.J. Lu  <hjl@gnu.org>

	* elf/dl-open.c (_dl_open): Increment the open count if it is
	put at the first place on the global scope list.

Index: dl-open.c
===================================================================
RCS file: /home/work/cvs/gnu/glibc-2.0/elf/dl-open.c,v
retrieving revision 1.1.1.5
diff -u -r1.1.1.5 dl-open.c
--- dl-open.c	1998/03/31 16:18:44	1.1.1.5
+++ dl-open.c	1998/05/01 15:44:11
@@ -142,6 +142,12 @@
 	}
     }
 
+  if (_dl_loaded == new)
+    /* We are put at the first place on the global scope list, one way
+       or the other. We may be used by other shared objects. We have to
+       make sure that it stays in memory for them. Increment the open
+       count. */
+    new->l_opencount++;
 
   /* Notify the debugger we have added some objects.  We need to call
      _dl_debug_initialize in a static program in case dynamic linking has


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