https://bugs.openldap.org/show_bug.cgi?id=9650
Issue ID: 9650 Summary: lloadd segfault on startup on systems using musl Product: OpenLDAP Version: unspecified Hardware: All OS: Linux Status: UNCONFIRMED Severity: normal Priority: --- Component: lloadd Assignee: bugs@openldap.org Reporter: git@freundtech.com Target Milestone: ---
I came across this problem while testing a fix for #9648. It seems to be unrelated, so I'm creating a separate issue.
After compiling OpenLDAP 2.5.7 with the fix from #9648 and ----enable-balancer=yes on an Alpine Linux system lloadd segfaults on startup. The backtrace from a debug build is
#0 0x00007ffff7fba852 in tss_get () from /lib/ld-musl-x86_64.so.1 #1 0x00005555555a844d in ldap_pvt_thread_key_getdata (key=0, data=0x7fffffffe820) at thr_posix.c:360 #2 0x00005555555a7f9f in ldap_pvt_thread_pool_context () at tpool.c:1442 #3 0x0000555555583122 in slap_sl_context (ptr=0x7ffff7f606e0) at sl_malloc.c:673 #4 0x0000555555580709 in ch_realloc (block=0x7ffff7f606e0, size=24) at ch_malloc.c:81 #5 0x0000555555572303 in lload_open_listener (url=0x7ffff7c43c30 "ldap:///", lud=0x7ffff7f60550, listeners=0x7fffffffeb1c, cur=0x7fffffffeb20) at daemon.c:465 #6 0x00005555555733bf in lloadd_listeners_init (urls=0x5555555d1958 "ldap:///") at daemon.c:749 #7 0x000055555557f7a9 in main (argc=1, argv=0x7fffffffed08) at main.c:632
The problem seems to be that ldap_pvt_thread_pool_context in tpool.c is called before ldap_int_thread_pool_startup in tpool.c is called.
ldap_int_thread_pool_startup calls ldap_pvt_thread_key_create, which on posix calls pthread_key_create. ldap_pvt_thread_pool_context calls ldap_pvt_thread_key_getdata, which on posix calls pthread_getspecific. If ldap_int_thread_pool_startup wasn't called pthread_getspecific gets passed an uninitialized key, which is always 0 (because the variable is static).
According to man 3 pthread_getspecific "The effect of calling pthread_getspecific() or pthread_setspecific() with a key value not obtained from pthread_key_create() or after key has been deleted with pthread_key_delete() is undefined."
This seems to work fine on glibc, but crash on musl.