I am trying to use the function EVP_PKEY_new_raw_private_key from libcrypto.so.3.
When I link with -l:libcrypot.so.3, it works.
When I try to open the same file with dlmopen+dlsym, it SEGV when the function is called.
An MWE is here:
main.c
#define _GNU_SOURCE
#include <assert.h>
#include <dlfcn.h>
#include <openssl/evp.h>
// c.f. objects/objects.pl
#define NID_X25519 1034
// some data to call new with
unsigned const char scalar[] = {
0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x10, 0x11,
0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x20, 0x21, 0x22,
0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x30, 0x31, 0x32,
};
int main(int argc, char **argv) {
int keylen = 32;
assert(keylen == sizeof(scalar));
// open the library
void *libhandle = dlmopen(LM_ID_NEWLM, "/usr/local/lib64/libcrypto.so.3",
RTLD_LAZY | RTLD_DEEPBIND | RTLD_LOCAL);
assert(libhandle != NULL);
// declare the pointer to the function
EVP_PKEY *(*dl_EVP_PKEY_new_raw_private_key)(
int type, ENGINE *e, const unsigned char *key, size_t keylen);
// load from libhandle
if ((dl_EVP_PKEY_new_raw_private_key =
dlsym(libhandle, "EVP_PKEY_new_raw_private_key")) == NULL) {
fprintf(stderr, "dlsym EVP_PKEY_new_raw_private_key: %s\n", dlerror());
}
// create a private key form it.
EVP_PKEY *skey = NULL;
printf("about to create the skey\n");
if (argc > 1) {
// this segfaults somewhere in the library
skey = dl_EVP_PKEY_new_raw_private_key(NID_X25519, NULL, scalar, keylen);
} else {
// this does not
skey = EVP_PKEY_new_raw_private_key(NID_X25519, NULL, scalar, keylen);
}
printf("created the skey\n");
assert(skey != NULL);
dlclose(libhandle);
return 0;
}
Makefile
LIBRARY_PATH=/usr/local/lib64
LIBRARY_NAME=libcrypto.so.3
all: ok fail
a.out: main.c $(LD_LIBRARY_PATH)/$(LIBRARY_NAME)
gcc main.c -ldl -L $(LD_LIBRARY_PATH) -l:$(LIBRARY_NAME)
ok: a.out
@echo sould be ok
LD_LIBRARY_PATH=$(LIBRARY_PATH) ldd ./${^}
LD_LIBRARY_PATH=$(LIBRARY_PATH) ./${^}
@echo ok
@echo
fail: a.out
@echo should segfault
LD_LIBRARY_PATH=$(LIBRARY_PATH) ldd ./${^}
LD_LIBRARY_PATH=$(LIBRARY_PATH) ./${^} dl
@echo wont be able to read this
echo
When executing make you can see that the second call, where we call the dlsymd function, SIGSEGVs. We also see, that the same libcrypto.so.3 is used.
$ make
sould be ok
LD_LIBRARY_PATH=/usr/local/lib64 ldd ./a.out
linux-vdso.so.1 (0x00007ffc0b7b9000)
libdl.so.2 => /usr/lib/libdl.so.2 (0x00007fd36def3000)
libcrypto.so.3 => /usr/local/lib64/libcrypto.so.3 (0x00007fd36dad5000)
libc.so.6 => /usr/lib/libc.so.6 (0x00007fd36d909000)
/lib64/ld-linux-x86-64.so.2 => /usr/lib64/ld-linux-x86-64.so.2 (0x00007fd36df21000)
libpthread.so.0 => /usr/lib/libpthread.so.0 (0x00007fd36d8e8000)
LD_LIBRARY_PATH=/usr/local/lib64 ./a.out
about to create the skey
created the skey
ok
should segfault
LD_LIBRARY_PATH=/usr/local/lib64 ldd ./a.out
linux-vdso.so.1 (0x00007ffc7bbac000)
libdl.so.2 => /usr/lib/libdl.so.2 (0x00007f9d68d2d000)
libcrypto.so.3 => /usr/local/lib64/libcrypto.so.3 (0x00007f9d6890f000)
libc.so.6 => /usr/lib/libc.so.6 (0x00007f9d68743000)
/lib64/ld-linux-x86-64.so.2 => /usr/lib64/ld-linux-x86-64.so.2 (0x00007f9d68d5b000)
libpthread.so.0 => /usr/lib/libpthread.so.0 (0x00007f9d68722000)
LD_LIBRARY_PATH=/usr/local/lib64 ./a.out dl
about to create the skey
make: *** [Makefile:18: fail] Segmentation fault (core dumped)
NOTES:
- It does works when using the libcrypto.so.1.1 files
- I compiled OpenSSL from here (commit f87b4c4ea67393c9269663ed40a7ea3463cc59d3) with
./Configure --api=3.0.0 no-deprecated && make -jand copied the resultinglibcrypto.so.3to/usr/local/lib64/ - When using
./Configure --api=3.0.0 no-deprecated no-threadsit all works flawlessly, which makes me think it is a problem withlibpthread+dlsym... - The stack trace of that thread seems to be (from
coredumpctl debug)
Stack trace of thread 1903409:
#0 0x00007fb6d8f8f8ec __pthread_rwlock_rdlock (/usr/lib/libpthread-2.33.so + 0xd8ec)
#1 0x00007fb6d91ba539 CRYPTO_THREAD_read_lock (/usr/local/lib64/libcrypto.so.3 + 0x210539)
#2 0x00007fb6d91a8627 ossl_lib_ctx_get_data (/usr/local/lib64/libcrypto.so.3 + 0x1fe627)
#3 0x00007fb6d91813f4 evp_generic_fetch (/usr/local/lib64/libcrypto.so.3 + 0x1d73f4)
#4 0x00007fb6d918b1c8 EVP_KEYMGMT_fetch (/usr/local/lib64/libcrypto.so.3 + 0x1e11c8)
#5 0x00007fb6d91976f9 EVP_PKEY_CTX_new_from_name (/usr/local/lib64/libcrypto.so.3 + 0x1ed6f9)
#6 0x00007fb6d9192be1 EVP_PKEY_new_raw_private_key (/usr/local/lib64/libcrypto.so.3 + 0x1e8be1)
#7 0x00005575befac2c2 n/a (/home/joel/mwe-dl-libcrypto3/a.out + 0x12c2)
#8 0x00007fb6d9447b25 __libc_start_main (libc.so.6 + 0x27b25)
#9 0x00005575befac0de n/a (/home/joel/mwe-dl-libcrypto3/a.out + 0x10de)
What Am I doing wrong? Is that a dlmopen issue or an openssl issue? (Both seems unlikely to me)