This is the mail archive of the
libc-alpha@sourceware.org
mailing list for the glibc project.
Re: Incorrect IFUNC use in libpthread for fork, vfork wrapper [BZ #19861]
- From: Richard Henderson <rth at redhat dot com>
- To: Florian Weimer <fweimer at redhat dot com>, GNU C Library <libc-alpha at sourceware dot org>
- Date: Wed, 30 Mar 2016 09:47:39 -0700
- Subject: Re: Incorrect IFUNC use in libpthread for fork, vfork wrapper [BZ #19861]
- Authentication-results: sourceware.org; auth=none
- References: <56FBD238 dot 1010101 at redhat dot com>
On 03/30/2016 06:18 AM, Florian Weimer wrote:
> The IFUNC use is incorrect because you cannot assume that some other
> symbol has been relocated, and the current implementation sometimes
> returns an unrelocated address. (The bug is about vfork, but I'm sure
> fork has the same issue.)
You should be able to rely on relocations within library A having been run
before ifunc use within library A. Anything else is probably a linker/loader bug.
There are complex situations in which an IFUNC in library A references a symbol
X within library B, and the data structures behind X have not been relocated.
But that is not the case here: The reference to __libc_fork within libpthread
should be resolved by ld.so to the location within libc during primary
(non-lazy) relocation processing, before entry to main.
> Is there a reliable test case which exposes this problem? I made the
> vfork wrapper in libpthread a non-tail-call, fixed up the nptl vfork
> tests to actually call the wrapper (which I assume they currently don't
> due to the compat symbol), and still didn't get any crash.
If you're talking vfork, then you *must* use a tail-call, or other means (like
ifunc) to arrive at the syscall with no stack used. Otherwise you will have
situations where the child corrupts the saved return address of the parent.
The inability to reliably generate a tail-call between libraries for all ports
is exactly why we're defaulting to use an IFUNC in the first place.
But certainly individual ports are free to override pt-vfork.c. The simplest
way is simply not to bounce to libc at all, but continue to provide a copy of
vfork within libpthread. E.g. sysdeps/unix/sysv/linux/alpha/pt-vfork.S.
r~