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

Re: IFUNC resolver scheduling (bugs 21041, 20019)


On 01/25/2017 11:28 AM, Szabolcs Nagy wrote:
> if by 'ifunc-based' relocation you mean that the
> copy relocation refers to an STT_GNU_IFUNC type
> symbol, then that should not happen and it is ok
> to crash on it.
> 
> i still think that it is invalid for an ifunc resolver
> to return an object address but in case of copy relocs
> it would not work anyway:
> 
> to do the copy the symbol size in the symbol table is
> used but that's the size of the resolver function, not
> the size of the object whose address is returned.

See elf/ifuncmain6pie.c and elf/ifuncmod6.c.

The particular case that fails is where the main PIE binary
references a function pointer defined in a shared object and
whose initial value is the address of the STT_GNU_IFUNC function.

The function pointer is global data accessed by the PIE binary
and so a COPY relocation is emitted for the value.

The function pointer in the shared object must be initialized
before the COPY relocation otherwise you are copying zero into
the binary copy.

The ifuncmain6pie test fails because get_foo_p (0x0) != foo.
You get this because the COPY reloc copies 0x0 from the shared
object version of the function pointer. Then the binary calls
get_foo_p() and the library returns the value of foo_p which
is 0x0 since it also references the interposed binary value of
the symbol.

The COPY relocation depends on memory initialized by an IRELATIVE
reloc, and so must happen last, but as Florian notes, there could
be IRELATIVE resolver functions which depend on data initialized
by a COPY reloc.

There are several solutions:

(a) Handle COPY relocs last.

- The only failure mode is a resolver function in a binary
  which references global data defined in a shared object
  dependency. We should be able to detect this in the static
  linker or with an external tool e.g. COPY reloc initializes
  symbol and the address of the symbol in any other dependent
  DSO has an IRELTIVE reloc against it's memory.

- We can document this as being something we don't support.
  e.g. Don't reference global data in other shared objects
  from resolver functions in the main executable.

or

(b) Handle COPY relocs twice.

- The first pass of COPY relocs may copy zeroes, but it will
  also setup all data for things that _don't_ depend on IRELATIVE
  reloc initialized data. Then run the IRELATIVE relocs.
  Then run the COPY relocs again.

- We then document: Don't reference global data in other shared
  objects that are themselves initialized to the value of IFUNCs
  (narrower restriction).

I vote for (a) and documenting the reasonable restriction.

-- 
Cheers,
Carlos.


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