null-pointer dereference when using `OTRL_INSTAG_RECENT` with `otrl_message_sending`
There is a null-pointer dereference bug in libotr 4.0.0 that is triggered by using OTRL_INSTAG_RECENT with otrl_message_sending. When a new OTR context is created via the add_context part in otrl_message_sending, the recent_child field is not set. On the next message otrl_message_sending crashes because even though there is a context, otrl_context_find returns NULL.
The following (untested) patch lets otrl_context_find_recent_instance default to returning the master context when recent_child or one of its friends is not set.
--- a/src/context.c +++ b/src/context.c @@ -168,6 +168,7 @@ static ConnContext * new_context(const char * user, const char * accountname, ConnContext * otrl_context_find_recent_instance(ConnContext * context, otrl_instag_t recent_instag) { ConnContext * m_context; + ConnContext * recent_child; if (!context) return NULL; @@ -177,14 +178,19 @@ ConnContext * otrl_context_find_recent_instance(ConnContext * context, switch(recent_instag) { case OTRL_INSTAG_RECENT: - return m_context->recent_child; + recent_child = m_context->recent_child; case OTRL_INSTAG_RECENT_RECEIVED: - return m_context->recent_rcvd_child; + recent_child = m_context->recent_rcvd_child; case OTRL_INSTAG_RECENT_SENT: - return m_context->recent_sent_child; + recent_child = m_context->recent_sent_child; default: - return NULL; + recent_child = NULL; } + + if(recent_child) + return recent_child; + else + return m_context; /* default to master context */ }
/* Find the instance of this context that has the best security level,
After that, one might also consider removing the "dummy" initialization of recent_child et al. when using OTRL_INSTAG_MASTER, though I am not really sure what is intended.
--- a/src/context.c +++ b/src/context.c @@ -334,14 +334,6 @@ ConnContext * otrl_context_find(OtrlUserState us, const char *user, protocol, OTRL_INSTAG_MASTER, 1, NULL, add_app_data, data); } - if (their_instance == OTRL_INSTAG_MASTER) { - /* if we're adding a master, there are no children, so the most - * recent context is the one we add. */ - newctx->recent_child = newctx; - newctx->recent_rcvd_child = newctx; - newctx->recent_sent_child = newctx; - } - return *curp; } return NULL;
Cf. also: http://bugs.bitlbee.org/bitlbee/ticket/1110#comment:9
(original: http://sourceforge.net/p/otr/bugs/25/)
(from redmine: created on 2014-04-18)