[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