Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature request: dynamically link against openssl #3803

Closed
htto opened this issue Apr 20, 2015 · 17 comments
Closed

Feature request: dynamically link against openssl #3803

htto opened this issue Apr 20, 2015 · 17 comments
Assignees
Labels

Comments

@htto
Copy link

htto commented Apr 20, 2015

I noticed that your steamclient.so (and probably others as well) include a whole (statically linked?) copy of openssl. This leads to problems for games, that themselves link against openssl. This results in libssl.so* and libcrypto.so* loaded by ld for the game itself, which is fine. Unfortunately, libsteam_api.so dlopens steamclient.so, which as stated above also has openssl symbols. Now if the application does call something in steamclient.so that uses ssl, this issues ssl initialization of the statically linked OPENSSL_cpuid_setup() that then dynamically calls the first occurrence of OPENSSL_ia32_cpuid() which resides in the prior loaded libcrypto.so from the system or the game itself. Game crashes like the following are then bound to happen if the openssl versions differ:
#0 OPENSSL_ia32_cpuid () at x86cpuid.s:26
#1 0xf2934701 in OPENSSL_cpuid_setup () from /games/Steam/linux32/steamclient.so
#2 0xf7913dcc in __libc_calloc (n=0, elem_size=0) at malloc.c:3258
#3 0xf1def5b4 in ?? () from /games/Steam/linux32/steamclient.so
#4 [..]

The crash happens in OPENSSL_ia32_cpuid() because it got a parameter added in openssl commit c5cd28bd64fa2b02f29e74486539e4b2f6741114, which your statically builtin version doesn't set up.

Is there a specific reason for including openssl in steamclient.so instead of dynamically linking against it?

@htto
Copy link
Author

htto commented Apr 20, 2015

A really simple example.c to show the problem is:

#include <unistd.h>

extern int SteamAPI_Init(void);

int main(int c, char **argv)
{
    int rc = 0;
    sleep(1);
    rc = SteamAPI_Init(); // crashes due to openssl initialization
    sleep(1);
    return rc;
}

Compilable with gcc -m32 -ggdb -lssl -lcrypto -L/path/to/libsteam_api/ -lsteam_api example.c -o example.

If compiled against openssl 1.0.2 it'll crash because of OPENSSL_ia32_cpuid() is now OPENSSL_ia32_cpuid(unsigned int *) [https://github.com/openssl/openssl/commit/c5cd28bd64fa2b02f29e74486539e4b2f6741114].

@gdrewb-valve
Copy link
Contributor

I don't think the symbols were intentionally exported, they shouldn't be exposed from steamclient.so.

@htto
Copy link
Author

htto commented Apr 20, 2015

Well, would be a solution to have absolute addressing within steamclient.so and no exported symbols.

But still, linking dynamically would be the preferable solution, I'd say. Unless you really want to ship everything, using the system libraries is probably better for security and performance reasons and would reduce distribution sizes.

@EoD
Copy link

EoD commented Nov 14, 2015

I found my way here by google, so I am not sure if my following Star Conflict crash is related to the issue here or not:

/steam/SteamApps/common/star conflict/StarConflict: /usr/lib32/libcurl.so.4: no version information available (required by /steam/SteamApps/common/star conflict/StarConflict)
/steam/SteamApps/common/star conflict/StarConflict: /usr/lib32/libcrypto.so.1.0.0: no version information available (required by /steam/SteamApps/common/star conflict/StarConflict)
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib64/libthread_db.so.1".
(0):[INFO] //////////////////////////////////////////////////////////////////////////////
(0):[INFO] //
(0):[INFO] // Build: StarConflict 1.2.3.78951 (Linux) (Nov 13 2015 18:41:14)
(0):[INFO] //
(0):[INFO] //////////////////////////////////////////////////////////////////////////////
(0):[INFO] 
[New Thread 0xf37d4b40 (LWP 1772)]
[New Thread 0xf3fd5b40 (LWP 1771)]
[New Thread 0xf48dcb40 (LWP 1770)]

Program received signal SIGSEGV, Segmentation fault.
OPENSSL_ia32_cpuid () at x86cpuid.s:26
26  x86cpuid.s: No such file or directory.

@mboquien
Copy link

I am getting a crash that may be related with Total War: Attila. I have trouble getting the relevant information but dmesg indicates this:
[ 6164.563478] Attila[18779]: segfault at 7f1d97db971b ip 00007f1d9c649c65 sp 00007ffd453da438 error 7 in libcrypto.so.1.0.0[7f1d9c5de000+24e000]
[ 6176.213308] Attila[18872]: segfault at 0 ip 00007f74781e2078 sp 00007ffcab4db288 error 6 in libc-2.22.so[7f7478151000+19b000]
Is there any way I can investigate whether the issue is actually linked to this bug report?

@htto
Copy link
Author

