Bug 12575 - dlopen RTLD_NOW does not apply to GNU-IFUNCs
Summary: dlopen RTLD_NOW does not apply to GNU-IFUNCs
Status: RESOLVED WORKSFORME
Alias: None
Product: glibc
Classification: Unclassified
Component: libc (show other bugs)
Version: unspecified
: P2 normal
Target Milestone: ---
Assignee: Ulrich Drepper
URL:
Keywords:
Depends on:
Blocks: 2328
  Show dependency treegraph
 
Reported: 2011-03-13 10:15 UTC by Jan Kratochvil
Modified: 2014-06-27 13:45 UTC (History)
0 users

See Also:
Host: x86_64-fedora15-linux-gnu
Target: x86_64-fedora15-linux-gnu
Build:
Last reconfirmed:
fweimer: security-


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Jan Kratochvil 2011-03-13 10:15:43 UTC
`-Wl,-z,now' works and the GNU-IFUNC resolver is called before `main'.

But RTLD_NOW returns handle and GNU-IFUNC gets called only after `dlsym'.
Even if the executable calling dlopen(, RTLD_NOW) uses -Wl,-z,-now.

The first part of the test below is correct:
+ ./mc
f
main

But this part prints:
+ ./mcd
dlsym
f

while I expect:
+ ./mcd
f
dlsym

This behavior determines how the glibc Bug 2328 should be resolved in GDB.


cat >lc.c <<EOH
#include <stdio.h>
static int
fi (int a)
{
  return a + 1;
}
asm (".type f, @gnu_indirect_function");
int (*
f (void)) (int a)
{
  puts ("f");
  return fi;
}
EOH
cat >mc.c <<EOH
#include <stdio.h>
extern int f (int a);
int
main (void)
{
  puts ("main");
  return f (-1);
}
EOH
cat >mcd.c <<EOH
#include <stdio.h>
#include <dlfcn.h>
int
main (void)
{
  void *h = dlopen ("./lc.so", RTLD_NOW);
  puts ("dlsym");
  int (*fp) (int a) = (int (*) (int a)) dlsym (h, "f");
  return fp (-1);
}
EOH
gcc -o lc.so lc.c -Wall -g -shared -fPIC; gcc -o mc mc.c -Wall -g -Wl,-z,now ./lc.so; gcc -o mcd mcd.c -Wall -g -Wl,-z,now -ldl; (set -x; ./mc; ./mcd)
Comment 1 Jan Kratochvil 2011-03-13 10:16:28 UTC
Tested on Fedora 15:
glibc-2.13.90-6.i686
glibc-2.13.90-6.x86_64
Comment 2 Ulrich Drepper 2011-05-12 03:09:03 UTC
There is nothing to change in the dynamic linker.

When you dynamically load the DSO this doesn't magically make a relocation appear.  In your test, the symbol f doesn't have any relocation attached to it and this is correct.  This is really the expected behavior.  Without a relocation or returning the symbol address (as in dlsym) there is no place to store the result of the ifunc function call.
Comment 3 Jan Kratochvil 2011-06-02 13:13:06 UTC
I agree now, there is no <f@plt> stub anywhere in the dlopen case, thanks.