This is the mail archive of the
libc-help@sourceware.org
mailing list for the glibc project.
Function calls in my ifunc resolver crash due to unitialized PLT entries.
- From: nisse at lysator dot liu dot se (Niels MÃller)
- To: libc-help at sourceware dot org
- Cc: Mark H Weaver <mhw at netris dot org>
- Date: Mon, 22 Jun 2015 09:22:01 +0200
- Subject: Function calls in my ifunc resolver crash due to unitialized PLT entries.
- Authentication-results: sourceware.org; auth=none
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.