This is the mail archive of the glibc-bugs@sourceware.org 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]
Other format: [Raw text]

[Bug dynamic-link/14612] New: Bogus input causes ld --verify to segfault


http://sourceware.org/bugzilla/show_bug.cgi?id=14612

             Bug #: 14612
           Summary: Bogus input causes ld --verify to segfault
           Product: glibc
           Version: 2.17
            Status: NEW
          Severity: normal
          Priority: P2
         Component: dynamic-link
        AssignedTo: unassigned@sourceware.org
        ReportedBy: law@redhat.com
    Classification: Unclassified


Given an i686 executable with the following program headers:

Program Headers:
  Type           Offset   VirtAddr   PhysAddr   FileSiz MemSiz  Flg Align
  PHDR           0x000034 0x08050034 0x00000000 0x000c0 0x000c0 R E 0
  INTERP         0x0000f4 0x00000000 0x00000000 0x00011 0x00000 R   0
      [Requesting program interpreter: /usr/lib/ld.so.1]
  LOAD           0x000000 0x08050000 0x00000000 0x0d0b8 0x0d0b8 R E 0x10000
  LOAD           0x00d0b8 0x0806d0b8 0x00000000 0x01d97 0x0259c RWE 0x10000
  DYNAMIC        0x00d214 0x0806d214 0x00000000 0x000f8 0x00000 RWE 0
  NOTE           0x00ee4f 0x00000000 0x00000000 0x000c8 0x00000     0

Running ld.so --verify on that executable will cause a segafult in strcmp as we
pass a NULL pointer as one of the arguments.

If we look at the PT_INTERP code we have:

     case PT_INTERP:
        /* This "interpreter segment" was used by the program loader to
           find the program interpreter, which is this program itself, the
           dynamic linker.  We note what name finds us, so that a future
           dlopen call or DT_NEEDED entry, for something that wants to link
           against the dynamic linker as a shared library, will know that
           the shared object is already loaded.  */
        _dl_rtld_libname.name = ((const char *) main_map->l_addr
                                 + ph->p_vaddr);
        /* _dl_rtld_libname.next = NULL;        Already zero.  */
        GL(dl_rtld_map).l_libname = &_dl_rtld_libname;
        [ ... ]
        has_interp = true;


main_map->l_addr and ph->p_vaddr will both be zero.  Thus _dl_rtld_libname.name
will be zero. _dl_rtld_libname gets copied into GL(dl_rtld_map).l_libname.

Then slightly later we have this:

  /* If the current libname is different from the SONAME, add the
     latter as well.  */
  if (GL(dl_rtld_map).l_info[DT_SONAME] != NULL
      && strcmp (GL(dl_rtld_map).l_libname->name,
                 (const char *) D_PTR (&GL(dl_rtld_map), l_info[DT_STRTAB])
                 + GL(dl_rtld_map).l_info[DT_SONAME]->d_un.d_val) != 0)


Note now we pass GL(dl_rtld_map).l_libname->name to strcmp.  That value is NULL
resulting in the segfault.



So the question in my mind is how far do we go to avoid faulting on bogus
input?  It's easy enough to check for NULL, but a bogus PT_INTERP could cause a
fault by pointing to any unmapped memory region.

Assuming we can settle that question, we also need to avoid setting
"has_interp" to true when the PT_INTERP is bogus.  Otherwise we'll think we got
a valid interpreter and won't flag the executable/DSO has bogus in this code:

  if (__builtin_expect (mode, normal) == verify)
    {
      /* We were called just to verify that this is a dynamic
         executable using us as the program interpreter.  Exit with an
         error if we were not able to load the binary or no interpreter
         is specified (i.e., this is no dynamically linked binary.  */
      if (main_map->l_ld == NULL)
        _exit (1);

      /* We allow here some platform specific code.  */
#ifdef DISTINGUISH_LIB_VERSIONS
      DISTINGUISH_LIB_VERSIONS;
#endif
      _exit (has_interp ? 0 : 2);
    }

-- 
Configure bugmail: http://sourceware.org/bugzilla/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
You are on the CC list for the bug.


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