_IO_stdin_used stripped by version scripts

Florian Weimer fweimer@redhat.com
Mon Aug 29 08:49:00 GMT 2016


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



More information about the Libc-alpha mailing list