8000 Init failiure leads to seg fault · Issue #2129 · warmcat/libwebsockets · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

Init failiure leads to seg fault #2129

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

Closed
LadMartin opened this issue Nov 27, 2020 · 1 comment
Closed

Init failiure leads to seg fault #2129

LadMartin opened this issue Nov 27, 2020 · 1 comment

Comments

@LadMartin
Copy link

Hi,

I have prepared a minimal (I hope not too minimal) example that crashes during uv_run.

The important thing is that the lws_create_context has to fail to create a context. My approach was that I set info.port to some already taken port on my pc.

Used libraries lws 4.1.4, uv 1.35.0

#include <uv.h>
#include <libwebsockets.h>

int main(int argc, const char **argv)
{
	uv_loop_t loop;
	uv_loop_init(&loop);

	struct lws_context_creation_info info;
	struct lws_context *context;

	lws_set_log_level(LLL_USER | LLL_ERR | LLL_WARN | LLL_NOTICE | LLL_DEBUG | LLL_HEADER | LLL_LATENCY | LLL_CLIENT | LLL_PARSER | LLL_EXT | LLL_INFO, NULL);

	memset(&info, 0, sizeof info); /* otherwise uninitialized garbage */
	info.port = 8081; // NOTE this has conflict with some existing socket
	info.options |=  LWS_SERVER_OPTION_LIBUV | LWS_SERVER_OPTION_UV_NO_SIGSEGV_SIGFPE_SPIN | LWS_SERVER_OPTION_HTTP_HEADERS_SECURITY_BEST_PRACTICES_ENFORCE;

	void *loops[2];
	loops[0] = &loop;
	loops[1] = NULL;
	info.foreign_loops = loops;

	context = lws_create_context(&info);
	if (!context) {
		lwsl_err("lws init failed\n");
	}

	uv_run(&loop, UV_RUN_DEFAULT);

	lws_context_destroy(context);
	return 0;
}

