Harden powerpc64 elf_machine_fixup_plt
Alan Modra
amodra@gmail.com
Mon Mar 23 03:35:00 GMT 2015
On Fri, Mar 20, 2015 at 06:02:56PM -0400, Mike Frysinger wrote:
> On 20 Mar 2015 08:58, H.J. Lu wrote:
> > On Fri, Mar 20, 2015 at 8:51 AM, Carlos O'Donell wrote:
> > > Unfortunately no core developer wants to step up and fix this, and
> > > thus it remains a poorly understood and difficult to use feature.
The solutions I see are
1) Run two passes over dynamic relocations. Who wants to be
responsible for slowing down app startup?
2) Like (1) but on the first pass put ifunc relocations on a worklist.
3) Recursive dynamic relocation. ie. before running an ifunc
resolver, check that it has been relocated, and if not, resolve its
shared library. Probably not feasible due to loops in reloc
dependencies.
4) Accept that you may need to write ifunc resolvers in assembly.
They cannot use the GOT unless there is an ironclad guarantee that
they won't be called before they themselves are relocated.
> > IFUNC is processor specific. I have some old docs for x86 IFUNC:
>
> the relocs might be, but that doesn't mean the overall process/ABI contract is.
> it's crazy that the same C code might work/not work depending on the CPU/C lib.
The really bad news is that it is trivial to construct a testcase that
shows current C ifunc resolvers, even in libc.so, won't work on
targets that must use the GOT to return the address of a function.
cat > hello.c <<EOF
#include <stdio.h>
extern int world (int) __attribute__ ((weak));
void
print (const char *str)
{
puts (str);
}
int
main ()
{
print ("Hello");
if (world)
return world (1);
return 0;
}
EOF
cat > world.c <<EOF
extern void print (const char *);
int
world (int x)
{
print ("world");
return x;
}
EOF
gcc -o world.so -fPIC -shared -nostdlib world.c
gcc -o hello -Wl,-no-as-needed,-rpath,. hello.c -lc world.so
LD_DEBUG=reloc ./hello 2>&1 | grep relocation
The debug output will show world.so being relocated first, before
libc.so. So if world.so happened to take the address of a libc.so
ifunc, or call a libc.so ifunc with LD_BIND_NOW=1, then the libc.so
ifunc resolver would be called *before libc.so has been relocated*.
Now the only thing I did a little unusual was to link "world.so" with
-nostdlib. I also specified library order when linking "hello" in an
evil way that I happen to know will cause a problem. Users can easily
do that by accident..
When you start looking at a current libm.so and libpthread.so, you'll
see ifunc again, and the chance of users getting the wrong dynamic
relocation order increases.
--
Alan Modra
Australia Development Lab, IBM
More information about the Libc-alpha
mailing list