Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SIP Plugin - Failed registration causes segfault #2419

Closed
eggysplat opened this issue Nov 3, 2020 · 6 comments
Closed

SIP Plugin - Failed registration causes segfault #2419

eggysplat opened this issue Nov 3, 2020 · 6 comments

Comments

@eggysplat
Copy link

Hi,

So, not quite sure what information would be useful here but, I'm using the SIP plugin with Janus, and discovering that a registration, with invalid credentials is causing the gateway to segfault.

It seems to be depending on the response that comes from the proxy. I think I have replicated it using the SIP plugin demo page too.

I work for a VoIP communication provider myself and, the registration process that our proxy uses is as follows:

  • Send REGISTER, with just a username
  • Receive 401 Unauthorised, with a WWW-Authenticate header
  • Send REGISTER, with a response to the challenge
  • (If successful) Receive 200 OK, (If failed) Receive 401 Unauthorised, with no WWW-Authenticate header

This seems to be a pattern used by a large number of VoIP companies. It looks to be the second 401 that is causing the issue.

The stack trace that I'm getting from lldb is as follows:

frame #0: 0x0000000101f48efd libjanus_sip.0.dylib`janus_sip_sofia_callback(event=nua_r_register, status=401, phrase="Unauthorised", nua=0x0000000100f12bf0, magic=0x0000000103811c00, nh=0x0000000100f12890, hmagic=0x0000000103811c00, sip=0x00000001019a0bf8, tags=0x00000001019a1310) at janus_sip.c:0
   1   	/*! \file   janus_sip.c
   2   	 * \author Lorenzo Miniero <lorenzo@meetecho.com>
   3   	 * \copyright GNU General Public License v3
   4   	 * \brief  Janus SIP plugin
   5   	 * \details Check the \ref sip for more details.
   6   	 *
   7   	 * \ingroup plugins
(lldb) f 1
frame #1: 0x000000010504127d libsofia-sip-ua.0.dylib`nua_application_event + 443
libsofia-sip-ua.0.dylib`nua_application_event:
->  0x10504127d <+443>: addq   $0x20, %rsp
    0x105041281 <+447>: leaq   -0x38(%rbp), %rdi
    0x105041285 <+451>: callq  0x1050847e7               ; su_msg_destroy
    0x10504128a <+456>: movq   -0x40(%rbp), %rax
(lldb) f 2
frame #2: 0x0000000105085246 libsofia-sip-ua.0.dylib`su_base_port_execute_msgs + 90
libsofia-sip-ua.0.dylib`su_base_port_execute_msgs:
->  0x105085246 <+90>:  movq   %r14, %rdi
    0x105085249 <+93>:  callq  0x105084788               ; su_msg_delivery_report
    0x10508524e <+98>:  incl   %ebx
    0x105085250 <+100>: movq   %r15, -0x20(%rbp)
(lldb) f 3
frame #3: 0x0000000105085376 libsofia-sip-ua.0.dylib`su_base_port_run + 110
libsofia-sip-ua.0.dylib`su_base_port_run:
->  0x105085376 <+110>: cmpq   $0x0, (%r14)
    0x10508537a <+114>: jne    0x105085382               ; <+122>
    0x10508537c <+116>: cmpq   $0x0, (%r15)
    0x105085380 <+120>: je     0x1050853b1               ; <+169>
(lldb) f 4
frame #4: 0x0000000101f53685 libjanus_sip.0.dylib`janus_sip_sofia_thread(user_data=0x0000000103811c00) at janus_sip.c:6566:2
   6563					SIPTAG_SUPPORTED_STR("replaces"),	/* Advertise that we support the Replaces header */
   6564					SIPTAG_SUPPORTED(NULL),
   6565					TAG_NULL());
-> 6566		su_root_run(session->stack->s_root);
   6567		/* When we get here, we're done */
   6568		janus_mutex_lock(&session->stack->smutex);
   6569		nua_t *s_nua = session->stack->s_nua;

The error seems to happen between lines 5504 & 5506 of janus_sip.c (from the v0.10.7 release).

These three lines are as follows:

                                JANUS_LOG(LOG_VERB, "\t%s\n", auth);
                                /* Authenticate */
                                nua_authenticate(nh,
                                        NUTAG_AUTH(auth),
                                        TAG_END());

If I set a breakpoint on line 5504 (JANUS_LOG), the breakpoint is hit, and auth contains a valid Digest string. However, if I set a breakpoint on 5506, the application segfaults before it hits this line, with the stack trace above.

I can see this code is only executed on a status of 401, or 407 back from the proxy and I suspect the lack of WWW-Authenticate header is partly responsible for this.

As a workaround, we've put another proxy inbetween our VoIP platform and Janus, and on receipt of a 401 with no WWW-Authenticate header, we convert this to a 403 Forbidden. However, I suspect it's a problem that may plague other users with other VoIP providers.

@eggysplat
Copy link
Author

by the way, this behaviour is present when running Janus from MacOS, the details of which are above, and also get the same problem when running Janus v0.10.7 in a docker container, on Linux

@lminiero
Copy link
Member

lminiero commented Nov 3, 2020

The stack trace is unfortunately useless: su_root_run is the Sofia stack main loop, so all it tells us is that it crashes within the Sofia stack while it's handling its own events. As such, I don't think it's a bug in Janus, but in Sofia SIP itself.

@eggysplat
Copy link
Author

Ah, that's unfortunate. sofia-sip looks to be an abandoned project. I've installed that, as per the documentation from the janus build instructions and homebrew poured version v1.12.11. Looks like the last release of sofia-sip was 1.12.11 back in March '11.

@lminiero
Copy link
Member

lminiero commented Nov 3, 2020

Actually scratch that, I managed to replicate this with SIPp as a fake registrar, which gave me this libasan output:

==26420==ERROR: AddressSanitizer: SEGV on unknown address 0x000000000030 (pc 0x7fe8422a0555 bp 0x7fe83d330240 sp 0x7fe83d327e60 T54)
==26420==The signal is caused by a READ memory access.
==26420==Hint: address points to the zero page.
    #0 0x7fe8422a0555 in janus_sip_sofia_callback plugins/janus_sip.c:5482

This definitely is us doing something wrong, as that line is

				if(status == 401) {
					/* Get scheme/realm from 401 error */
					sip_www_authenticate_t const* www_auth = sip->sip_www_authenticate;
-->					scheme = www_auth->au_scheme;
					realm = msg_params_find(www_auth->au_params, "realm=");
				} else {

We're giving for granted that www_auth is not NULL, which it is here. I'll work on a fix shortly, thanks for spitting this!

@lminiero
Copy link
Member

lminiero commented Nov 3, 2020

The above commit fixes it for me, please let me know if it works for you too.

@eggysplat
Copy link
Author

Stunned at how quick the turnaround on this was.

Deployed master into our staging environment now, which is working perfectly. We'll pick up the v0.10.8 when it's tagged, so that we get the stable release.

Thanks @lminiero for fixing this so quickly.

PauKerr pushed a commit to caffeinetv/janus-gateway that referenced this issue Nov 11, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants