https://bugs.openldap.org/show_bug.cgi?id=9458
Issue ID: 9458 Summary: undefined behavior and possible crash in connection_init() Product: OpenLDAP Version: unspecified Hardware: All OS: All Status: UNCONFIRMED Severity: normal Priority: --- Component: slapd Assignee: bugs@openldap.org Reporter: grapvar@gmail.com Target Milestone: ---
ITS#9112 (Howard Chu, 2019-10-28, "cleaner error handling...") introduces the following code in
servers/slapd/connection.c`connection_init():
if( ber_sockbuf_ctrl( c->c_sb, LBER_SB_OPT_SET_NONBLOCK, c ) < 0 ) { Debug( "connection_init(%d, %s): set nonblocking failed\n", ... ); ... ber_sockbuf_free( c->c_sb ); c->c_sb = NULL; ... return NULL; }
If [Connection c] has already been initialized and "set nonblocking failed", then nullified c->c_sb crashes slapd on next connect on the same file descriptor:
Assertion failed: sb != NULL, file ../../../libraries/ liblber/sockbuf.c, line 180, function ber_sockbuf_add_io
The above is true for both 2.4 and 2.5/master branches.
For branch 2.4 this code (commit 934055a11b) additionally causes undefined behavior for uninitialized [Connection c], because of re-initialization of already initialized mutexes and cv's:
if( doinit ) { c->c_send_ldap_result = slap_send_ldap_result; ... ldap_pvt_thread_mutex_init( &c->c_mutex ); ldap_pvt_thread_mutex_init( &c->c_write1_mutex ); ldap_pvt_thread_mutex_init( &c->c_write2_mutex ); ldap_pvt_thread_cond_init( &c->c_write1_cv ); ldap_pvt_thread_cond_init( &c->c_write2_cv ); ... }