[asterisk-bugs] [JIRA] (ASTERISK-28936) pjsip crash when using non-sip uri

Walter Doekes (JIRA) noreply at issues.asterisk.org
Fri Jun 5 04:02:25 CDT 2020


Walter Doekes created ASTERISK-28936:
----------------------------------------

             Summary: pjsip crash when using non-sip uri
                 Key: ASTERISK-28936
                 URL: https://issues.asterisk.org/jira/browse/ASTERISK-28936
             Project: Asterisk
          Issue Type: Bug
      Security Level: None
          Components: Resources/res_pjsip
    Affects Versions: 13.33.0
            Reporter: Walter Doekes


{noformat}
*CLI> channel originate PJSIP/bob/tel:123 application Wait
Segmentation fault
{noformat}
(Note that this does not always crash, because it depends on reading out-of-bounds mem.)

BT:
{noformat}
(gdb) bt
#0  __strncasecmp_l_avx () at ../sysdeps/x86_64/multiarch/strcmp-sse42.S:198
#1  0x00007ffff78e7c37 in pj_stricmp (str1=str1 at entry=0x7fff88009228, str2=str2 at entry=0x7fffa158b7f0 <x_name>) at ../include/pj/string_i.h:222
#2  0x00007ffff784fdbd in pjsip_param_find (param_list=param_list at entry=0x7fff88009210, name=name at entry=0x7fffa158b7f0 <x_name>) at ../src/pjsip/sip_uri.c:38
#3  0x00007fffa134bac3 in ast_sip_get_transport_name (endpoint=endpoint at entry=0x555555dde150, sip_uri=0x7fff88009188, buf=buf at entry=0x7fff9e842700 "", buf_len=buf_len at entry=128) at res_pjsip.c:3102
#4  0x00007fffa134bbcf in ast_sip_set_tpselector_from_ep_or_uri (endpoint=endpoint at entry=0x555555dde150, sip_uri=<optimized out>, selector=selector at entry=0x7fff9e842830) at res_pjsip.c:3272
#5  0x00007fffa134bc5c in ast_sip_dlg_set_transport (endpoint=endpoint at entry=0x555555dde150, dlg=0x7fff88008c38, selector=selector at entry=0x7fff9e842830) at res_pjsip.c:3130
#6  0x00007fffa134bdfd in ast_sip_create_dialog_uac (endpoint=endpoint at entry=0x555555dde150, uri=uri at entry=0x7fff9e842ba4 "tekl:123 at bob", request_user=request_user at entry=0x0) at res_pjsip.c:3347
{noformat}
{noformat}
(gdb) up
#1  0x00007ffff78e7c37 in pj_stricmp (str1=str1 at entry=0x7fff88009228, str2=str2 at entry=0x7fffa158b7f0 <x_name>) at ../include/pj/string_i.h:222
222		int res = pj_ansi_strnicmp(str1->ptr, str2->ptr, min);
(gdb) print *str1
$1 = {ptr = 0x13 <error: Cannot access memory at address 0x13>, slen = 140737346742117}
{noformat}
The problem is in {{ast_sip_dlg_set_transport()}}. It assumes that the dlg->target is a {{pjsip_sip_uri}}, while it can also be a {{pjsip_other_uri}}:
{code}
pjsip_dialog *ast_sip_create_dialog_uac(const struct ast_sip_endpoint *endpoint,
        const char *uri, const char *request_user)
{
...
        res = pjsip_dlg_create_uac(pjsip_ua_instance(), &local_uri, NULL, &remote_uri, &target_uri, &dlg);
...

        /* We have to temporarily bump up the sess_count here so the dialog is not prematurely destroyed */
        dlg->sess_count++;

        ast_sip_dlg_set_transport(endpoint, dlg, &selector);

        if (sip_dialog_create_from(dlg->pool, &local_uri, endpoint->fromuser, endpoint->fromdomain, &remote_uri, &selector)) {
{code}
And:
{code}
int ast_sip_dlg_set_transport(const struct ast_sip_endpoint *endpoint, pjsip_dialog *dlg,
        pjsip_tpselector *selector)
{
        pjsip_sip_uri *uri;
        pjsip_tpselector sel = { .type = PJSIP_TPSELECTOR_NONE, };

        uri = pjsip_uri_get_uri(dlg->target);  // <-- invalid "dynamic" cast to pjsip_sip_uri
{code}
{{pjsip_dlg_create_uac()}} will initialize {{dlg->target}}, but it's not guaranteed to be a pjsip_sip_uri.

After the cast in {{ast_sip_dlg_set_transport}}, {{ast_sip_set_tpselector_from_ep_or_uri}} reads out of bounds memory. (Memory that a pjsip_sip_uri would own, but a pjsip_other_uri does not.)

Result: crash.

Possible fix:
{noformat}
--- a/res/res_pjsip.c
+++ b/res/res_pjsip.c
@@ -3327,6 +3327,11 @@ pjsip_dialog *ast_sip_create_dialog_uac(const struct ast_sip_endpoint *endpoint,
        pj_cstr(&target_uri, uri);
 
        res = pjsip_dlg_create_uac(pjsip_ua_instance(), &local_uri, NULL, &remote_uri, &target_uri, &dlg);
+       if (res == PJ_SUCCESS && (!PJSIP_URI_SCHEME_IS_SIP(dlg->target) && !PJSIP_URI_SCHEME_IS_SIPS(dlg->target))) {
+               /* dlg->target is not a pjsip_sip_uri but a pjsip_other_uri;
+                * but we don't expect those below. Fail now. */
+               res = PJSIP_EINVALIDURI;
+       }
        if (res != PJ_SUCCESS) {
                if (res == PJSIP_EINVALIDURI) {
                        ast_log(LOG_ERROR,
{noformat}
^- I'll put this on gerrit



--
This message was sent by Atlassian JIRA
(v6.2#6252)



More information about the asterisk-bugs mailing list