#0  0x00007ffff795a7b0 in delete_from_fd () from /lib64/libwebsockets.so.17
#1  0x00007ffff7968724 in __lws_close_free_wsi_final () from /lib64/libwebsockets.so.17
#2  0x00007ffff4e28019 in lws_libuv_closewsi () from /usr/lib64/libwebsockets-evlib_uv.so
#3  0x00007ffff7bbd485 in uv__finish_close (handle=0x60faf0) at src/unix/core.c:298
#4  uv__run_closing_handles (loop=0x7fffffffe6f0) at src/unix/core.c:312
#5  uv_run (loop=0x7fffffffe6f0, mode=UV_RUN_DEFAULT) at src/unix/core.c:382
#6  0x00000000004008c3 in main ()
[2020/11/27 23:26:13:0710] D: _realloc: size 24: lws_plat_dlopen                                                                                                                                          [15/7286]
[2020/11/27 23:26:13:0710] I: Event loop: libuv                                                                                                                                                                    
[2020/11/27 23:26:13:0710] D: _realloc: size 9032: context                                                                                                                                                         
[2020/11/27 23:26:13:0710] D: _realloc: size 72: lws_smd_register                                                                                                                                                  
[2020/11/27 23:26:13:0710] D: lws_smd_register: registered                                                                                                                                                         
[2020/11/27 23:26:13:0711] D: _realloc: size 8192: fds table                                                                                                                                                       
[2020/11/27 23:26:13:0711] I:  ctx:  5680B (1584 ctx + pt(1 thr x 4096)), pt-fds: 1024, fdmap: 8192                                                                                                                
[2020/11/27 23:26:13:0711] I:  http: ah_data: 4096, ah: 976, max count 1024                                                                                                                                        
[2020/11/27 23:26:13:0711] D: _realloc: size 8192: lws_lookup                                                                                                                                                      
[2020/11/27 23:26:13:0711] I:  mem: platform fd map:  8192 B                                                                                                                                                       
[2020/11/27 23:26:13:0711] N:  Using foreign event loop...                                                                                                                                                         
[2020/11/27 23:26:13:0711] D: _realloc: size 864: event pipe wsi                                                                                                                                                   
[2020/11/27 23:26:13:0711] D: lws_role_transition: 0x60f780: wsistate 0x200, ops pipe                                                                                                                              
[2020/11/27 23:26:13:0711] D: event pipe fd 14                                                                                                                                                                     
[2020/11/27 23:26:13:0711] D: _realloc: size 160: uvh                                                                                                                                                              
[2020/11/27 23:26:13:0711] D: __insert_wsi_socket_into_fds: 0x60f780: tsi=0, sock=14, pos-in-fds=0                                                                                                                 
[2020/11/27 23:26:13:0711] D: elops_io_uv: 0x60f780: 5
[2020/11/27 23:26:13:0712] I:  Compiled with OpenSSL support
[2020/11/27 23:26:13:0712] I:  SSL disabled: no LWS_SERVER_OPTION_DO_SSL_GLOBAL_INIT
[2020/11/27 23:26:13:0712] I:  canonical_hostname = localhost.localdomain
[2020/11/27 23:26:13:0712] D: _realloc: size 712: lws_create_vhost
[2020/11/27 23:26:13:0712] D: _realloc: size 112: vhost-specific plugin table
[2020/11/27 23:26:13:0712] D: _realloc: size 24: same vh list
[2020/11/27 23:26:13:0712] I: Creating Vhost 'default' port 8081, 1 protocols, IPv6 off
[2020/11/27 23:26:13:0713] E: ERROR on binding fd 15 to port 8081 (-1 98)
[2020/11/27 23:26:13:0713] E: init server failed
[2020/11/27 23:26:13:0713] D: _realloc: size 24: deferred free
[2020/11/27 23:26:13:0713] I: lws_vhost_destroy1
[2020/11/27 23:26:13:0713] D: lws_vhost_destroy: count_bound_wsi 0
[2020/11/27 23:26:13:0713] I: __lws_vhost_destroy2: 0x60fcb0
[2020/11/27 23:26:13:0713] I:   __lws_vhost_destroy2: Freeing vhost 0x60fcb0
[2020/11/27 23:26:13:0713] E: Failed to create default vhost
[2020/11/27 23:26:13:0713] I: lws_destroy_event_pipe 
[2020/11/27 23:26:13:0713] D: elops_io_uv: 0x60f780: -2147483637
[2020/11/27 23:26:13:0713] D: elops_io_uv: 0x60f780: 11
[2020/11/27 23:26:13:0713] D: elops_wsi_logical_close_uv: 0x60f780: 0 1 stop listener / pipe poll
[2020/11/27 23:26:13:0714] D: elops_wsi_logical_close_uv: lws_libuv_closehandle: wsi 0x60f780
[2020/11/27 23:26:13:0714] D: lws_libuv_closehandle: 0x60f780
[2020/11/27 23:26:13:0714] E: lws init failed
[2020/11/27 23:26:13:0714] I: lws_libuv_closewsi: 0x60f780
[2020/11/27 23:26:13:0714] D: __lws_close_free_wsi_final: wsi 0x60f780: fd 14
[2020/11/27 23:26:13:0714] D: closing: close ret 9
[2020/11/27 23:26:13:0714] D: elops_io_uv: 0x60f780: -2147483637
[2020/11/27 23:26:13:0710] D: _realloc: size 24: lws_plat_dlopen                                                                                                                                          [15/7286]
[2020/11/27 23:26:13:0710] I: Event loop: libuv                                                                                                                                                                    
[2020/11/27 23:26:13:0710] D: _realloc: size 9032: context                                                                                                                                                         
[2020/11/27 23:26:13:0710] D: _realloc: size 72: lws_smd_register                                                                                                                                                  
[2020/11/27 23:26:13:0710] D: lws_smd_register: registered                                                                                                                                                         
[2020/11/27 23:26:13:0711] D: _realloc: size 8192: fds table                                                                                                                                                       
[2020/11/27 23:26:13:0711] I:  ctx:  5680B (1584 ctx + pt(1 thr x 4096)), pt-fds: 1024, fdmap: 8192                                                                                                                
[2020/11/27 23:26:13:0711] I:  http: ah_data: 4096, ah: 976, max count 1024                                                                                                                                        
[2020/11/27 23:26:13:0711] D: _realloc: size 8192: lws_lookup                                                                                                                                                      
[2020/11/27 23:26:13:0711] I:  mem: platform fd map:  8192 B                                                                                                                                                       
[2020/11/27 23:26:13:0711] N:  Using foreign event loop...                                                                                                                                                         
[2020/11/27 23:26:13:0711] D: _realloc: size 864: event pipe wsi                                                                                                                                                   
[2020/11/27 23:26:13:0711] D: lws_role_transition: 0x60f780: wsistate 0x200, ops pipe                                                                                                                              
[2020/11/27 23:26:13:0711] D: event pipe fd 14                                                                                                                                                                     
[2020/11/27 23:26:13:0711] D: _realloc: size 160: uvh                                                                                                                                                              
[2020/11/27 23:26:13:0711] D: __insert_wsi_socket_into_fds: 0x60f780: tsi=0, sock=14, pos-in-fds=0                                                                                                                 
[2020/11/27 23:26:13:0711] D: elops_io_uv: 0x60f780: 5
[2020/11/27 23:26:13:0712] I:  Compiled with OpenSSL support
[2020/11/27 23:26:13:0712] I:  SSL disabled: no LWS_SERVER_OPTION_DO_SSL_GLOBAL_INIT
[2020/11/27 23:26:13:0712] I:  canonical_hostname = localhost.localdomain
[2020/11/27 23:26:13:0712] D: _realloc: size 712: lws_create_vhost
[2020/11/27 23:26:13:0712] D: _realloc: size 112: vhost-specific plugin table
[2020/11/27 23:26:13:0712] D: _realloc: size 24: same vh list
[2020/11/27 23:26:13:0712] I: Creating Vhost 'default' port 8081, 1 protocols, IPv6 off
[2020/11/27 23:26:13:0713] E: ERROR on binding fd 15 to port 8081 (-1 98)
[2020/11/27 23:26:13:0713] E: init server failed
[2020/11/27 23:26:13:0713] D: _realloc: size 24: deferred free
[2020/11/27 23:26:13:0713] I: lws_vhost_destroy1
[2020/11/27 23:26:13:0713] D: lws_vhost_destroy: count_bound_wsi 0
[2020/11/27 23:26:13:0713] I: __lws_vhost_destroy2: 0x60fcb0
[2020/11/27 23:26:13:0713] I:   __lws_vhost_destroy2: Freeing vhost 0x60fcb0
[2020/11/27 23:26:13:0713] E: Failed to create default vhost
[2020/11/27 23:26:13:0713] I: lws_destroy_event_pipe 
[2020/11/27 23:26:13:0713] D: elops_io_uv: 0x60f780: -2147483637
[2020/11/27 23:26:13:0713] D: elops_io_uv: 0x60f780: 11
[2020/11/27 23:26:13:0713] D: elops_wsi_logical_close_uv: 0x60f780: 0 1 stop listener / pipe poll
[2020/11/27 23:26:13:0714] D: elops_wsi_logical_close_uv: lws_libuv_closehandle: wsi 0x60f780
[2020/11/27 23:26:13:0714] D: lws_libuv_closehandle: 0x60f780
[2020/11/27 23:26:13:0714] E: lws init failed
[2020/11/27 23:26:13:0714] I: lws_libuv_closewsi: 0x60f780
[2020/11/27 23:26:13:0714] D: __lws_close_free_wsi_final: wsi 0x60f780: fd 14
[2020/11/27 23:26:13:0714] D: closing: close ret 9
[2020/11/27 23:26:13:0714] D: elops_io_uv: 0x60f780: -2147483637
[2020/11/27 23:26:13:0714] I: elops_io_uv: no watcher
lws-team added a commit that referenced this issue Nov 28, 2020
When using a foreign libuv loop, context creation may fail after adding
handles to the foreign loop... if so, it can no longer deal with the
fatal error by unpicking the created context and returning NULL... it
has to brazen it out with a half-baked context that has already started
the destroy flow and allow the foreign loop to close out the handles
the usual way for libuv.

#2129
lws-team added a commit that referenced this issue Nov 28, 2020
When using a foreign libuv loop, context creation may fail after adding
handles to the foreign loop... if so, it can no longer deal with the
fatal error by unpicking the created context and returning NULL... it
has to brazen it out with a half-baked context that has already started
the destroy flow and allow the foreign loop to close out the handles
the usual way for libuv.

#2129
@lws-team
Copy link
Member

Unfortunately, uniquely, libuv is "asymmetric" in its api... you can add handles to its loop without the loop running. But you cannot cleanly remove them from the loop without the loop running, since it stages handle close to complete only after having gone around its loop. And while not completed, libuv is containing dangling references to the related lws objects, which cannot be destroyed until all those libuv completions (needing a running loop) happened. For non-foreign loop, it doesn't matter since the loop is part of the context footprint and both can be destroyed.

lws knows this for context destroy flow, it marks the context and wanting to be destroyed and returns to the libuv loop instead of destroying in one step, counts handles added by lws to the loop, counts their libuv handle close completions, and finalizes the lws destroy only when the count reaches 0 some time later.

But this is a situation where we decide partway through we want to fatally fail creating the context and unpick the work returning NULL for the context... normally we can do that OK (and it is the natural way...) but with libuv, if we touched the loop at all, we cannot unpick context creation in one step just like we can't do anything else related to libuv handle close in one step either. With libuv, for fatal context creation errors, we would have to instead treat them as not immediately fatal, create an incomplete context that has already started the destroy flow by the time it leaves lws_destroy_context(), let you start the loop and enter the normal context destroy flow with this half-baked context.

I pushed a patch on main + v4.1-stable that detects if it's on libuv + foreign and if the context creation is past the point that it has created handles on the foreign loop, to instead fail by calling destroy_context() and leaving with the half-baked, self-destructing failed context returned. This solves the crash on your example.

lws-team added a commit that referenced this issue Nov 28, 2020
When using a foreign libuv loop, context creation may fail after adding
handles to the foreign loop... if so, it can no longer deal with the
fatal error by unpicking the created context and returning NULL... it
has to brazen it out with a half-baked context that has already started
the destroy flow and allow the foreign loop to close out the handles
the usual way for libuv.

#2129
lws-team added a commit that referenced this issue Nov 28, 2020
When using a foreign libuv loop, context creation may fail after adding
handles to the foreign loop... if so, it can no longer deal with the
fatal error by unpicking the created context and returning NULL... it
has to brazen it out with a half-baked context that has already started
the destroy flow and allow the foreign loop to close out the handles
the usual way for libuv.

#2129
@lws-team lws-team closed this as completed Dec 1, 2020
lws-team added a commit that referenced this issue Dec 1, 2020
When using a foreign libuv loop, context creation may fail after adding
handles to the foreign loop... if so, it can no longer deal with the
fatal error by unpicking the created context and returning NULL... it
has to brazen it out with a half-baked context that has already started
the destroy flow and allow the foreign loop to close out the handles
the usual way for libuv.

#2129
lws-team added a commit that referenced this issue Dec 1, 2020
When using a foreign libuv loop, context creation may fail after adding
handles to the foreign loop... if so, it can no longer deal with the
fatal error by unpicking the created context and returning NULL... it
has to brazen it out with a half-baked context that has already started
the destroy flow and allow the foreign loop to close out the handles
the usual way for libuv.

#2129
lws-team added a commit that referenced this issue Dec 1, 2020
When using a foreign libuv loop, context creation may fail after adding
handles to the foreign loop... if so, it can no longer deal with the
fatal error by unpicking the created context and returning NULL... it
has to brazen it out with a half-baked context that has already started
the destroy flow and allow the foreign loop to close out the handles
the usual way for libuv.

#2129
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
0