[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#966173: marked as done (libc6: __atan2_finite reference in dlopened module no longer found in executable linked to libm)



Your message dated Sat, 4 Sep 2021 21:53:54 +0200
with message-id <YTPO0p75ccys1+7R@aurel32.net>
and subject line Re: Bug#966173: libc6: __atan2_finite reference in dlopened module no longer found in executable linked to libm
has caused the Debian Bug report #966173,
regarding libc6: __atan2_finite reference in dlopened module no longer found in executable linked to libm
to be marked as done.

This means that you claim that the problem has been dealt with.
If this is not the case it is now your responsibility to reopen the
Bug report if necessary, and/or fix the problem forthwith.

(NB: If you are a system administrator and have no idea what this
message is talking about, this may indicate a serious mail system
misconfiguration somewhere. Please contact owner@bugs.debian.org
immediately.)


-- 
966173: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=966173
Debian Bug Tracking System
Contact owner@bugs.debian.org with problems
--- Begin Message ---
Package: libc6
Version: 2.31-1
Severity: normal

I've encountered an odd bug in openarena (#966150) which I'm concerned
might be a glibc regression affecting other packages.

Some background: openarena is a game running on the ioquake3 engine
(main executable: /usr/lib/ioquake3/ioquake3). During startup, the engine
dlopens some modules, which implement the actual openarena game and UI.
One of those modules is uix86_64.so.

uix86_64.so uses mathematical functions from libm, but is not itself
linked to libm. At runtime (at least on older systems) it works as
intended, because the ioquake3 executable *is* linked to libm. I'm aware
that this is not the most robust setup, and uix86_64.so would ideally be
linked with -lm to make it self-contained; but it's documented as being
expected to work, and has always worked in the past:

    Symbol references in the shared object are resolved using (in order):
    symbols in the link map of objects loaded for the main program and its
    dependencies; [... and some more places ...]
    — dlopen(3)

The bug (#966150) is that a version of uix86_64.so compiled with a slightly
older (2020-02-18) toolchain fails to load on an up-to-date sid system, with:

    undefined symbol: __atan2_finite

If I recompile openarena in a sid chroot, *with no source code changes*
(in particular uix86_64.so is still not linked to -lm!), then it starts
to work again. The recompiled uix86_64.so has an undefined reference
to atan2, but no reference to __atan2_finite any more.

I'm going to address this in bullseye by making openarena more robust
(explicitly linking to -lm). After I've done that, the updated version of
openarena will not be suitable as a reproducer for this bug report, but
the buster version of openarena will still be suitable.

If you believe this is not a significant regression in glibc and should
only be fixed by changes in openarena, I have no problem with doing that
and just closing this bug report. However, I wanted to raise this in
case it affects other previously-built binaries.

This can be reproduced somewhat conveniently as follows:

* Have a buster virtual machine
* Install openarena and enough of a desktop to get a terminal in an X11
  environment
* Run openarena
    * It succeeds
    * To exit quickly: Shift+Escape, type "/quit", Enter
* Add a bullseye apt source and "apt update", but do not upgrade everything
* Upgrade libc6 from 2.28-10 to 2.31-1, while upgrading as few other
  packages as possible
    * I used aptitude, which made me also upgrade gcc-9 and related
      packages, removing gcc-8
* Run openarena
    * It fails as described in #966150
* Downgrade libc6 and closely-related packages from 2.31-1 to 2.28-10
    * In my case this meant downgrading libc-dev-bin, libc6-dev, libc6
      and libc-bin, and removing libcrypt-dev and libcrypt1
* Run openarena
    * It succeeds again, confirming that this was a glibc behaviour change

I've been trying to put together a standalone reproducer that only uses
libdl and libm, but so far I have not been successful.

I believe this is related to a change in the representation of
the __atan2_finite symbol, which is used (at least by versions of
openarena compiled against older glibc) because openarena is compiled
with -ffast-math. In 2.28-10, that symbol was not hidden:

$ objdump -Tx /lib/x86_64-linux-gnu/libm.so.6
...
0000000000028280 g   iD  .text  0000000000000046  GLIBC_2.15  __atan2_finite

In 2.31-1, it is hidden, and there is no non-hidden definition (default
symbol-version):

$ objdump -Tx /lib/x86_64-linux-gnu/libm.so.6
...
000000000002a1e0 g   iD  .text  0000000000000049 (GLIBC_2.15) __atan2_finite

Because uix86_64.so is not directly linked to -lm, it has an undefined
reference to __atan2_finite with no particular version:

$ objdump -Tx /usr/lib/openarena/baseoa/pak6-patch088/uix86_64.so
...
0000000000000000      D  *UND*  0000000000000000              __atan2_finite

As far as I can work out, this unversioned undefined reference can be
satisfied by __atan2_finite@@GLIBC_2.15 in the global namespace from
the old libm, but not by the hidden version __atan2_finite@GLIBC_2.15
in the new libm.

Thanks,
    smcv

--- End Message ---
--- Begin Message ---
Version: 2.31-3

On 2020-07-27 00:12, Aurelien Jarno wrote:
> On 2020-07-24 15:23, Simon McVittie wrote:
> > On Fri, 24 Jul 2020 at 14:36:54 +0200, Bastian Blank wrote:
> > > On Fri, Jul 24, 2020 at 10:11:04AM +0100, Simon McVittie wrote:
> > > > The bug (#966150) is that a version of uix86_64.so compiled with a slightly
> > > > older (2020-02-18) toolchain fails to load on an up-to-date sid system, with:
> > > >     undefined symbol: __atan2_finite
> > > 
> > > Because the binary was not linked with -lm, the linker never saw the
> > > real symbol __atan2_finite@GLIBC2_16, so the linke only emitted a reference
> > > to __atan2_finite.
> > 
> > Right. However, note that there's no mention of __atan2_finite() in the
> > source code - it's only used because older glibc would replace atan2()
> > with a reference to __atan2_finite() when building with -ffast-math.
> 
> I do not see what does it change. atan2 also need to be linked with
> -libm. If it is not, issues like the one you encountered might happen.
> The change from atan2 to __atan2_finite when -ffast-math is in used is
> purely done in the preprocessor.
> 
> > > At least dpkg-shlibdeps or so should warn about that.
> > 
> > For at least openarena, it doesn't seem to. I'm not sure why not.
> > 
> > For the next update to openarena I'm going to build it with -Wl,-z,defs
> > so that missing dependencies are always fatal. However, that isn't
> > always applicable: some plugin architectures (like Python extensions)
> > rely on being able to pick up symbols exported by the executable, which
> > are not necessarily programmatically distinguishable from symbols that
> > are defined by libraries used by the executable.
> 
> This is indeed an issue, under-linking is sometimes difficult to find.
> Given we now the list of affected symbols, I'll try to check if other
> binaries are affected so that they can be fixed even if no users report
> an issue.
> 
> > > > I've been trying to put together a standalone reproducer that only uses
> > > > libdl and libm, but so far I have not been successful.
> > > 
> > > Something like that?
> > > 
> > > | % cat test.c
> > > | void __atan2_finite(void);
> > > | void test(void) {
> > > |   __atan2_finite();
> > > | }
> > 
> > I was aiming for something a bit closer to openarena's situation,
> > where there is no explicit reference to __atan2_finite() in the source
> > code: it calls atan2(), and cc -ffast-math rewrites that into a call
> > to __atan2_finite(). I've now managed to make this work: see attached.
> > 
> > Compile them and run ./prog in a buster environment (or an outdated
> > bullseye/sid environment with glibc < 2.31), then run ./prog in an
> > up-to-date bullseye/sid environment without recompiling.
> > 
> > libmymodule.so will get a dynamic reference to __atan2_finite.
> > 
> > The historical result is that prog outputs 0.463648, twice.
> > 
> > The result in up-to-date bullseye/sid is that prog outputs 0.463648,
> > once, and then fails with "undefined symbol: __atan2_finite".
> > 
> > Using __FINITE_MATH_ONLY__ (which is defined by -ffast-math) is necessary
> > to be able to reproduce the bug this way.
> > 
> > If you consider this sort of thing to be too niche to be supportable,
> > please feel free to close the bug.
> 
> I do consider it a bug on the openarena side, as it's basically using a
> non-versioned symbol due to under-linking. However from the user point
> of view, we should prevent that to happen, so I'll add the corresponding
> Breaks: entry on the glibc side to ensure a flawless upgrade for the
> users.

This has been done in glibc 2.31-3. Closing the bug accordingly.

Regards,
Aurelien

-- 
Aurelien Jarno                          GPG: 4096R/1DDD8C9B
aurelien@aurel32.net                 http://www.aurel32.net

--- End Message ---

Reply to: