WebKit network process crash loading SSL Labs client test
Try loading https://www.ssllabs.com/ssltest/viewMyClient.html in Epiphany and the network process will crash (though users might never notice, the only indication is an error message in the web inspector). This is a regression from my shared base class work. Full crash details below, but the key part is this frame here:
#6 0x00007f0f6b31b0e4 in IPC::Encoder::encodeFixedLengthData (this=<optimized out>, data=0x7f0f63a84400 "\210\002\003\350ng.1 101 Switching Protocols\r\nServer: Apache-Coyote/1.1\r\nUpgrade: websocket\r\nConnection: upgrade\r\nSec-WebSocket-Accept: A4hMnbrpLzek2SUBj/oBFFxJ+CE=\r\nDate: Sun, 23 Jun 2019 18:52:26 GMT\r\n\r\n", size=139704119996146, alignment=<optimized out>) at /home/mcatanzaro/Projects/WebKit/Source/WebKit/Platform/IPC/Encoder.cpp:183
Note the size is insane, way longer than the actual size of the data buffer.
It's coming from SocketStreamHandleImpl::readReadyCallback which is calling g_input_stream_read_finish() on a GInputStream. After some investigation inside libsoup, I eventually determined that the GInputStream is our GTlsClientConnection. The crash occurs because WebKit attempts to allocate the 127 TB that GInputStream reports it has read and fails. (Unfortunately my desktop doesn't have quite that much RAM.)
The problem is that g_tls_connection_gnutls_read() -- and also g_tls_connection_openssl_read() -- sets nread only when ret >= 0, so if ret < 0 then nread is uninitialized. But there is nothing here to prevent to from then returning G_TLS_CONNECTION_BASE_SUCCESS even if nread is uninitialized. The function just assumes that status will not be success if ret < 0, but in fact it might not be. In this case, ret == GNUTLS_E_PREMATURE_TERMINATION, but SoupSocket has set require-close-notify to FALSE when creating the GTlsClientConnection, so instead of returning G_TLS_CONNECTION_BASE_ERROR, end_gnutls_io() instead returns G_TLS_CONNECTION_BASE_OK.
So this is really a two-part problem:
- Got to ensure we set nread (and also nwrote in the write functions, of course) whenever we return G_TLS_CONNECTION_BASE_OK
- Got to try to fix require-close-notify
I haven't decided how to fix it yet. I suppose we could compute the data size with strlen and hope it doesn't contain NULL bytes, but that assumption would be incorrect. I might look up what the original code was doing here, but I suspect there's no way to actually get the correct size out of GnuTLS. I'm not even certain that it's safe to assume that the data buffer is filled with meaningful data when an error is returned by GnuTLS (though it nicely is in this case) so it might be illegal for us to ignore the error and return the data anyway.
Backtrace:
Program terminated with signal SIGSEGV, Segmentation fault.
#0 0x00007f0f69773abd in bmalloc::Heap::allocateLarge (this=<optimized out>,
lock=..., alignment=alignment@entry=8, size=size@entry=140737488355328)
at /home/mcatanzaro/Projects/WebKit/Source/bmalloc/bmalloc/Heap.cpp:591
591 RELEASE_BASSERT(result);
(gdb) bt
#0 0x00007f0f69773abd in bmalloc::Heap::allocateLarge (this=<optimized out>,
lock=..., alignment=alignment@entry=8, size=size@entry=140737488355328)
at /home/mcatanzaro/Projects/WebKit/Source/bmalloc/bmalloc/Heap.cpp:591
#1 0x00007f0f6a587f51 in bmalloc::Allocator::allocateLarge (
this=0x7f0f6ab6c710, size=140737488355328)
at /home/mcatanzaro/Projects/WebKit/Source/bmalloc/bmalloc/Allocator.cpp:180
#2 0x00007f0f6a588145 in bmalloc::Allocator::allocateSlowCase (
this=<optimized out>, size=<optimized out>)
at /home/mcatanzaro/Projects/WebKit/Source/bmalloc/bmalloc/Allocator.cpp:204
#3 0x00007f0f6b31b010 in IPC::allocBuffer<unsigned char> (
size=140737488355328, buffer=<synthetic pointer>: <optimized out>)
at /home/mcatanzaro/Projects/WebKit/Source/WebKit/Platform/IPC/Encoder.cpp:144
#4 IPC::Encoder::reserve (this=this@entry=0x7f0f63ab8a00,
size=size@entry=139704119996234)
at /home/mcatanzaro/Projects/WebKit/Source/WebKit/Platform/IPC/Encoder.cpp:144
#5 0x00007f0f6b31b08f in IPC::Encoder::grow (this=0x7f0f63ab8a00,
alignment=<optimized out>, size=size@entry=139704119996146)
at /home/mcatanzaro/Projects/WebKit/Source/WebKit/Platform/IPC/Encoder.cpp:169
#6 0x00007f0f6b31b0e4 in IPC::Encoder::encodeFixedLengthData (this=<optimized out>, data=0x7f0f63a84400 "\210\002\003\350ng.1 101 Switching Protocols\r\nServer: Apache-Coyote/1.1\r\nUpgrade: websocket\r\nConnection: upgrade\r\nSec-WebSocket-Accept: A4hMnbrpLzek2SUBj/oBFFxJ+CE=\r\nDate: Sun, 23 Jun 2019 18:52:26 GMT\r\n\r\n", size=139704119996146, alignment=<optimized out>) at /home/mcatanzaro/Projects/WebKit/Source/WebKit/Platform/IPC/Encoder.cpp:183
#7 0x00007f0f6b31b1d4 in IPC::Encoder::encodeVariableLengthByteArray (this=<optimized out>, dataReference=...) at /home/mcatanzaro/Projects/WebKit/Source/WebKit/Platform/IPC/DataReference.h:59
#8 0x00007f0f6b31a16e in IPC::DataReference::encode (this=<optimized out>, encoder=...) at /home/mcatanzaro/Projects/WebKit/Source/WebKit/Platform/IPC/DataReference.cpp:36
#9 0x00007f0f6b2a0b09 in IPC::ArgumentCoder<IPC::DataReference>::encode (t=..., encoder=...) at /home/mcatanzaro/Projects/WebKit/Source/WebKit/Platform/IPC/ArgumentCoder.h:97
#10 IPC::Encoder::encode<IPC::DataReference const&, (void*)0> (t=..., this=0x7f0f63ab8a00) at /home/mcatanzaro/Projects/WebKit/Source/WebKit/Platform/IPC/Encoder.h:71
#11 IPC::Encoder::operator<< <IPC::DataReference const&, (void*)0> (t=..., this=0x7f0f63ab8a00) at /home/mcatanzaro/Projects/WebKit/Source/WebKit/Platform/IPC/Encoder.h:84
#12 IPC::TupleEncoder<1ul, IPC::DataReference const&>::encode (tuple=..., encoder=...) at /home/mcatanzaro/Projects/WebKit/Source/WebKit/Platform/IPC/ArgumentCoders.h:167
#13 IPC::ArgumentCoder<std::tuple<IPC::DataReference const&> >::encode (tuple=..., encoder=...) at /home/mcatanzaro/Projects/WebKit/Source/WebKit/Platform/IPC/ArgumentCoders.h:239
#14 IPC::Encoder::encode<std::tuple<IPC::DataReference const&> const&, (void*)0> (t=..., this=0x7f0f63ab8a00) at /home/mcatanzaro/Projects/WebKit/Source/WebKit/Platform/IPC/Encoder.h:71
#15 IPC::MessageSender::send<Messages::WebSocketStream::DidReceiveSocketStreamData> (sendOptions=..., destinationID=1, message=..., this=0x7f0f63ae82a0) at /home/mcatanzaro/Projects/WebKit/Source/WebKit/Platform/IPC/MessageSender.h:47
#16 IPC::MessageSender::send<Messages::WebSocketStream::DidReceiveSocketStreamData> (sendOptions=..., message=..., this=0x7f0f63ae82a0) at /home/mcatanzaro/Projects/WebKit/Source/WebKit/Platform/IPC/MessageSender.h:39
#17 WebKit::NetworkSocketStream::didReceiveSocketStreamData (this=0x7f0f63ae82a0, handle=..., data=<optimized out>, length=<optimized out>) at /home/mcatanzaro/Projects/WebKit/Source/WebKit/NetworkProcess/NetworkSocketStream.cpp:90
#18 0x00007f0f6c7690d4 in WebCore::SocketStreamHandleImpl::readBytes (bytesRead=<optimized out>, this=0x7f0f63a91c60) at /usr/include/c++/9/bits/unique_ptr.h:615
#19 WebCore::SocketStreamHandleImpl::readBytes (this=0x7f0f63a91c60, bytesRead=<optimized out>) at /home/mcatanzaro/Projects/WebKit/Source/WebCore/platform/network/soup/SocketStreamHandleImplSoup.cpp:168
#20 0x00007f0f6c769313 in WebCore::SocketStreamHandleImpl::readReadyCallback (stream=<optimized out>, result=<optimized out>, handle=0x7f0f63a91c60) at /home/mcatanzaro/Projects/WebKit/Source/WebCore/platform/network/soup/SocketStreamHandleImplSoup.cpp:203
#21 0x00007f0f65c1d3f3 in async_ready_callback_wrapper (source_object=0x1230e50, res=0x116fc80, user_data=0x7f0f63a91c60) at ../../../../Projects/glib/gio/ginputstream.c:532
#22 0x00007f0f65c615e3 in g_task_return_now (task=0x116fc80) at ../../../../Projects/glib/gio/gtask.c:1212
#23 0x00007f0f65c61649 in complete_in_idle_cb (task=0x116fc80) at ../../../../Projects/glib/gio/gtask.c:1226
#24 0x00007f0f6661cd03 in g_idle_dispatch (source=0xfb6f90, callback=0x7f0f65c61631 <complete_in_idle_cb>, user_data=0x116fc80) at ../../../../Projects/glib/glib/gmain.c:5612
#25 0x00007f0f6661a19d in g_main_dispatch (context=0xd379f0) at ../../../../Projects/glib/glib/gmain.c:3176
#26 0x00007f0f6661affa in g_main_context_dispatch (context=0xd379f0) at ../../../../Projects/glib/glib/gmain.c:3841
#27 0x00007f0f6661b1de in g_main_context_iterate (context=0xd379f0, block=1, dispatch=1, self=0xd43e90) at ../../../../Projects/glib/glib/gmain.c:3914
#28 0x00007f0f6661b60d in g_main_loop_run (loop=0xd37ab0) at ../../../../Projects/glib/glib/gmain.c:4108
#29 0x00007f0f6a583060 in WTF::RunLoop::run () at /home/mcatanzaro/Projects/WebKit/Source/WTF/wtf/glib/RunLoopGLib.cpp:96
#30 0x00007f0f6b30d090 in WebKit::AuxiliaryProcessMain<WebKit::NetworkProcess, WebKit::NetworkProcessMain> (argc=3, argv=<optimized out>) at /home/mcatanzaro/Projects/WebKit/Source/WebKit/Shared/unix/AuxiliaryProcessMain.h:40
#31 0x00007f0f653b9f33 in __libc_start_main () from /lib64/libc.so.6
#32 0x0000000000400b0e in _start ()