[Libwebsockets] Double freeing causes crashing??

Duy Lan Nguyen ndlan2k at gmail.com
Wed Nov 18 07:19:13 CET 2015


I've just tested the proxy basic authentication but it doesn't seem to work.

The error from squid3 proxy's log is
"192.168.137.1 TCP_DENIED/407 3731 CONNECT 192.168.137.1:443
%cc%cc%cc%cc%cc%cctest1 HIER_NONE/- text/html"

The user name is supposed to be test1, so there seem to be some bytes "%cc"
preceding it (you can see that character at
http://www.degraeve.com/reference/urlencoding.php).

In using lws, I set the proxy in this string "
test1:password at 192.168.137.106:3128". And I use wss.

I set up squid3's proxy basic authentication following this instruction
http://stackoverflow.com/questions/3297196/how-to-set-up-a-squid-proxy-with-basic-username-and-password-authentication,
and it works using Chrome browser via the proxy and user name and password
as above.

Thanks,
Lan


On Sat, Nov 7, 2015 at 6:28 PM, Andy Green <andy at warmcat.com> wrote:

>
>
> On 8 November 2015 09:26:55 GMT+08:00, Andy Green <andy at warmcat.com>
> wrote:
> >
> >
> >On 7 November 2015 14:46:49 GMT+08:00, Duy Lan Nguyen
> ><ndlan2k at gmail.com> wrote:
> >>Awesome, mine is older than that.
> >>
> >>It seems to me that lws has supported proxy, but not yet proxy
> >>authentication using user name and password. Do you plan to support
> >>that in
> >>a near future?
> >
> >Depends what you mean... according to this
> >
> >https://wiki.archlinux.org/index.php/Proxy_settings
> >
> >You can just stick your auth details behind the proxy url
> >
> >echo -n "username: "; read username
> >if [[ $username != "" ]]; then
> >   echo -n "password: "
> >   read -es password
> >   local pre="$username:$password@"
> >fi
> >
> >export http_proxy="http://$pre$server:$port/"
> >export https_proxy=$http_proxy
> >...
> >
> >There are other kinds of proxy auth like http basic auth you can add in
> >user code.
>
> I pushed a patch to support the user:pw@ syntax and send the header with
> a base64 version of it on proxy connect.  I tested the parsing but the
> header part is untested since no suitable proxy here.
>
> Please let me know how it goes.
>
> -Andy
>
> >-Andy
> >
> >
> >>Thanks,
> >>Lan
> >>
> >>
> >>On Fri, Nov 6, 2015 at 3:40 PM, Andy Green <andy at warmcat.com> wrote:
> >>
> >>>
> >>>
> >>> On 6 November 2015 16:51:29 GMT+08:00, Duy Lan Nguyen
> >><ndlan2k at gmail.com>
> >>> wrote:
> >>> >Sorry, it was due to referring to already freed memory, not double
> >>> >freeing.
> >>> >I can point to where it happens.
> >>> >At line 300,
> >>> >
> >>>
> >>
> http://git.libwebsockets.org/cgi-bin/cgit/libwebsockets/tree/lib/client-handshake.c#n300
> >>> ,
> >>> >wsi is freed by lws_free(wsi) (in function
> >>> >libwebsocket_client_connect_2,
> >>> >called by lws_client_socket_service, called by
> >>libwebsocket_service_fd
> >>> ><=
> >>> >lws_plat_service <= libwebsocket_service).
> >>> >But that wsi memory is referred to again at
> >>> >
> >>>
> >>
> http://git.libwebsockets.org/cgi-bin/cgit/libwebsockets/tree/lib/lws-plat-win.c#n45
> >>> >(in function wsi_from_fd, called by libwebsocket_context_destroy).
> >>> >
> >>> >Do you think it is the problem? I can fix it by assigning wsi=NULL
> >>> >after
> >>> >freeing and checking if wsi!=NULL before referring to its memory,
> >>then
> >>> >git-pushing the change. Is that ok?
> >>>
> >>> No that has a slightly deeper cause, which is we errored out of
> >>client
> >>> connection init, but didn't take care to remove the connection from
> >>the fd
> >>> list on that path.  However that was fixed a while ago
> >>>
> >>>
> >>>
> >>
> http://git.libwebsockets.org/cgi-bin/cgit/libwebsockets/commit/?id=b5cf69fdb57c4025572cde1007e0ff16108d4f80
> >>>
> >>> How old is your lws?
> >>>
> >>> -Andy
> >>>
> >>> >Besides, in the code as follows, I waited for the thread of
> >>> >libwebsocket_service loop to stop before calling
> >>> >libwebsocket_context_destroy(). So I think the crash may happen
> >even
> >>> >without threading.
> >>> >if (pVeraSocket)
> >>> >{
> >>> >if (pVeraSocket->m_hThreadService && pVeraContext &&
> >>> >pVeraContext->m_pVeraSocketInfo)
> >>> >{
> >>> >pVeraContext->m_pVeraSocketInfo->m_ConnInfo.m_fConnClosed = TRUE;
> >>> >
> >>> >WaitForSingleObject(pVeraSocket->m_hThreadService, INFINITE);
> >>> >CloseHandle(pVeraSocket->m_hThreadService);
> >>> >pVeraSocket->m_hThreadService = NULL;
> >>> >pVeraSocket->m_dwThreadServiceId = 0;
> >>> >}
> >>> >...
> >>> >}
> >>> >
> >>> >if (pVeraContext)
> >>> >                {
> >>> >s_rgppVeraSocketInfo[pVeraContext->m_nConnTicket] = NULL;
> >>> >    if (pVeraContext->m_pContext)
> >>> >{
> >>> >libwebsocket_context_destroy(pVeraContext->m_pContext);
> >>> >pVeraContext->m_pContext = NULL;
> >>> >}
> >>> >                }
> >>> >
> >>> >I have a further question. I was trying to develop based on the
> >>> >following
> >>> >description of libwebsocket_service() at
> >>> >https://libwebsockets.org/libwebsockets-api-doc.html. If I don't
> >>> >interpret
> >>> >it incorrectly, it means I could create another thread for the
> >>> >libwebsocket_service() loop so that it doesn't block the main
> >>thread,
> >>> >which
> >>> >can do other stuff. So how should I interpret this description?
> >>> >"*int* *libwebsocket_service* (*struct libwebsocket_context **
> >>> >*context*,
> >>> >*int* *timeout_ms*)
> >>> >...Description
> >>> >
> >>> >This function deals with any pending websocket traffic, for three
> >>kinds
> >>> >of
> >>> >event. It handles these events on both server and client types of
> >>> >connection the same.
> >>> >
> >>> >1) Accept new connections to our context's server
> >>> >
> >>> >2) Call the receive callback for incoming frame data received by
> >>server
> >>> >or
> >>> >client connections.
> >>> >
> >>> >You need to call this service function periodically to all the
> >above
> >>> >functions to happen; if your application is single-threaded you can
> >>> >just
> >>> >call it in your main event loop.
> >>> >
> >>> >Alternatively you can fork a new process that asynchronously
> >handles
> >>> >calling this service in a loop. In that case you are happy if this
> >>call
> >>> >blocks your thread until it needs to take care of something and
> >>would
> >>> >call
> >>> >it with a large nonzero timeout. Your loop then takes no CPU while
> >>> >there is
> >>> >nothing happening.
> >>> >
> >>> >If you are calling it in a single-threaded app, you don't want it
> >to
> >>> >wait
> >>> >around blocking other things in your loop from happening, so you
> >>would
> >>> >call
> >>> >it with a timeout_ms of 0, so it returns immediately if nothing is
> >>> >pending,
> >>> >or as soon as it services whatever was pending."
> >>> >
> >>> >Thanks,
> >>> >Lan
> >>> >
> >>> >
> >>> >
> >>> >On Wed, Nov 4, 2015 at 7:16 PM, Andy Green <andy at warmcat.com>
> >wrote:
> >>> >
> >>> >>
> >>> >>
> >>> >> On 5 November 2015 09:52:11 GMT+08:00, Duy Lan Nguyen
> >>> ><ndlan2k at gmail.com>
> >>> >> wrote:
> >>> >> >Hi Andy and Anyone-who-can-help,
> >>> >> >
> >>> >> >We have a situation of double freeing and crashing here and
> >>wonder
> >>> >if
> >>> >> >anyone can help.
> >>> >>
> >>> >> Maybe someone else can help.
> >>> >>
> >>> >> I don't have windows, and lws doesn't have threads.
> >>> >>
> >>> >> If you can make a patch that does the minimum to lws-test-server
> >>to
> >>> >make
> >>> >> the problem come on Linux, I'll study it.  But the answer is
> >>likely
> >>> >in your
> >>> >> threading additions outside of lws.
> >>> >>
> >>> >> -Andy
> >>> >>
> >>> >> >We use lws as follows, with highlights
> >>> >> >
> >>> >> >We have a connection function VeraConnect that calls
> >>> >> >libwebsocket_create_context and libwebsocket_client_connect, and
> >>> >> >creates
> >>> >> >another thread PollService for the polling service
> >>> >> >libwebsocket_service. If
> >>> >> >VeraConnect fails, it will clean up by stopping the thread
> >>> >PollService
> >>> >> >and
> >>> >> >calling libwebsocket_context_destroy. The functions VeraConnect
> >>and
> >>> >> >PollService are summarized as below.
> >>> >> >
> >>> >> >...
> >>> >> >VeraConnect(...)
> >>> >> >{
> >>> >> >....
> >>> >> >  if (!pVeraContext->m_pContext)
> >>> >> >    {
> >>> >> >        pVeraContext->m_pContext = libwebsocket_create_context
> >>> >> >(pVeraContext->m_pInfo);
> >>> >> >        if (!pVeraContext->m_pContext) {
> >>> >> >            ret = VERA_FAIL;
> >>> >> >            goto exit;
> >>> >> >        }
> >>> >> >    }
> >>> >> >
> >>> >> >pVeraSocket->m_pWSI =
> >>> >> >libwebsocket_client_connect(pVeraContext->m_pContext,
> >>> >> >...);
> >>> >> >
> >>> >> >    if (!pVeraSocket->m_pWSI) {
> >>> >> >        ret = VERA_FAIL;
> >>> >> >        goto exit;
> >>> >> >    }
> >>> >> >
> >>> >> >  pVeraContext->m_pVeraSocketInfo->m_ConnInfo.m_fConnClosed =
> >>FALSE;
> >>> >> >
> >>> >> >  pVeraSocket->m_hThreadService = CreateThread(
> >>> >> >...
> >>> >> >        PollService,       // thread function name
> >>> >> >        pVeraContext,          // argument to thread function
> >>> >> >...);   // returns the thread identifier
> >>> >> >
> >>> >> >exit:
> >>> >> >  if (ret != VERA_OK)
> >>> >> >    {
> >>> >> >if (pVeraSocket)
> >>> >> >{
> >>> >> >if (pVeraSocket->m_hThreadService && pVeraContext &&
> >>> >> >pVeraContext->m_pVeraSocketInfo)
> >>> >> >{
> >>> >> >pVeraContext->m_pVeraSocketInfo->m_ConnInfo.m_fConnClosed =
> >TRUE;
> >>> >> >
> >>> >> >WaitForSingleObject(pVeraSocket->m_hThreadService, INFINITE);
> >>> >> >CloseHandle(pVeraSocket->m_hThreadService);
> >>> >> >pVeraSocket->m_hThreadService = NULL;
> >>> >> >pVeraSocket->m_dwThreadServiceId = 0;
> >>> >> >}
> >>> >> >...
> >>> >> >}
> >>> >> >
> >>> >> >if (pVeraContext)
> >>> >> >                {
> >>> >> >s_rgppVeraSocketInfo[pVeraContext->m_nConnTicket] = NULL;
> >>> >> >    if (pVeraContext->m_pContext)
> >>> >> >{
> >>> >> >libwebsocket_context_destroy(pVeraContext->m_pContext);
> >>> >> >pVeraContext->m_pContext = NULL;
> >>> >> >}
> >>> >> >                }
> >>> >> >...
> >>> >> >   }
> >>> >> >...
> >>> >> >}
> >>> >> >...
> >>> >> >... PollService(LPVOID lpParam)
> >>> >> >{
> >>> >> >        int n = 0;
> >>> >> >VeraContext *pVeraContext = (VeraContext *)lpParam;
> >>> >> >
> >>> >> >if (pVeraContext && pVeraContext->m_pVeraSocketInfo &&
> >>> >> >pVeraContext->m_pContext)
> >>> >> >{
> >>> >> >BOOL *pfSocketClosed =
> >>> >> >&pVeraContext->m_pVeraSocketInfo->m_ConnInfo.m_fConnClosed;
> >>> >> >struct libwebsocket_context *pContext =
> >pVeraContext->m_pContext;
> >>> >> >
> >>> >> >while (n >= 0 && !*pfSocketClosed) {
> >>> >> >n = libwebsocket_service(pContext, 64);
> >>> >> >}
> >>> >> >}
> >>> >> >        return 0;
> >>> >> >}
> >>> >> >
> >>> >> >Sometimes, our first VeraConnect call fails, then the immediate
> >>next
> >>> >> >VeraConnect call crashes. The crash details are below, with line
> >>> >> >numbers (e.g.
> >>> >> >one line below refers to calling wsi_from_fd() near line 310 of
> >>> >> >context.c
> >>> >> >in function libwebsocket_context_destroy()). Basically, the
> >>memory
> >>> >has
> >>> >> >been
> >>> >> >freed by libwebsocket_service below (its trace includes
> >>> >> >libwebsocket_service_fd, lws_client_socket_service,
> >>> >> >libwebsocket_client_connect_2, _realloc), but it is then freed
> >>again
> >>> >by
> >>> >> >the
> >>> >> >libwebsocket_context_destroy() inside VeraConnect. Therefore it
> >>> >> >crashes.
> >>> >> >
> >>> >> >So could anyone please tell me if my way of using lws should be
> >>> >changed
> >>> >> >to
> >>> >> >fix this? Or is there a way to change lws to avoid this crash?
> >>> >> >
> >>> >> >Many thanks,
> >>> >> >Lan
> >>> >> >
> >>> >> >original faulting stack:
> >>> >> >
> >>> >> >0:003> .ecxr
> >>> >> >rax=000000000477cee0 rbx=0000000013f70c50 rcx=0000000000000000
> >>> >> >rdx=000000000402d680 rsi=0000000000000000 rdi=0000000000000000
> >>> >> >rip=00000000ff3f159a rsp=000000000659f788 rbp=00000000ff406ba0
> >>> >> > r8=0000000000000004  r9=0000000013f70c50 r10=0000000000000280
> >>> >> >r11=0000000000000004 r12=0000000000000000 r13=0000000000000102
> >>> >> >r14=000000000659f880 r15=0000000004847ff8
> >>> >> >iopl=0         nv up ei pl nz na pe nc
> >>> >> >cs=0033  ss=002b  ds=002b  es=002b  fs=0053  gs=002b
> >>> >> >efl=00010202
> >>> >> >phantom!wsi_from_fd+0x3a:
> >>> >> >00000000`ff3f159a 44395060        cmp     dword ptr
> >>[rax+60h],r10d
> >>> >> >ds:00000000`0477cf40=????????
> >>> >> >0:003> kv
> >>> >> >  *** Stack trace for last set context - .thread/.cxr resets it
> >>> >> >Child-SP          RetAddr           : Args to
> >>> >> >Child
> >:
> >>> >Call
> >>> >> >Site
> >>> >> >00000000`0659f788 00000000`ff3efe1f : 00000000`00000000
> >>> >> >00000000`ff3a1c74
> >>> >> >00000000`ff3a1c78 00000000`03eade30 : phantom!wsi_from_fd+0x3a
> >>> >> >[c:\libwebsockets\lib\lws-plat-win.c @ 45]
> >>> >> >00000000`0659f790 00000000`ff3c2b7f : 00000000`00000102
> >>> >> >00000000`03eade30
> >>> >> >00000000`03eade20 00000000`04847fe0 :
> >>> >> >phantom!libwebsocket_context_destroy+0x5f
> >>> >> >[c:\libwebsockets\lib\context.c @ 310]
> >>> >> >00000000`0659f7d0 00000000`ff3bec11 : 00000000`0659f898
> >>> >> >00000000`02460000
> >>> >> >00000000`00000050 00000000`ff40e5f8 : phantom!VeraConnect+0x29f
> >>> >> >[c:\socketcode\c\verasock\verasocklws.c @ 1194]
> >>> >> >...
> >>> >> >00000000`0659ff10 00000000`76fa3281 : 00000000`00000000
> >>> >> >00000000`00000000
> >>> >> >00000000`00000000 00000000`00000000 :
> >>> >kernel32!BaseThreadInitThunk+0xd
> >>> >> >00000000`0659ff40 00000000`00000000 : 00000000`00000000
> >>> >> >00000000`00000000
> >>> >> >00000000`00000000 00000000`00000000 :
> >>ntdll!RtlUserThreadStart+0x1d
> >>> >> >
> >>> >> >0:003> !heap -p -a 000000000477cee0
> >>> >> >    address 000000000477cee0 found in
> >>> >> >    _DPH_HEAP_ROOT @ 3d51000
> >>> >> >    in free-ed allocation (  DPH_HEAP_BLOCK:         VirtAddr
> >>> >> >VirtSize)
> >>> >> >                                    3d549c0:          477c000
> >>> >> >2000
> >>> >> >*** ERROR: Symbol file could not be found.  Defaulted to export
> >>> >symbols
> >>> >> >for
> >>> >> >verifier.dll -
> >>> >> >    000007fef45b8726
> >>> >>
> >>>
> >>>>verifier!VerifierDisableFaultInjectionExclusionRange+0x000000000000234e
> >>> >> >    000000007703c415 ntdll!RtlDebugFreeHeap+0x0000000000000035
> >>> >> >    0000000076fdd0fe ntdll! ??
> >>> >::FNODOBFM::`string'+0x00000000000122e2
> >>> >> >    0000000076fc2075 ntdll!RtlFreeHeap+0x00000000000001a2
> >>> >> >*** ERROR: Symbol file could not be found.  Defaulted to export
> >>> >symbols
> >>> >> >for
> >>> >> >msvcrt.dll -
> >>> >> >    000007fefd4e10c4 msvcrt!free+0x000000000000001c
> >>> >> >    00000000ff3f2bac phantom!_realloc+0x000000000000001c
> >>> >> >[c:\libwebsockets\lib\alloc.c @ 9]
> >>> >> >00000000ff3f0e77
> >>> >> >phantom!libwebsocket_client_connect_2+0x00000000000003b7
> >>> >> >[c:\libwebsockets\lib\client-handshake.c @ 289]
> >>> >> >  00000000ff3f5385
> >>> >phantom!lws_client_socket_service+0x0000000000000045
> >>> >> >[c:\libwebsockets\lib\client.c @ 63]
> >>> >> >    00000000ff3f0a46
> >>> >phantom!libwebsocket_service_fd+0x00000000000003f6
> >>> >> >[c:\libwebsockets\lib\service.c @ 616]
> >>> >> >    00000000ff3f1909 phantom!lws_plat_service+0x0000000000000119
> >>> >> >[c:\libwebsockets\lib\lws-plat-win.c @ 164]
> >>> >> >    00000000ff3c1cf6 phantom!PollService+0x0000000000000036
> >>> >> >[c:\socketcode\c\verasock\verasocklws.c @ 377]
> >>> >> >    0000000076e6f56d
> >>kernel32!BaseThreadInitThunk+0x000000000000000d
> >>> >> >    0000000076fa3281 ntdll!RtlUserThreadStart+0x000000000000001d
> >>> >>
> >>> >>
> >>>
> >>>
> >
> >_______________________________________________
> >Libwebsockets mailing list
> >Libwebsockets at ml.libwebsockets.org
> >http://ml.libwebsockets.org/mailman/listinfo/libwebsockets
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://libwebsockets.org/pipermail/libwebsockets/attachments/20151117/6cad0b41/attachment-0001.html>


More information about the Libwebsockets mailing list