[GHC] #8935: Obscure linker bug leads to crash in GHCi

GHC ghc-devs at haskell.org
Wed May 7 18:57:31 UTC 2014


#8935: Obscure linker bug leads to crash in GHCi
-------------------------------------+------------------------------------
        Reporter:  simonmar          |            Owner:  simonmar
            Type:  bug               |           Status:  patch
        Priority:  high              |        Milestone:  7.8.3
       Component:  Runtime System    |          Version:  7.8.1-rc2
      Resolution:                    |         Keywords:
Operating System:  Unknown/Multiple  |     Architecture:  Unknown/Multiple
 Type of failure:  GHCi crash        |       Difficulty:  Rocket Science
       Test Case:                    |       Blocked By:
        Blocking:                    |  Related Tickets:
-------------------------------------+------------------------------------

Comment (by dagit):

 After playing with your example a bit I see what you mean about the copy
 semantics.  I found this article:
 http://netwinder.osuosl.org/users/p/patb/public_html/elf_relocs.html

 Interestingly, [http://src.gnu-darwin.org/src/libexec/rtld-
 elf/amd64/reloc.c.html glibc] has these comments:

 {{{
 /*
  * Process the special R_X86_64_COPY relocations in the main program.
 These
  * copy data from a shared object into a region in the main program's BSS
  * segment.
  *
  * Returns 0 on success, -1 on failure.
  */
 int
 do_copy_relocations(Obj_Entry *dstobj)
 }}}

 And:
 {{{
 case R_X86_64_COPY:
                 /*
                  * These are deferred until all other relocations have
                  * been done.  All we do here is make sure that the COPY
                  * relocation is not in a shared library.  They are
 allowed
                  * only in executable files.
                  */
 }}}

 The elf interpreter delays processing of the `R_COPY`'s so that it gets
 the correct behavior. I think this supports your earlier hypothesis.

 At this point, I noticed that I can switch `environ` in the executable
 between `R_X86_64_GLOB_DAT` and `R_X86_64_COPY` by adding `-fPIC` (you
 probably already knew that). Specifically, without `-fPIC` I get copy and
 with it I get glob dat.

 Test program again:
 {{{
 #define _GNU_SOURCE
 #include <dlfcn.h>
 #include <stdio.h>
 #include <stdlib.h>

 extern char**environ;

 char envname[]  = "environ";

 void dlsym_check(void *handle, char * lib, char * sym){
     void * e = dlsym(handle,sym);
     fprintf(stderr, "dlsym(\"%s\", \"%s\") = %p\n", lib, sym, e);
     char * error = dlerror();
     if( error != NULL )
     fprintf(stderr, "Errors: %s\n", error);
 }

 int main(int argc, char *argv[])
 {
   if( argc < 2 ){
     printf("usage: ./check-environ <path to shared object>\n");
     exit(1);
   }
   char* so  = argv[1];
   void *deflt, *hdl;

   fprintf(stderr, "environ = %p\n", &environ);

   deflt = dlopen(NULL, RTLD_LAZY | RTLD_GLOBAL);
   fprintf(stderr, "\nFind a symbol after passing NULL to dlopen:\n");
   dlsym_check(deflt, NULL, envname);
   hdl = dlopen(so, RTLD_LAZY | RTLD_GLOBAL);
   if( hdl == NULL ){
     fprintf(stderr, "Error: %s", dlerror());
     exit(1);
   }

   fprintf(stderr, "\nFind a symbol that is located here and libc (handle
 comes from dlopen on %s)\n", so);
   dlsym_check(hdl,          so, envname);
 }
 }}}

 {{{
 $ ./check-environ-without-pic /usr/lib64/libgmp.so.10
 environ = 0x601070

 Find a symbol after passing NULL to dlopen:
 dlsym("(null)", "environ") = 0x601070

 Find a symbol that is located here and libc (handle comes from dlopen on
 /usr/lib64/libgmp.so.10)
 dlsym("/usr/lib64/libgmp.so.10", "environ") = 0x31e45bd508

 $ ./check-environ-with-pic /usr/lib64/libgmp.so.10
 environ = 0x31e45bd508

 Find a symbol after passing NULL to dlopen:
 dlsym("(null)", "environ") = 0x31e45bd508

 Find a symbol that is located here and libc (handle comes from dlopen on
 /usr/lib64/libgmp.so.10)
 dlsym("/usr/lib64/libgmp.so.10", "environ") = 0x31e45bd508
 }}}

--
Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/8935#comment:39>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler


More information about the ghc-tickets mailing list