htto commented Jan 2, 2016

Well, I don't own any of those games you mention, but the backtrace looks like it's the same issue. For me the problem is triggered for games linked against openssl, since having openssl 1.0.2 system libraries.

For a dirty workaround you can try LD_PRELOAD=/path/to/steam/ubuntu12_32/steamclient.so for the affected game.

@EoD
Copy link

EoD commented Jan 2, 2016

Star Conflict is free to play. Just give it a try: http://store.steampowered.com/app/212070/

@htto
Copy link
Author

htto commented Jan 3, 2016

Well, after downloading 5GB of StarConflict, it seems to have the very same problem

(0):[INFO] //////////////////////////////////////////////////////////////////////////////
(0):[INFO] //
(0):[INFO] // Build: StarConflict 1.3.0.81352 (Linux) (Dec 25 2015 15:19:19)
(0):[INFO] //
(0):[INFO] //////////////////////////////////////////////////////////////////////////////
(0):[INFO]

Program received signal SIGSEGV, Segmentation fault.
0xf7cc1ba5 in OPENSSL_ia32_cpuid () from /usr/lib32/libcrypto.so.1.0.0
(gdb) bt
#0 0xf7cc1ba5 in OPENSSL_ia32_cpuid () from /usr/lib32/libcrypto.so.1.0.0
#1 0xf2bdfc31 in OPENSSL_cpuid_setup () from /games/Steam/linux32/steamclient.so
#2 0xf74ba91c in calloc () from /lib32/libc.so.6
#3 0x00000000 in ?? ()

Can be hacked around by: env LD_LIBRARY_PATH=/path/to/steam/ubuntu12_32/ LD_PRELOAD=/path/to/steam/ubuntu12_32/steamclient.so ./StarConflict
or using some pre-1.0.2 openssl libs.

Does forcing steam-runtime help?

@htto
Copy link
Author

htto commented Jan 3, 2016

@mboquien Either run attilla through gdb and print the backtrace (bt) on crash, or at least look up the address of OPENSSL_ia32_cpuid with
objdump -T /usr/lib{,64}/libcrypto.so.1.0.0 | grep OPENSSL_ia32_cpuid.
If the returned address is around 0x6BC65 (0x00007f1d9c649c65-0x7f1d9c5de000) it's probably the same issue as well. Then the workaround from my previous comment should hold as well.

@mboquien
Copy link

mboquien commented Jan 3, 2016

@htto It appears to be the same problem if I believe objdump:

000000000006bc60 g    DF .text  0000000000000187  Base        OPENSSL_ia32_cpuid

and the gdb backtrace:

#0  0x00007ffff174bc65 in OPENSSL_ia32_cpuid () from /usr/lib/libcrypto.so.1.0.0
#1  0x00007fffe944e834 in ?? () from /home/mederic/.local/share/Steam/linux64/steamclient.so
#2  0x00007fffe8a501ab in _init () from /home/mederic/.local/share/Steam/linux64/steamclient.so
#3  0x00007fffe8857df0 in ?? () from /home/mederic/.local/share/Steam/linux64/steamclient.so
#4  0x00007ffff7dea23a in call_init.part () from /lib64/ld-linux-x86-64.so.2
#5  0x00007ffff7dea38b in _dl_init () from /lib64/ld-linux-x86-64.so.2
#6  0x00007ffff7dee830 in dl_open_worker () from /lib64/ld-linux-x86-64.so.2
#7  0x00007ffff7dea124 in _dl_catch_error () from /lib64/ld-linux-x86-64.so.2
#8  0x00007ffff7dedfd1 in _dl_open () from /lib64/ld-linux-x86-64.so.2
#9  0x00007ffff774f918 in ?? () from /usr/lib/libdl.so.2
#10 0x00007ffff7dea124 in _dl_catch_error () from /lib64/ld-linux-x86-64.so.2
#11 0x00007ffff774f5e1 in ?? () from /usr/lib/libdl.so.2
#12 0x00007ffff774f9c6 in dlmopen () from /usr/lib/libdl.so.2
#13 0x00007ffff753a6af in ?? () from ./libsteam_api.so
#14 0x00007ffff753cc34 in ?? () from ./libsteam_api.so
#15 0x00007ffff753d54f in SteamAPI_Init () from ./libsteam_api.so
#16 0x0000000000575310 in EMPIRE::STEAM_INITIALISER::create (anti_piracy_v2_cracked_3=@0x7fffe9643a13: 1313165391) at Source/SteamInitialiser.cpp:128
#17 0x000000000058769a in EMPIRE::STEAM_APPLICATION_INITIALISER::initialise (this=<optimized out>, init=...) at Source/ApplicationInitialisers.cpp:2610
#18 0x00000000005895dd in operator new (size=<optimized out>, init=0x560d8d0, init=0x560d8d0, init=0x560d8d0, tw_init=..., size=<optimized out>)
    at Source/ApplicationInitialisers.cpp:167
