res_pjsip: Copy default_from_user to avoid crash.
authorMark Michelson <mmichelson@digium.com>
Thu, 10 Sep 2015 14:49:45 +0000 (09:49 -0500)
committerMark Michelson <mmichelson@digium.com>
Thu, 10 Sep 2015 14:55:00 +0000 (09:55 -0500)
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

include/asterisk/res_pjsip.h
res/res_pjsip.c
res/res_pjsip/config_global.c

index b7b875d..29edbd2 100644 (file)
@@ -2025,9 +2025,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()                            \
index 4af886b..3e93b6f 100644 (file)
@@ -2338,9 +2338,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 */
index b348896..ef706f0 100644 (file)
@@ -182,20 +182,17 @@ unsigned int ast_sip_get_max_initial_qualify_time(void)
        return time;
 }
 
-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;
 }
 
 /*!