Here's a simple hello world sha1-hasher that's using the openssl library.
#include <openssl/sha.h>
#include <stdio.h>
#include <stdlib.h>
int main()
{
system("printf '%s' 'hello world' | sha1sum");
unsigned char digest[SHA_DIGEST_LENGTH];
char digest_pr[(SHA_DIGEST_LENGTH)*2+1];
SHA_CTX ctx;
if(!SHA1_Init(&ctx)) return 1;
#define STR_STRLEN(A) A, (sizeof(A)/sizeof(*(A))-1)
if(!SHA1_Update(&ctx,STR_STRLEN("hello"))) return EXIT_FAILURE;
if(!SHA1_Update(&ctx,STR_STRLEN(" world"))) return EXIT_FAILURE;
if(!SHA1_Final(digest,&ctx)) return EXIT_FAILURE;
#define DIGITS "0123456789abcdef"
for(size_t i=0;i<sizeof(digest);i++){
digest_pr[i*2+0]=DIGITS[digest[i]/16];
digest_pr[i*2+1]=DIGITS[digest[i]%16];
}
digest_pr[(SHA_DIGEST_LENGTH)*2]='\0';
puts(digest_pr);
}
On a Mint/Ubuntu with libssl-dev installed, I can compile and link it with $CC sha.c
(where CC is one of gcc, tcc, or clang) and then successfully run it, but this didn't work with musl so I grabbed the openssl source (git clone https://github.com/openssl/openssl
), configured it with ./config --prefix=/usr/local/musl
, built it and installed it and now musl-gcc sha.c -lcrypto works
but running LD_LIBRARY_PATH=/usr/local/musl/lib a.out
gets me:
Error relocating /usr/local/musl/lib/libcrypto.so.1.1: __fprintf_chk: symbol not found
Error relocating /usr/local/musl/lib/libcrypto.so.1.1: makecontext: symbol not found
Error relocating /usr/local/musl/lib/libcrypto.so.1.1: setcontext: symbol not found
Error relocating /usr/local/musl/lib/libcrypto.so.1.1: __register_atfork: symbol not found
Error relocating /usr/local/musl/lib/libcrypto.so.1.1: __memcpy_chk: symbol not found
Error relocating /usr/local/musl/lib/libcrypto.so.1.1: __strcat_chk: symbol not found
Error relocating /usr/local/musl/lib/libcrypto.so.1.1: secure_getenv: symbol not found
Error relocating /usr/local/musl/lib/libcrypto.so.1.1: __vfprintf_chk: symbol not found
Error relocating /usr/local/musl/lib/libcrypto.so.1.1: __syslog_chk: symbol not found
Error relocating /usr/local/musl/lib/libcrypto.so.1.1: __memset_chk: symbol not found
Error relocating /usr/local/musl/lib/libcrypto.so.1.1: __fread_chk: symbol not found
Error relocating /usr/local/musl/lib/libcrypto.so.1.1: getcontext: symbol not found
Error relocating /usr/local/musl/lib/libcrypto.so.1.1: __sprintf_chk: symbol not found
What's causing this and how can I fix it?
It seems that your OpenSSL is not built against musl-libc.
The musl-libc has its own dynamic linker (see https://wiki.musl-libc.org/faq.html), we could create a soft link for the musl dynamic linker. (-syslibdir
is the directory in which the dynamic library, e.g. ld-musl-x86_64.so.1
, is, see https://wiki.musl-libc.org/getting-started.html)
sudo ln -sf <YOUR-MUSL-LIBC-syslibdir/ld-musl-x86_64.so.1> /usr/bin/musl-ldd
Then you could see whether openssl is built against musl-libc. When I build OpenSSL using glibc, it shows the following error
$ musl-ldd <YOUR-OPENSSL-SRC>/libcrypto.so.1.1
musl-ldd (0x7fcd5a749000)
libdl.so.2 => musl-ldd (0x7fcd5a749000)
libpthread.so.0 => musl-ldd (0x7fcd5a749000)
libc.so.6 => musl-ldd (0x7fcd5a749000)
Error relocating ./libcrypto.so.1.1: makecontext: symbol not found
Error relocating ./libcrypto.so.1.1: setcontext: symbol not found
Error relocating ./libcrypto.so.1.1: __register_atfork: symbol not found
Error relocating ./libcrypto.so.1.1: getcontext: symbol not found
And the glib dynamic linker works fine,
$ ldd <YOUR-OPENSSL-SRC>/libcrypto.so.1.1
linux-vdso.so.1 (0x00007ffd395a6000)
libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007ff6e6e64000)
libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007ff6e6e41000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007ff6e6c4f000)
/lib64/ld-linux-x86-64.so.2 (0x00007ff6e71d7000)
To build OpenSSL using musl-libc, we have to also specify the location of linux headers to avoid errors like <linux/mman.h>
I only have attempted to build OpenSSL using Clang and Musl-libc, here is the clang wrapper I used https://gist.github.com/randoruf/d1aa4e8acb0a852addcd2b84fc003719.
(taken from https://qiita.com/kakinaguru_zo/items/399ab7ea716a56aef50c which is written by kakinaguru_zo)
But there are still a few issues in the clang-wrapper.
This wrapper will link the startfile (e.g. Scrt1.o
) regardless of building libraries or executables. Apparently, only executables need startfile. Hence, if you use this wrapper, you may encounter the following strange error (main
symbol not found):
$ musl-clang mylibrary.c -shared -fPIC -o libmylibrary.so
$ musl-ldd libmylibrary.so
ld-musl-x86_64.so.1 (0x7f49faef7000)
libc.so => ld-musl-x86_64.so.1 (0x7f49faef7000)
Error relocating libmylibrary.so: main: symbol not found
If the library has the startfile, it may have an entry to main
. This is the reason why the main
symbol is not found.
The solution is not to include startfile for shared libraries (the new clang wrapper should fix the problem).
Another issue is that test_errstr
, test_ca
, test_ssl_new
will not pass due to the fact that the operating system and its software are built against glibc.
Details are posted on my blog https://randoruf.github.io/2022/08/23/musl-libc-ubuntu.html#about-the-test-case-in-openssl
The final issue is that this wrapper only supports c language. Another wrapper may be helpful see https://github.com/esjeon/musl-clang/blob/master/musl-clang