From: Mark Michelson Date: Thu, 10 Sep 2015 14:49:45 +0000 (-0500) Subject: res_pjsip: Copy default_from_user to avoid crash. X-Git-Tag: certified/13.1-cert3~74 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=8826e6c416ce1b97b4e85e06913df65cb84dade5;p=thirdparty%2Fasterisk.git res_pjsip: Copy default_from_user to avoid crash. The default_from_user retrieval function was pulling the default_from_user from the global configuration struct in an unsafe way. If using a database as a backend configuration store, the global configuration struct is short-lived, so grabbing a pointer from it results in referencing freed memory. The fix here is to copy the default_from_user value out of the global configuration struct. Thanks go to John Hardin for discovering this problem and proposing the patch on which this fix is based. ASTERISK-25390 #close Reported by Mark Michelson Change-Id: I6b96067a495c1259da768f4012d44e03e7c6148c --- diff --git a/include/asterisk/res_pjsip.h b/include/asterisk/res_pjsip.h index c216287fbf..9760dad24d 100644 --- a/include/asterisk/res_pjsip.h +++ b/include/asterisk/res_pjsip.h @@ -2051,9 +2051,11 @@ char *ast_sip_get_endpoint_identifier_order(void); * is no better option (such as an endpoint-configured from_user or * caller ID number). * - * \retval The global default_from_user value. + * \param[out] from_user The default from user + * \param size The buffer size of from_user + * \return nothing */ -const char *ast_sip_get_default_from_user(void); +void ast_sip_get_default_from_user(char *from_user, size_t size); /*! \brief Determines whether the res_pjsip module is loaded */ #define CHECK_PJSIP_MODULE_LOADED() \ diff --git a/res/res_pjsip.c b/res/res_pjsip.c index 9726de922d..10e0163ffd 100644 --- a/res/res_pjsip.c +++ b/res/res_pjsip.c @@ -2191,9 +2191,11 @@ static int sip_dialog_create_from(pj_pool_t *pool, pj_str_t *from, const char *u pjsip_sip_uri *sip_uri; pjsip_transport_type_e type = PJSIP_TRANSPORT_UNSPECIFIED; int local_port; + char default_user[PJSIP_MAX_URL_SIZE]; if (ast_strlen_zero(user)) { - user = ast_sip_get_default_from_user(); + ast_sip_get_default_from_user(default_user, sizeof(default_user)); + user = default_user; } /* Parse the provided target URI so we can determine what transport it will end up using */ diff --git a/res/res_pjsip/config_global.c b/res/res_pjsip/config_global.c index bde9cc44ce..c829afab6c 100644 --- a/res/res_pjsip/config_global.c +++ b/res/res_pjsip/config_global.c @@ -152,20 +152,17 @@ unsigned int ast_sip_get_keep_alive_interval(void) return interval; } -const char *ast_sip_get_default_from_user(void) +void ast_sip_get_default_from_user(char *from_user, size_t size) { - const char *from_user; struct global_config *cfg; cfg = get_global_cfg(); if (!cfg) { - return DEFAULT_FROM_USER; + ast_copy_string(from_user, DEFAULT_FROM_USER, size); + } else { + ast_copy_string(from_user, cfg->default_from_user, size); + ao2_ref(cfg, -1); } - - from_user = cfg->default_from_user; - ao2_ref(cfg, -1); - - return from_user; } int ast_sip_initialize_sorcery_global(void)