#19 EMPIRE::EMPIRE_APP_MODULE::initialise_locale_independent_systems (this=<optimized out>) at Source/Empire.cpp:1919
#20 0x0000000000589465 in EMPIRE::EMPIRE_APP_MODULE::EMPIRE_APP_MODULE (this=0x57ab660, init=..., cmdLine=...) at Source/Empire.cpp:1869
#21 0x000000000057553b in TOTALWAR::GLOBALS::GLOBALS (this=0x4c17a38 <TOTALWAR::globals(EMPIRE::PlatformContext const&)::s_globals>, init=...) at Source/POSIX/AppModuleWrapper.cpp:87
#22 0x0000000000575771 in TOTALWAR::globals () at Source/POSIX/AppModuleWrapper.cpp:104
#23 TOTALWAR::on_app_created (init=...) at Source/POSIX/AppModuleWrapper.cpp:122
#24 0x00000000004e3bdc in run_thread (argc=<optimized out>, argv=<optimized out>) at Source/TotalWar.cpp:116
#25 0x00000000004e3e1b in main (argc=1, argv=0x7fffffffe818) at Source/TotalWar.cpp:177

I have tried your workaround but I cannot get it to work. Attila has a 64 bit executable

Attila: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 2.6.24, BuildID[sha1]=d50fb24964d58940101b031b9b6e861500e53642, not stripped)

I have tried adapting your command line to get the 64 bit files. It still crashes but the backtrace is very different so I think it is another bug that should not be discussed here. Thanks!

@supagu
Copy link

supagu commented Jan 22, 2016

I am getting this error with steam while trying to run a game I am developing with the unreal engine 4 (which uses steam, openssl and libcurl) and trying to work out how to resolve it.

Is the solution to build my game against the same version of openssl or libcurl as steam is built with? If so, what version is steam built with?

@Plagman
Copy link
Member

Plagman commented Jan 23, 2016

Can you guys try opting into the Beta? We fixed something there that should address these issues.

For the linking question, in general to ship software through Steam you should build against the Steam Runtime SDK:

https://github.com/ValveSoftware/steam-runtime

@EoD
Copy link

EoD commented Jan 23, 2016

Steam Built: Jan 21 2016, at 20:12:46

Star Conflict is working again. Thanks!

@supagu
Copy link

supagu commented Jan 24, 2016

Thanks Plagman, so it looks like we need to build our game through the steam environment?
I'm trying to build the unreal engine 4 source and it needs mono-xbuild so I ran:
apt-get install mono-xbuild

but it installs an older version (2.10) where UE4 requires version 3 or above.
I am unsure how to try to get a newer version installed...

I then opted into the steam beta and the game ran fine. So I am wondering if the proper procedure is to build via steam environment or to simply leave our game build through our own environment and tell people to opt into the steam beta if they hit the crash?

@htto
Copy link
Author

htto commented Jan 24, 2016

@Plagman Is there some more precise changelog/information available about the change? Still the need for statically including openssl into steamclient.so would be interesting.

@supagu It should suffice to adjust LD_LIBRARY_PATH for runtime or use a proper -rpath path when linking if you require and distribute some specific openssl version. You just need to make sure to pick up only one version. This bug is basically about crashes due to different/incompatible openssl libraries being loaded into the same process. So if steam-runtime uses the same openssl version as is linked into steamclient.so, and that version suffices for your needs, then using/building against steam-runtime should work.

@mboquien It looks like the same issue to me. steamclient.so should use the OPENSSL_ia32_cpuid from it's library instead the system's one.

Also note, that running the game from command-line probably breaks the use of steam-runtime (by picking up some different openssl library, e.g. the system's one) and has different results than starting through steam. Though, I've not traced the library path setup...

@spstarr
Copy link

spstarr commented Feb 13, 2016

This remains a problem for the Fedora world... but its not a game that's crashing yet.. but steam itself. gdb shows this:

#0 0xf6275b85 in OPENSSL_ia32_cpuid () from /lib/libcrypto.so.10
#1 0xf1dc1351 in OPENSSL_cpuid_setup () from /home/XXXXX/.local/share/Steam/ubuntu12_32/steamui.so
#2 0xf7c6d7b0 in main_arena () from /lib/libc.so.6
#3 0x000000d0 in ?? ()
#4 0x00007670 in ?? ()
#5 0xf7c6d000 in ?? () from /lib/libc.so.6
Backtrace stopped: previous frame inner to this frame (corrupt stack?)

Ideas...?

@spstarr
Copy link

spstarr commented Feb 18, 2016

my ugly work around was to remove that function from OpenSSL, c'mon Steam you're doing a horrible job here with your building of the Steam binary..

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

7 participants