Skip to content

Compress::Raw::Zlib doesn't apply symbol versioning when building zlib-src #8

Closed
Perl/perl5
#19725
@monkburger

Description

@monkburger

There's a rare chance that when using the C:R:Z XS module under Linux (possibly others, like Solaris), there may be a symbol collision depending on your backend environment (perlcc, mod_perl, or other modules).

Zlib.so exports these functions, globally, without any symbol versions (via readelf -s blib/arch/auto/Compress/Raw/Zlib/Zlib.so | egrep flate)

57: 0000000000012ce0   198 FUNC    GLOBAL DEFAULT   14 inflateResetKeep
61: 0000000000015650    80 FUNC    GLOBAL DEFAULT   14 inflateCodesUsed
62: 00000000000152d0    75 FUNC    GLOBAL DEFAULT   14 inflateSyncPoint
64: 000000000000f310   228 FUNC    GLOBAL DEFAULT   14 deflateResetKeep
65: 0000000000012580    62 FUNC    GLOBAL DEFAULT   14 inflateBackEnd
66: 0000000000015530    70 FUNC    GLOBAL DEFAULT   14 inflateUndermine
67: 0000000000012ee0   192 FUNC    GLOBAL DEFAULT   14 inflateInit2_
69: 0000000000014ec0   212 FUNC    GLOBAL DEFAULT   14 inflateSetDictionary
70: 0000000000012e10   198 FUNC    GLOBAL DEFAULT   14 inflateReset2
77: 000000000000f590   210 FUNC    GLOBAL DEFAULT   14 deflatePrime
78: 000000000000f800  4985 FUNC    GLOBAL DEFAULT   14 deflate

On ELF based systems (Linux, etc), unversioned symbols preempt versioned ones, so you could run into issues such as what was described in this bug report with CryptX, as well as these upstream reports relating to symbol versions, as well as this

He's what LD_DEBUG=all shows on some test code:

foo.1358336: 1358336: symbol=inflate; lookup in file=/usr/lib/x86_64-linux-gnu/perl/5.30/auto/Compress/Raw/Zlib/Zlib.so [0]
foo.1358336: 1358336: symbol=inflate; lookup in file=/lib/x86_64-linux-gnu/libz.so.1 [0]

Which yields the following:

foo.1358336:   1358336:	binding file /usr/lib/x86_64-linux-gnu/perl/5.30/auto/Compress/Raw/Zlib/Zlib.so [0] to /lib/x86_64-linux-gnu/libz.so.1 [0]: normal symbol `inflate'

A small rant: ELF systems (Solaris, Linux) situation is ever worse because they allow runtime symbol interposition (i.e. libraries compete for who wins over symbol names at program startup). There's no telling what symbol you will get, as the flat namespace model shows.

Some ideas to avoid any issues:

  • Use zlib.map from upstream when building zlib-src
  • -Bsymbolic to the linker/compiler flags? <-- not tested, unsure of how it would work unless you linked libperl.so / libperl.a at link time
  • Avoid building zlib-src and just depend on the system libz

Metadata

Metadata

Assignees

Labels

bugSomething isn't working

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions