question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Cannot get required symbol EVP_rc2_cbc from libssl

See original GitHub issue

Powershell: powershell-7.1.3-linux-x64.tar.gz OS: ubuntu 16.04

$ ./pwsh 
PowerShell 7.1.3
Copyright (c) Microsoft Corporation.

https://aka.ms/powershell
Type 'help' to get help.

Cannot get required symbol EVP_rc2_cbc from libssl
Aborted
$ readelf -a libssl.so.1.0.0 | grep EVP_rc2_cbc
0000002660f8  007a00000007 R_X86_64_JUMP_SLO 0000000000000000 EVP_rc2_cbc@OPENSSL_1.0.0 + 0
   122: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND EVP_rc2_cbc@OPENSSL_1.0.0 (7)

$ readelf -a libcrypto.so.1.0.0 | grep EVP_rc2_cbc
  3571: 00000000001265d0     8 FUNC    GLOBAL DEFAULT   13 EVP_rc2_cbc@@OPENSSL_1.0.0

Any ideas to resolve this issue or get more error output for details?

Issue Analytics

  • State:closed
  • Created 2 years ago
  • Comments:10

github_iconTop GitHub Comments

1reaction
jborean93commented, May 16, 2021

Thanks for the reproducer I’m able to replicate the problem in a docker container myself. I can see that the /opt/microsoft/powershell/7/libSystem.Security.Cryptography.Native.OpenSsl.so library is the one that’s dynamically loading the libssl library which in turn loads the libcrypto library. You can see this by doing LD_DEBUG=all pwsh and looking at this in the output

     14282:     calling init: /opt/microsoft/powershell/7/libSystem.Security.Cryptography.Native.OpenSsl.so
     14282:
     14282:
     14282:     file=libssl.so.1.1 [0];  dynamically loaded by /opt/microsoft/powershell/7/libSystem.Security.Cryptography.Native.OpenSsl.so [0]
     14282:     find library=libssl.so.1.1 [0]; searching
     14282:      search cache=/etc/ld.so.cache
     14282:       trying file=/usr/local/openssl-1.1.1/lib/libssl.so.1.1
     14282:
     14282:     file=libssl.so.1.1 [0];  generating link map
     14282:       dynamic: 0x00007f517ee6fd60  base: 0x00007f517ebe1000   size: 0x0000000000293780
     14282:         entry: 0x00007f517ebfe710  phdr: 0x00007f517ebe1040  phnum:                  7
     14282:
     14282:
     14282:     file=libcrypto.so.1.1 [0];  needed by /usr/local/openssl-1.1.1/lib/libssl.so.1.1 [0]
     14282:     find library=libcrypto.so.1.1 [0]; searching
     14282:      search cache=/etc/ld.so.cache
     14282:       trying file=/usr/local/openssl-1.1.1/lib/libcrypto.so.1.1
     14282:
     14282:     file=libcrypto.so.1.1 [0];  generating link map
     14282:       dynamic: 0x00007f517ebd9d08  base: 0x00007f517e6e5000   size: 0x00000000004fb3a0
     14282:         entry: 0x00007f517e75b000  phdr: 0x00007f517e6e5040  phnum:   

It shows that it is correctly looking in the ld.so.cache fo libssl.so.1.1 and because there’s now a match it uses the custom ssl library and not the one the system provides. You can see in the native code that the OpenSSL shim libSystem.Security.Cryptography.Native.OpenSsl.so setups up tries a whole bunch of versions using dlopen so you won’t see a direct dependency when checking through ldd https://github.com/dotnet/runtime/blob/64303750a9198a49f596bcc3aa13de804e421579/src/libraries/Native/Unix/System.Security.Cryptography.Native/opensslshim.c#L78-L133.

Also in that code you can see that during the init phase defined in InitializeOpenSSLShim it first checks if SSL_State is defined to determine if the linked OpenSSL lib is based on 1.0.0 or not. We can see in the LD logs that this happens and fails because the loaded OpenSSL library is based on 1.1.x

     14335:     symbol=SSL_state;  lookup in file=/usr/local/openssl-1.1.1/lib/libssl.so.1.1 [0]
     14335:     symbol=SSL_state;  lookup in file=/usr/local/openssl-1.1.1/lib/libcrypto.so.1.1 [0]
     14335:     symbol=SSL_state;  lookup in file=/lib/x86_64-linux-gnu/libpthread.so.0 [0]
     14335:     symbol=SSL_state;  lookup in file=/lib/x86_64-linux-gnu/libc.so.6 [0]
     14335:     symbol=SSL_state;  lookup in file=/lib/x86_64-linux-gnu/libz.so.1 [0]
     14335:     symbol=SSL_state;  lookup in file=/lib/x86_64-linux-gnu/libdl.so.2 [0]
     14335:     symbol=SSL_state;  lookup in file=/lib64/ld-linux-x86-64.so.2 [0]
     14335:     /usr/local/openssl-1.1.1/lib/libssl.so.1.1: error: symbol lookup error: undefined symbol: SSL_state (fatal)

