[asterisk-bugs] [JIRA] (ASTERISK-25814) Segfault on res_pjsip_refer

Sergio Medina Toledo (JIRA) noreply at issues.asterisk.org
Fri Feb 26 04:53:56 CST 2016


     [ https://issues.asterisk.org/jira/browse/ASTERISK-25814?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]

Sergio Medina Toledo updated ASTERISK-25814:
--------------------------------------------

    Description: 
Hi guys, I have a segmentation fault in a production server of asterisk 13.6, as it is production it doesn't have debug symbols or core dumps activated, looking at the kern.log it says that 
{code} "asterisk[32690]: segfault at f ip 00007f11881919bc sp 00007f11837fc740 error 6 in         res_pjsip_refer.so[7f118818e000+7000]" 
{code}
 The error 6 in the kern.log message means a write access in user mode.

So I subtract the library loaded direction "7f118818e000" to the instruction pointer "00007f11881919bc" that gives me the direction (39bc) of the bad instruction in my res_pjsip_refer.so lib

I made a objdump of the library to see the what instruction is failing and what is happening and find this asm procedure:

{code}
    39b2:       48 8b 50 40             mov    0x40(%rax),%rdx
    39b6:       48 8b 40 48             mov    0x48(%rax),%rax
    39ba:       31 c9                       xor    %ecx,%ecx
 X 39bc:       c6 04 02 00             movb   $0x0,(%rdx,%rax,1)
    39c0:       49 8b 55 48             mov    0x48(%r13),%rdx
    39c4:       49 8b 75 40             mov    0x40(%r13),%rsi
    39c8:       49 8b 3c 24             mov    (%r12),%rdi
    39cc:       e8 df ea ff ff             callq  24b0 <pjsip_parse_uri at plt>
    39d1:       48 85 c0                  test   %rax,%rax
    39d4:       49 89 c6                  mov    %rax,%r14
    39d7:       74 3e                       je     3a17 <pjsip_xfer_init_module at plt+0x1497>
{code}

As you can see in the asm code it call the pjsip_parse_uri, in the c code of the module res_pjsip_refer.so it only calls that function in one point so it was easy to found the code corresponding to that asm procedure (arround line 1013), is the next :

{code}
	/* This is done on purpose (and is safe) - it's done so that the value passed to
	 * pjsip_parse_uri is NULL terminated as required
	 */
	uri = refer_to->hvalue.ptr;
	uri[refer_to->hvalue.slen] = '\0';
{code}

The comment says that it's secure but for me doesn't seems secure, for me it is a segmentation fault so I asked myself why it isn't failing always, so looking at the code that allocated the memory of refer_to->hvalue.ptr I found that it happens in the pjsip library and that library uses a pool of memory. Thinking about it, the segmentation fault only happens when the allocated string is at the end of a page of the pool, in other cases this produces a write in a part of memory that it shouldn't but because it is allocated by the pool it doesn't happen the segfault.

I think that this can be a fix :

{code}
/* This is done on purpose (and is safe) - it's done so that the value passed to
	 * pjsip_parse_uri is NULL terminated as required
	 */
	uri = malloc(refer_to->hvalue.slen + 1);
	strncpy(uri, refer_to->hvalue.ptr, refer_to->hvalue.slen);
	uri[refer_to->hvalue.slen] = '\0';

	target = pjsip_parse_uri(rdata->tp_info.pool, uri, refer_to->hvalue.slen, 0);
	free(uri);

{code}

  was:
Hi guys, I have a segmentation fault in a production server of asterisk 13.6, as it is production it doesn't have debug symbols or core dumps activated, looking at the kern.log it says that 
{code} "asterisk[32690]: segfault at f ip 00007f11881919bc sp 00007f11837fc740 error 6 in         res_pjsip_refer.so[7f118818e000+7000]" 
{code},
 The error 6 in the kern.log message means a write access in user mode.

So I subtract the library loaded direction "7f118818e000" to the instruction pointer "00007f11881919bc" that gives me the direction (39bc) of the bad instruction in my res_pjsip_refer.so lib

I made a objdump of the library to see the what instruction is failing and what is happening and find this asm procedure:

{code}
    39b2:       48 8b 50 40             mov    0x40(%rax),%rdx
    39b6:       48 8b 40 48             mov    0x48(%rax),%rax
    39ba:       31 c9                       xor    %ecx,%ecx
 X 39bc:       c6 04 02 00             movb   $0x0,(%rdx,%rax,1)
    39c0:       49 8b 55 48             mov    0x48(%r13),%rdx
    39c4:       49 8b 75 40             mov    0x40(%r13),%rsi
    39c8:       49 8b 3c 24             mov    (%r12),%rdi
    39cc:       e8 df ea ff ff             callq  24b0 <pjsip_parse_uri at plt>
    39d1:       48 85 c0                  test   %rax,%rax
    39d4:       49 89 c6                  mov    %rax,%r14
    39d7:       74 3e                       je     3a17 <pjsip_xfer_init_module at plt+0x1497>
{code}

As you can see in the asm code it call the pjsip_parse_uri, in the c code of the module res_pjsip_refer.so it only calls that function in one point so it was easy to found the code corresponding to that asm procedure (arround line 1013), is the next :

{code}
	/* This is done on purpose (and is safe) - it's done so that the value passed to
	 * pjsip_parse_uri is NULL terminated as required
	 */
	uri = refer_to->hvalue.ptr;
	uri[refer_to->hvalue.slen] = '\0';
{code}

The comment says that it's secure but for me doesn't seems secure, for me it is a segmentation fault so I asked myself why it isn't failing always, so looking at the code that allocated the memory of refer_to->hvalue.ptr I found that it happens in the pjsip library and that library uses a pool of memory. Thinking about it, the segmentation fault only happens when the allocated string is at the end of a page of the pool, in other cases this produces a write in a part of memory that it shouldn't but because it is allocated by the pool it doesn't happen the segfault.

I think that this can be a fix :

{code}
/* This is done on purpose (and is safe) - it's done so that the value passed to
	 * pjsip_parse_uri is NULL terminated as required
	 */
	uri = malloc(refer_to->hvalue.slen + 1);
	strncpy(uri, refer_to->hvalue.ptr, refer_to->hvalue.slen);
	uri[refer_to->hvalue.slen] = '\0';

	target = pjsip_parse_uri(rdata->tp_info.pool, uri, refer_to->hvalue.slen, 0);
	free(uri);

{code}


> Segfault on res_pjsip_refer
> ---------------------------
>
>                 Key: ASTERISK-25814
>                 URL: https://issues.asterisk.org/jira/browse/ASTERISK-25814
>             Project: Asterisk
>          Issue Type: Bug
>      Security Level: None
>          Components: Resources/res_pjsip_refer
>    Affects Versions: 13.6.0
>         Environment: Linux 3.13.0-68-generic #111-Ubuntu SMP  x86_64 GNU/Linux
> Ubuntu 14.04.3 LTS
>            Reporter: Sergio Medina Toledo
>
> Hi guys, I have a segmentation fault in a production server of asterisk 13.6, as it is production it doesn't have debug symbols or core dumps activated, looking at the kern.log it says that 
> {code} "asterisk[32690]: segfault at f ip 00007f11881919bc sp 00007f11837fc740 error 6 in         res_pjsip_refer.so[7f118818e000+7000]" 
> {code}
>  The error 6 in the kern.log message means a write access in user mode.
> So I subtract the library loaded direction "7f118818e000" to the instruction pointer "00007f11881919bc" that gives me the direction (39bc) of the bad instruction in my res_pjsip_refer.so lib
> I made a objdump of the library to see the what instruction is failing and what is happening and find this asm procedure:
> {code}
>     39b2:       48 8b 50 40             mov    0x40(%rax),%rdx
>     39b6:       48 8b 40 48             mov    0x48(%rax),%rax
>     39ba:       31 c9                       xor    %ecx,%ecx
>  X 39bc:       c6 04 02 00             movb   $0x0,(%rdx,%rax,1)
>     39c0:       49 8b 55 48             mov    0x48(%r13),%rdx
>     39c4:       49 8b 75 40             mov    0x40(%r13),%rsi
>     39c8:       49 8b 3c 24             mov    (%r12),%rdi
>     39cc:       e8 df ea ff ff             callq  24b0 <pjsip_parse_uri at plt>
>     39d1:       48 85 c0                  test   %rax,%rax
>     39d4:       49 89 c6                  mov    %rax,%r14
>     39d7:       74 3e                       je     3a17 <pjsip_xfer_init_module at plt+0x1497>
> {code}
> As you can see in the asm code it call the pjsip_parse_uri, in the c code of the module res_pjsip_refer.so it only calls that function in one point so it was easy to found the code corresponding to that asm procedure (arround line 1013), is the next :
> {code}
> 	/* This is done on purpose (and is safe) - it's done so that the value passed to
> 	 * pjsip_parse_uri is NULL terminated as required
> 	 */
> 	uri = refer_to->hvalue.ptr;
> 	uri[refer_to->hvalue.slen] = '\0';
> {code}
> The comment says that it's secure but for me doesn't seems secure, for me it is a segmentation fault so I asked myself why it isn't failing always, so looking at the code that allocated the memory of refer_to->hvalue.ptr I found that it happens in the pjsip library and that library uses a pool of memory. Thinking about it, the segmentation fault only happens when the allocated string is at the end of a page of the pool, in other cases this produces a write in a part of memory that it shouldn't but because it is allocated by the pool it doesn't happen the segfault.
> I think that this can be a fix :
> {code}
> /* This is done on purpose (and is safe) - it's done so that the value passed to
> 	 * pjsip_parse_uri is NULL terminated as required
> 	 */
> 	uri = malloc(refer_to->hvalue.slen + 1);
> 	strncpy(uri, refer_to->hvalue.ptr, refer_to->hvalue.slen);
> 	uri[refer_to->hvalue.slen] = '\0';
> 	target = pjsip_parse_uri(rdata->tp_info.pool, uri, refer_to->hvalue.slen, 0);
> 	free(uri);
> {code}



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



More information about the asterisk-bugs mailing list