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: _IO_stdin_used stripped by version scripts


On 08/28/2016 10:01 PM, Aurelien Jarno wrote:
On 2016-08-28 15:58, Florian Weimer wrote:
* Aurelien Jarno:

On some architectures the _IO_stdin_used symbol is used to determine if
the executable has been linked against the older version of libio or the
newer. More and more executables start to be linked with a version
script in order to control the symbols they export to their plugins.
Examples of such software are firefox, network-manager or mplayer. When
using a version-script without explicitly adding an entry for the
_IO_stdin_used symbol, it appears as a local symbol in the resulting
libraries. This causes random crashes or strange behaviours. We have
observed that in Debian at least on alpha, mips* and powerpc.

The first part would be to figure out what _IO_stdin_used is actually
about.  I think it's there to preserve the libio ABI (as far as
vtables are concerned) despite the fact that the struct layout was
changed (possibly to reflect a C++ ABI change).

For what I understood, the libio ABI has changed with glibc 2.1 in order
to support for wide-character streams and 64 bit offsets. These
changes required an incompatible change to the FILE structure. That's
why we have two versions of libio functions one tagged GLIBC_2.0 and one
tagged GLIBC_2.1. The problem is that the FILE structure can be passed
as a pointer so that the symbol versioning mechanism doesn't work.
Therefore when a binary is build against glibc >= 2.1, there will be a
reference to _IO_stdin_used add. If there are no references to
_IO_stdin_used, the compatibility layer will kick in, and make the
stdin/stdout/stderr pointers by pointers to the compatibility objects.

And if this leads to crashes, the compatibility mechanism doesn't work. I'm not saying we should fix this, but there does seem to be a bug here, beyond the unintentional selection of compatibility mode.

There are a lot of ways how we could improve the hack. But it's difficult to test that it works as intended because we don't have a large set of existing binaries to test with.

One fairly conservative change would version the symbols which
activate vtable compatibility, and have the new versions override the
_IO_stdin_used mechanism.  There should be room for such a flag in the
_flags2 member of struct _IO_file.

The other idea would be to simply disable this compatibility layer. This
means that binaries older than 15 years old would not work anymore, but
that *might* be acceptable for some architectures, although maybe not
for i386.

If we want to go this route, we should try it for i386 as well, and remove all external libio symbols (beyond those used by <stdio.h>), not just the existing compatibility hack. The general libio compatibility has a large cost for us, and it's unclear if users still need it.

Thanks,
Florian


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