Исправление ошибок динамического компоновщика при использовании libc с openssl
Вот простой hello world sha1-hasher, использующий библиотеку openssl.
#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);
}
На Mint/Ubuntu с установленным libssl-dev я могу скомпилировать и связать его с $CC sha.c
(где CC это один из gcc, tcc или clang) и затем успешно запустил его, но это не сработало с musl, поэтому я взял исходный код openssl (git clone https://github.com/openssl/openssl
), настроил его с ./config --prefix=/usr/local/musl
, построил и установил и сейчас musl-gcc sha.c -lcrypto works
но работает LD_LIBRARY_PATH=/usr/local/musl/lib a.out
получает меня:
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
Что вызывает это и как я могу это исправить?
1 ответ
Кажется, что ваш OpenSSL не создан против musl-libc .
У musl-libc есть собственный динамический компоновщик (см. https://wiki.musl-libc.org/faq.html), мы могли бы создать программную ссылку для динамического компоновщика musl. (-syslibdir
это каталог, в котором находится динамическая библиотека, напримерld-musl-x86_64.so.1
, см. 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
Тогда вы могли бы увидеть, построен ли openssl против musl-libc. Когда я создаю OpenSSL с помощью glibc, он показывает следующую ошибку
$ 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
И glib динамический компоновщик работает нормально,
$ 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)
Чтобы собрать OpenSSL с использованием musl-libc, мы также должны указать расположение заголовков linux, чтобы избежать таких ошибок, как<linux/mman.h>
Я только пытался собрать OpenSSL, используя Clang и Musl-libc, вот обертка clang, которую я использовал https://gist.github.com/randoruf/d1aa4e8acb0a852addcd2b84fc003719.
(взято с https://qiita.com/kakinaguru_zo/items/399ab7ea716a56aef50c , написанного kakinaguru_zo)
Но в clang-wrapper все еще есть несколько проблем .
Эта оболочка свяжет начальный файл (e.g. Scrt1.o
) независимо от сборки библиотек или исполняемых файлов. Судя по всему, startfile нужен только исполняемым файлам. Следовательно, если вы используете эту оболочку, вы можете столкнуться со следующей странной ошибкой (символ не найден):
$ 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
Если в библиотеке есть начальный файл, в нем может быть запись в . Это причина, по которойmain
символ не найден.
Решение состоит в том, чтобы не включать startfile для разделяемых библиотек (новая оболочка clang должна решить проблему).
Другая проблема заключается в том, чтоtest_errstr
,test_ca
,test_ssl_new
не пройдет из-за того, что операционная система и ее ПО построены против glibc.
Подробности размещены в моем блоге https://randoruf.github.io/2022/08/23/musl-libc-ubuntu.html#about-the-test-case-in-openssl
Последняя проблема заключается в том, что эта оболочка поддерживает только язык c. Может быть полезна другая оболочка, см. https://github.com/esjeon/musl-clang/blob/master/musl-clang .