This is the mail archive of the libc-help@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]

Function calls in my ifunc resolver crash due to unitialized PLT entries.


Hi,

I've recently added "fat binary" support to GNU nettle, and one of the
mechanisms used are __attribute__ ((ifunc (resolver_function))). (The
code uses a belt-and-suspenders approach to be portable also to systems
lacking both ifunc and constructors).

On x86_64, the resolver functions all call a common initialization
function, fat_init, see
https://git.lysator.liu.se/nettle/nettle/blob/master/fat-x86_64.c

It calls a couple of non-static functions, like

      uint32_t cpuid_data[4];
      _nettle_cpuid (0, cpuid_data);
      if (memcmp (cpuid_data + 1, "Genu" "ntel" "ineI", 12) == 0)
	features->vendor = X86_INTEL;

Now, it's been reported that the following test program:

  #include <stdio.h>
  #include <stdlib.h>
  #include <dlfcn.h>
  
  int main (int argc, char *argv[])
  {
    void *handle;
    
    handle = dlopen ("libnettle.so", RTLD_NOW);
    if (!handle)
      {
        fprintf (stderr, "%s\n", dlerror ());
        exit (EXIT_FAILURE);
      }
    dlclose (handle);
    exit (EXIT_SUCCESS);
  }

crashes in fat_init. Apparently due to calls via PLT entries which
aren't yet initialized. First the call to _nettle_cpuinfo crashes (this
is a function in libnettle.so, implemented in a separate .asm file). And
when Mark tried to mark that function with visibility "hidden",
bypassing the PLT, the call to memcmp (the standard libc functiomn)
crashed instead. See discussion at
http://lists.lysator.liu.se/pipermail/nettle-bugs/2015/003389.html

I'm not sure exactly what an application can do inside a ifunc resolver,
but I'd expect to at least be able to call libc functions? I have other
libc calls, including secure_getenv and fprintf (mainly for debug
purposes).

In what order are PLT entries initialized with RTLD_NOW? If all
non-ifunc entries were done first, that would make things easier for the
ifunc resolver functions. Or if such ordering is hard to do, first
initialize all PLT entries in the same way as with RTLD_LAZY, so that
the first call to _nettle_cpuid or memcmp gets that symbol properly
resolved.

Are there any other ways to tweak the ordering? Can I call back into the
libc resolver from the my ifunc resolver to request that particular
symbols are resolved, before I go on and call them?

Regards,
/Niels

-- 
Niels MÃller. PGP-encrypted email is preferred. Keyid C0B98E26.
Internet email is subject to wholesale government surveillance.


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