It then goes on to check that a whole bunch of functions that are required by the .NET OpenSSL shim are present and we can find EVP_rc2_cbc. Because EVP_rc2_cbc is a required function the .NET code goes to look up that symbol and we get this error in the LD_DEBUG log

     14335:     symbol=EVP_rc2_cbc;  lookup in file=/usr/local/openssl-1.1.1/lib/libssl.so.1.1 [0]
     14335:     symbol=EVP_rc2_cbc;  lookup in file=/usr/local/openssl-1.1.1/lib/libcrypto.so.1.1 [0]
     14335:     symbol=EVP_rc2_cbc;  lookup in file=/lib/x86_64-linux-gnu/libpthread.so.0 [0]
     14335:     symbol=EVP_rc2_cbc;  lookup in file=/lib/x86_64-linux-gnu/libc.so.6 [0]
     14335:     symbol=EVP_rc2_cbc;  lookup in file=/lib/x86_64-linux-gnu/libz.so.1 [0]
     14335:     symbol=EVP_rc2_cbc;  lookup in file=/lib/x86_64-linux-gnu/libdl.so.2 [0]
     14335:     symbol=EVP_rc2_cbc;  lookup in file=/lib64/ld-linux-x86-64.so.2 [0]
     14335:     /usr/local/openssl-1.1.1/lib/libssl.so.1.1: error: symbol lookup error: undefined symbol: EVP_rc2_cbc (fatal)

If any one of these symbols don’t exist then .NET prints out the error message you see and calls abort https://github.com/dotnet/runtime/blob/64303750a9198a49f596bcc3aa13de804e421579/src/libraries/Native/Unix/System.Security.Cryptography.Native/opensslshim.c#L154 bringing down the whole application. We can even prove that the libcrypto.so compiled and added to the ld cache doesn’t contain the symbol when the system library one does.

root@165e3b6118e9:/# objdump -TC /usr/lib/x86_64-linux-gnu/libcrypto.so | grep EVP_rc2_cbc
00000000001265d0 g    DF .text	0000000000000008  OPENSSL_1.0.0 EVP_rc2_cbc

root@165e3b6118e9:/# objdump -TC /usr/local/openssl-1.1.1/lib/libcrypto.so | grep EVP_rc2_cbc

Ultimately what this means is that a library provided by .NET requires the dynamically loaded OpenSSL lib have this symbol amongst others to be present for it to work. This isn’t someting controlled by the PowerShell team and a requirement from dotnet themselves.

The reason why you can do pwsh -Command ... and it not fail is due to PSReadLine which is loaded for interactive sessions. This will be in some way calling some crypto function which in turns calls the OpenSSL shim init code that ends up in the abort. By removing the module entirely, or by running in some non-interactive mode, you can get PowerShell to run. Or at least it will run until you yourself try to run some crypto based code like Invoke-WebRequest https://google.com. Ultimately it doesn’t matter as much as the problem lies in trying to use an incomplete OpenSSL lib from .NET’s perspective.

As for why .NET has a hard requirement of these functions you would have to open an issue on their end to get an answer.

<div> GitHub</div><div>dotnet/runtime</div><div>.NET is a cross-platform runtime for cloud, mobile, desktop, and IoT apps. - dotnet/runtime</div>
<div> GitHub</div><div>dotnet/runtime</div><div>.NET is a cross-platform runtime for cloud, mobile, desktop, and IoT apps. - dotnet/runtime</div>
0reactions
iceblueycommented, May 16, 2021

Thank you @jborean93 . I found a solution from debug information:

… 32227: file=libssl.so.1.1 [0]; dynamically loaded by /opt/microsoft/powershell/7/libSystem.Security.Cryptography.Native.OpenSsl.so [0] 32227: find library=libssl.so.1.1 [0]; searching 32227: search path=/opt/microsoft/powershell/7/netcoredeps/tls/x86_64:/opt/microsoft/powershell/7/netcoredeps/tls:/opt/microsoft/powershell/7/netcoredeps (RPATH from file /opt/microsoft/powershell/7/pwsh) 32227: trying file=/opt/microsoft/powershell/7/netcoredeps/tls/x86_64/libssl.so.1.1 32227: trying file=/opt/microsoft/powershell/7/netcoredeps/tls/libssl.so.1.1 32227: trying file=/opt/microsoft/powershell/7/netcoredeps/libssl.so.1.1 … 32227: file=libcrypto.so.1.1 [0]; needed by /usr/local/openssl-1.1.1/lib/libssl.so.1.1 [0] 32227: find library=libcrypto.so.1.1 [0]; searching 32227: search path=/opt/microsoft/powershell/7/netcoredeps/tls/x86_64:/opt/microsoft/powershell/7/netcoredeps/tls:/opt/microsoft/powershell/7/netcoredeps (RPATH from file /opt/microsoft/powershell/7/pwsh) 32227: trying file=/opt/microsoft/powershell/7/netcoredeps/tls/x86_64/libcrypto.so.1.1 32227: trying file=/opt/microsoft/powershell/7/netcoredeps/tls/libcrypto.so.1.1 32227: trying file=/opt/microsoft/powershell/7/netcoredeps/libcrypto.so.1.1

We build custom openssl 1.1.1 only for powershell and copy libssl.so.1.1 and libcrypto.so.1.1 to /opt/microsoft/powershell/7/netcoredeps/tls/x86_64/ .

PowerShell and .NET work fine.

Read more comments on GitHub >

github_iconTop Results From Across the Web

fixing cannot get required symbol SSL_set_alpn_protos ...
Hi! I dont use docker. Application is published in self-contained mode from Visual Studio IDE to folder and copied them to Debian server...
Read more >
View topic - [SOLVED] Possibly broken OpenSSL install
So a few weeks ago I noticed that whenever I ran 'dotnet-cli -h' it would segfault with the error message being: "Cannot get...
Read more >
fixing cannot get required symbol SSL_set_alpn_protos ...
Cannot get required symbol SSL_set_alpn_protos from libssl. How to run .NET 7.0.103 application in Debian Jessie ?
Read more >
Issues with libSSL : r/archlinux
Whenever I try and run paru I get paru: error while loading shared libraries: libcrypto.so.1.1: cannot open shared object file: No such file ......
Read more >
SOLVED: "No usable version of the libssl was found"
The problem is that versions 1.0 and 1.1 are not compatible. An application that expects 1.0 cannot build against 1.1, nor run against...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found