Skip to content

Null pointer dereference while parsing the HTTP header #103

@nik1as

Description

@nik1as

Hi,

we discovered a potential null pointer dereference during fuzzing. The bug is triggered during the parsing of the HTTP header.

Affected versions:

Logs

WARNING: All log messages before absl::InitializeLog() is called are written to STDERR
I0000 00:00:1774431059.274511      15 quiche_system_event_loop_impl.h:18] Starting event loop for quic_client
Connected to localhost:4433
AddressSanitizer:DEADLYSIGNAL
=================================================================
==15==ERROR: AddressSanitizer: SEGV on unknown address 0x000000000000 (pc 0x000000000000 bp 0x7ffe3431fde0 sp 0x7ffe3431fda8 T0)
==15==Hint: pc points to the zero page.
==15==The signal is caused by a READ memory access.
==15==Hint: address points to the zero page.
    #0 0x000000000000  (<unknown module>)
    #1 0x55d01bc607db in quic::QuicSpdyClientStream::OnInitialHeadersComplete(bool, unsigned long, quic::QuicHeaderList const&) /proc/self/cwd/quiche/quic/core/http/quic_spdy_client_stream.cc:116:8
    #2 0x55d01bcbcf37 in quic::QuicSpdyStream::OnStreamHeaderList(bool, unsigned long, quic::QuicHeaderList const&) /proc/self/cwd/quiche/quic/core/http/quic_spdy_stream.cc
    #3 0x55d01bcbdd03 in quic::QuicSpdyStream::OnHeadersDecoded(quic::QuicHeaderList, bool) /proc/self/cwd/quiche/quic/core/http/quic_spdy_stream.cc:614:3
    #4 0x55d01bd10b6f in quic::QpackDecodedHeadersAccumulator::OnDecodingCompleted() /proc/self/cwd/quiche/quic/core/qpack/qpack_decoded_headers_accumulator.cc:63:13
    #5 0x55d01bd11274 in quic::QpackDecodedHeadersAccumulator::EndHeaderBlock() /proc/self/cwd/quiche/quic/core/qpack/qpack_decoded_headers_accumulator.cc:95:13
    #6 0x55d01bcc905c in quic::QuicSpdyStream::OnHeadersFrameEnd() /proc/self/cwd/quiche/quic/core/http/quic_spdy_stream.cc:1183:39
    #7 0x55d01c2193e0 in quic::HttpDecoder::FinishParsing() /proc/self/cwd/quiche/quic/core/http/http_decoder.cc
    #8 0x55d01c21387c in quic::HttpDecoder::ProcessInput(char const*, unsigned long) /proc/self/cwd/quiche/quic/core/http/http_decoder.cc:128:31
    #9 0x55d01bcc35e7 in quic::QuicSpdyStream::OnDataAvailable() /proc/self/cwd/quiche/quic/core/http/quic_spdy_stream.cc:872:46
    #10 0x55d01c01231e in quic::QuicStreamSequencer::OnFrameData(unsigned long, unsigned long, char const*) /proc/self/cwd/quiche/quic/core/quic_stream_sequencer.cc:118:18
    #11 0x55d01c010190 in quic::QuicStreamSequencer::OnStreamFrame(quic::QuicStreamFrame const&) /proc/self/cwd/quiche/quic/core/quic_stream_sequencer.cc:65:3
    #12 0x55d01bfc9d8a in quic::QuicStream::OnStreamFrame(quic::QuicStreamFrame const&) /proc/self/cwd/quiche/quic/core/quic_stream.cc:533:14
    #13 0x55d01bf52dc0 in quic::QuicSession::OnStreamFrame(quic::QuicStreamFrame const&) /proc/self/cwd/quiche/quic/core/quic_session.cc:389:11
    #14 0x55d01bd9a3e1 in quic::QuicConnection::OnStreamFrame(quic::QuicStreamFrame const&) /proc/self/cwd/quiche/quic/core/quic_connection.cc:1458:13
    #15 0x55d01be7500d in quic::QuicFramer::ProcessIetfFrameData(quic::QuicDataReader*, quic::QuicPacketHeader const&, quic::EncryptionLevel) /proc/self/cwd/quiche/quic/core/quic_framer.cc:2839:22
    #16 0x55d01be6ca6c in quic::QuicFramer::ProcessIetfDataPacket(quic::QuicDataReader*, quic::QuicPacketHeader*, quic::QuicEncryptedPacket const&, char*, unsigned long) /proc/self/cwd/quiche/quic/core/quic_framer.cc:1920:10
    #17 0x55d01be668cc in quic::QuicFramer::ProcessPacketInternal(quic::QuicEncryptedPacket const&) /proc/self/cwd/quiche/quic/core/quic_framer.cc:1536:10
    #18 0x55d01be6604a in quic::QuicFramer::ProcessPacket(quic::QuicEncryptedPacket const&) /proc/self/cwd/quiche/quic/core/quic_framer.cc:1475:17
    #19 0x55d01bdbb5ea in quic::QuicConnection::ProcessUdpPacket(quiche::QuicheSocketAddress const&, quiche::QuicheSocketAddress const&, quic::QuicReceivedPacket const&) /proc/self/cwd/quiche/quic/core/quic_connection.cc:2816:16
    #20 0x55d01bf668ea in quic::QuicSession::ProcessUdpPacket(quiche::QuicheSocketAddress const&, quiche::QuicheSocketAddress const&, quic::QuicReceivedPacket const&) /proc/self/cwd/quiche/quic/core/quic_session.cc:1003:16
    #21 0x55d01bb77670 in quic::QuicPacketReader::ReadAndDispatchPackets(int, int, quic::QuicClock const&, quic::ProcessPacketInterface*, unsigned long*) /proc/self/cwd/quiche/quic/core/quic_packet_reader.cc:118:16
    #22 0x55d01bb595e9 in quic::QuicClientDefaultNetworkHelper::OnSocketEvent(quic::QuicEventLoop*, int, unsigned char) /proc/self/cwd/quiche/quic/tools/quic_client_default_network_helper.cc:158:38
    #23 0x55d01bb3e3fd in quic::QuicPollEventLoop::RunReadyCallbacks(std::vector<quic::QuicPollEventLoop::ReadyListEntry, std::allocator<quic::QuicPollEventLoop::ReadyListEntry>>&) /proc/self/cwd/quiche/quic/core/io/quic_poll_event_loop.cc:207:29
    #24 0x55d01bb3cab5 in quic::QuicPollEventLoop::ProcessIoEvents(quic::QuicTime, quic::QuicTimeDelta) /proc/self/cwd/quiche/quic/core/io/quic_poll_event_loop.cc:174:3
    #25 0x55d01bb3c39d in quic::QuicPollEventLoop::RunEventLoopOnce(quic::QuicTimeDelta) /proc/self/cwd/quiche/quic/core/io/quic_poll_event_loop.cc:89:3
    #26 0x55d01bb89798 in quic::QuicClientBase::WaitForEvents() /proc/self/cwd/quiche/quic/tools/quic_client_base.cc:284:20
    #27 0x55d01bb9bce5 in quic::QuicSpdyClientBase::SendRequestAndWaitForResponse(quiche::HttpHeaderBlock const&, std::basic_string_view<char, std::char_traits<char>>, bool) /proc/self/cwd/quiche/quic/tools/quic_spdy_client_base.cc:129:10
    #28 0x55d01bb2e450 in quic::QuicToyClient::SendRequestsAndPrintResponses(std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>>>) /proc/self/cwd/quiche/quic/tools/quic_toy_client.cc:560:13
    #29 0x55d01bb24e12 in main /proc/self/cwd/quiche/quic/tools/quic_client_bin.cc:67:17
    #30 0x7fa55624aca7  (/lib/x86_64-linux-gnu/libc.so.6+0x29ca7) (BuildId: 58749c528985eab03e6700ebc1469fa50aa41219)

==15==Register values:
rax = 0x0000000000000000  rbx = 0x0000000000001401  rcx = 0x00000a3e00000193  rdx = 0x000055d01d018400  
rdi = 0x000051f000000c80  rsi = 0x000050e000000910  rbp = 0x00007ffe3431fde0  rsp = 0x00007ffe3431fda8  
 r8 = 0x00000ff4aa1d1e3e   r9 = 0x000055d01d018400  r10 = 0x000051b00000a0b0  r11 = 0x000029d533e76df0  
r12 = 0x000051b00000a090  r13 = 0x00000ff4aa1d1e51  r14 = 0x00007fa550e8f288  r15 = 0x00000a3600001412  
AddressSanitizer can not provide additional info.
SUMMARY: AddressSanitizer: SEGV (<unknown module>) 
==15==ABORTING

If enabled (bazel build -c dbg), an assertion is triggered:

WARNING: All log messages before absl::InitializeLog() is called are written to STDERR
I0000 00:00:1774337524.791347   38696 quiche_system_event_loop_impl.h:18] Starting event loop for quic_client
I0324 07:32:04.794506   38696 quic_connection.cc:236] Client: Created connection with server connection ID 9120b2ad7523f76f and version: RFCv1
I0324 07:32:04.797540   38696 quic_connection.cc:6380] Client: setting client connection ID to 0 for connection with server connection ID 9120b2ad7523f76f
I0324 07:32:04.801001   38696 tls_client_handshaker.cc:281] Client using ALPN: 'h3'
I0324 07:32:04.801169   38696 transport_parameters.cc:1378] Serialized [Client [chosen_version 00000001 other_versions 00000001] max_idle_timeout 600000 max_udp_payload_size 1472 initial_max_data 15728640 initial_max_stream_data_bidi_local 6291456 initial_max_stream_data_bidi_remote 6291456 initial_max_stream_data_uni 6291456 initial_max_streams_bidi 100 initial_max_streams_uni 103 initial_source_connection_id 0 max_datagram_frame_size 65536] as 85 bytes
I0324 07:32:04.808033   38696 quic_connection.cc:984] Client: Accepting packet with new connection ID 5771f1a58bb8632a instead of 9120b2ad7523f76f
I0324 07:32:04.808211   38696 quic_connection.cc:984] Client: Accepting packet with new connection ID 5771f1a58bb8632a instead of 9120b2ad7523f76f
I0324 07:32:04.808279   38696 quic_connection.cc:3115] Client: Replacing connection ID 9120b2ad7523f76f with 5771f1a58bb8632a
I0324 07:32:04.811019   38696 quic_session.cc:1999] Client: Discarding ENCRYPTION_INITIAL keys
I0324 07:32:04.812903   38696 quic_session.cc:1999] Client: Discarding ENCRYPTION_ZERO_RTT keys
I0324 07:32:04.813210   38696 tls_client_handshaker.cc:600] Client: handshake finished
I0324 07:32:04.813331   38696 transport_parameters.cc:1731] Parsed transport parameters [Server original_destination_connection_id 9120b2ad7523f76f max_idle_timeout 30000 stateless_reset_token 94061ec0b82310202db467749bdaa94f max_udp_payload_size 1472 initial_max_data 4611686018427387903 initial_max_stream_data_bidi_local 1250000 initial_max_stream_data_bidi_remote 1250000 initial_max_stream_data_uni 1250000 initial_max_streams_bidi 100 initial_max_streams_uni 100 min_ack_delay_us 1000 active_connection_id_limit 5 initial_source_connection_id 5771f1a58bb8632a max_datagram_frame_size 65535 0x1993c36c=928d0b16fbceb9e91339 0x2ab2=] from 126 bytes
I0324 07:32:04.813654   38696 quic_session.cc:2940] Client: ALPN selected: h3
I0324 07:32:04.813680   38696 tls_client_handshaker.cc:634] Client: server selected ALPN: 'h3'
I0324 07:32:04.813785   38696 quic_connection.cc:2379] Client: OnDecryptedFirstPacketInKeyPhase
I0324 07:32:04.814109   38696 quic_connection.cc:3747] Client: lowest_packet_sent_in_current_key_phase_ = 5
Connected to localhost:5410
I0324 07:32:04.816569   38696 quic_session.cc:1999] Client: Discarding ENCRYPTION_HANDSHAKE keys
I0324 07:32:04.819782   38696 quic_session.cc:309] Process pending stream 3
I0324 07:32:04.820234   38696 quic_session.cc:309] Process pending stream 11
I0324 07:32:04.820421   38696 quic_session.cc:309] Process pending stream 7
I0324 07:32:04.820616   38696 quic_session.cc:309] Process pending stream 15
I0324 07:32:04.821514   38696 quic_connection.cc:1720] Client: STOP_SENDING frame received for stream: 0 with error: 0
I0324 07:32:04.822356   38696 quic_spdy_client_stream.cc:74] Received informational response code: 129 on stream 0
google-quiche-client: external/abseil-cpp+/absl/functional/internal/any_invocable.h:767: ReturnType absl::internal_any_invocable::Impl<void (const quiche::HttpHeaderBlock &) const>::operator()(P...) const [Sig = void (const quiche::HttpHeaderBlock &) const]: Assertion `this->invoker_ != nullptr' failed.

GDB backtrace:

$ gdb google-quiche-client 
GNU gdb (Debian 16.3-1) 16.3
...
(gdb) run https://localhost:4433 --disable_certificate_verification --stderrthreshold=0 --minloglevel=0
Starting program: /app/google-quiche-client https://localhost:4433 --disable_certificate_verification --stderrthreshold=0 --minloglevel=0
warning: Error disabling address space randomization: Operation not permitted
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
WARNING: All log messages before absl::InitializeLog() is called are written to STDERR
I0000 00:00:1774430355.361900     416 quiche_system_event_loop_impl.h:18] Starting event loop for quic_client
I0325 09:19:15.364462     416 quic_connection.cc:236] Client: Created connection with server connection ID 72b9e86c0ecd02d2 and version: RFCv1
I0325 09:19:15.366093     416 quic_connection.cc:6380] Client: setting client connection ID to 0 for connection with server connection ID 72b9e86c0ecd02d2
I0325 09:19:15.367660     416 tls_client_handshaker.cc:281] Client using ALPN: 'h3'
I0325 09:19:15.367761     416 transport_parameters.cc:1378] Serialized [Client [chosen_version 00000001 other_versions 00000001] max_idle_timeout 600000 max_udp_payload_size 1472 initial_max_data 15728640 initial_max_stream_data_bidi_local 6291456 initial_max_stream_data_bidi_remote 6291456 initial_max_stream_data_uni 6291456 initial_max_streams_bidi 100 initial_max_streams_uni 103 initial_source_connection_id 0 max_datagram_frame_size 65536] as 79 bytes
I0325 09:19:15.369638     416 quic_connection.cc:984] Client: Accepting packet with new connection ID 5ae8229d49576aee instead of 72b9e86c0ecd02d2
I0325 09:19:15.369697     416 quic_connection.cc:984] Client: Accepting packet with new connection ID 5ae8229d49576aee instead of 72b9e86c0ecd02d2
I0325 09:19:15.369740     416 quic_connection.cc:3115] Client: Replacing connection ID 72b9e86c0ecd02d2 with 5ae8229d49576aee
I0325 09:19:15.370837     416 quic_session.cc:1999] Client: Discarding ENCRYPTION_INITIAL keys
I0325 09:19:15.371498     416 quic_session.cc:1999] Client: Discarding ENCRYPTION_ZERO_RTT keys
I0325 09:19:15.371631     416 tls_client_handshaker.cc:600] Client: handshake finished
I0325 09:19:15.371680     416 transport_parameters.cc:1731] Parsed transport parameters [Server original_destination_connection_id 72b9e86c0ecd02d2 max_idle_timeout 30000 stateless_reset_token 4bf91634324fcfbfccacc622c209f036 max_udp_payload_size 1472 initial_max_data 4611686018427387903 initial_max_stream_data_bidi_local 1250000 initial_max_stream_data_bidi_remote 1250000 initial_max_stream_data_uni 1250000 initial_max_streams_bidi 100 initial_max_streams_uni 100 min_ack_delay_us 1000 active_connection_id_limit 5 initial_source_connection_id 5ae8229d49576aee max_datagram_frame_size 65535 0x2ab2= 0xf04f977d=43dca4cca0d2b69f929a9e77] from 128 bytes
I0325 09:19:15.371845     416 quic_session.cc:2940] Client: ALPN selected: h3
I0325 09:19:15.371860     416 tls_client_handshaker.cc:634] Client: server selected ALPN: 'h3'
I0325 09:19:15.371922     416 quic_connection.cc:2379] Client: OnDecryptedFirstPacketInKeyPhase
I0325 09:19:15.372057     416 quic_connection.cc:3747] Client: lowest_packet_sent_in_current_key_phase_ = 5
Connected to localhost:4433
I0325 09:19:15.372614     416 quic_session.cc:1999] Client: Discarding ENCRYPTION_HANDSHAKE keys
I0325 09:19:15.373175     416 quic_session.cc:309] Process pending stream 3
I0325 09:19:15.373334     416 quic_session.cc:309] Process pending stream 11
I0325 09:19:15.373428     416 quic_session.cc:309] Process pending stream 7
I0325 09:19:15.373548     416 quic_session.cc:309] Process pending stream 15
I0325 09:19:15.374102     416 quic_spdy_client_stream.cc:74] Received informational response code: 129 on stream 0
google-quiche-client: external/abseil-cpp+/absl/functional/internal/any_invocable.h:767: ReturnType absl::internal_any_invocable::Impl<void (const quiche::HttpHeaderBlock &) const>::operator()(P...) const [Sig = void (const quiche::HttpHeaderBlock &) const]: Assertion `this->invoker_ != nullptr' failed.

Program received signal SIGABRT, Aborted.
0x00007f5056b2095c in ?? () from /lib/x86_64-linux-gnu/libc.so.6
(gdb) backtrace
#0  0x00007f5056b2095c in ?? () from /lib/x86_64-linux-gnu/libc.so.6
#1  0x00007f5056acbcc2 in raise () from /lib/x86_64-linux-gnu/libc.so.6
#2  0x00007f5056ab44ac in abort () from /lib/x86_64-linux-gnu/libc.so.6
#3  0x00007f5056ab4420 in ?? () from /lib/x86_64-linux-gnu/libc.so.6
#4  0x00005571a81b094b in absl::lts_20260107::internal_any_invocable::Impl<void(quiche::HttpHeaderBlock const&) const>::operator() (this=<optimized out>, args=...)
    at external/abseil-cpp+/absl/functional/internal/any_invocable.h:767
#5  quic::QuicSimpleClientSession::CreateClientStream()::$_0::operator()(quiche::HttpHeaderBlock const&) const (this=<optimized out>, headers=...)
    at quiche/quic/tools/quic_simple_client_session.cc:66
#6  std::__invoke_impl<void, quic::QuicSimpleClientSession::CreateClientStream()::$_0 const&, quiche::HttpHeaderBlock const&>(std::__invoke_other, quic::QuicSimpleClientSession::CreateClientStream()::$_0 const&, quiche::HttpHeaderBlock const&) (__f=..., __args=...) at /usr/lib/gcc/x86_64-linux-gnu/14/../../../../include/c++/14/bits/invoke.h:61
#7  std::__invoke<quic::QuicSimpleClientSession::CreateClientStream()::$_0 const&, quiche::HttpHeaderBlock const&>(quic::QuicSimpleClientSession::CreateClientStream()::$_0 const&, quiche::HttpHeaderBlock const&) (__fn=..., __args=...) at /usr/lib/gcc/x86_64-linux-gnu/14/../../../../include/c++/14/bits/invoke.h:96
#8  std::invoke<quic::QuicSimpleClientSession::CreateClientStream()::$_0 const&, quiche::HttpHeaderBlock const&>(quic::QuicSimpleClientSession::CreateClientStream()::$_0 const&, quiche::HttpHeaderBlock const&) (__fn=..., __args=...) at /usr/lib/gcc/x86_64-linux-gnu/14/../../../../include/c++/14/functional:120
#9  absl::lts_20260107::internal_any_invocable::InvokeR<void, quic::QuicSimpleClientSession::CreateClientStream()::$_0 const&, quiche::HttpHeaderBlock const&>(quic::QuicSimpleClientSession::CreateClientStream()::$_0 const&, quiche::HttpHeaderBlock const&) (f=..., args=...) at external/abseil-cpp+/absl/functional/internal/any_invocable.h:121
#10 absl::lts_20260107::internal_any_invocable::LocalInvoker<false, void, quic::QuicSimpleClientSession::CreateClientStream()::$_0 const&, quiche::HttpHeaderBlock const&> (
--Type <RET> for more, q to quit, c to continue without paging--
    state=<optimized out>, args=...) at external/abseil-cpp+/absl/functional/internal/any_invocable.h:278
#11 0x00005571a81b6446 in absl::lts_20260107::internal_any_invocable::Impl<void(quiche::HttpHeaderBlock const&) const>::operator() (this=0x7fffffffff01, args=...)
    at external/abseil-cpp+/absl/functional/internal/any_invocable.h:767
#12 quic::QuicSimpleClientStream::ParseAndValidateStatusCode (this=<optimized out>) at quiche/quic/tools/quic_simple_client_stream.cc:41
#13 0x00005571a82af0ca in quic::QuicSpdyClientStream::OnInitialHeadersComplete (this=<optimized out>, fin=<optimized out>, frame_len=<optimized out>, header_list=...)
    at quiche/quic/core/http/quic_spdy_client_stream.cc:116
#14 0x00005571a83285fb in quic::QuicSpdyStream::OnStreamHeaderList (this=<optimized out>, fin=<optimized out>, frame_len=<optimized out>, header_list=...)
    at quiche/quic/core/http/quic_spdy_stream.cc:581
#15 0x00005571a8329093 in quic::QuicSpdyStream::OnHeadersDecoded (this=<optimized out>, headers=..., header_list_size_limit_exceeded=<optimized out>)
    at quiche/quic/core/http/quic_spdy_stream.cc:614
#16 0x00005571a838c5bb in quic::QpackDecodedHeadersAccumulator::OnDecodingCompleted (this=<optimized out>) at quiche/quic/core/qpack/qpack_decoded_headers_accumulator.cc:63
#17 0x00005571a83e5970 in quic::QpackProgressiveDecoder::FinishDecoding (this=<optimized out>) at quiche/quic/core/qpack/qpack_progressive_decoder.cc:377
#18 0x00005571a83e5390 in quic::QpackProgressiveDecoder::EndHeaderBlock (this=<optimized out>) at quiche/quic/core/qpack/qpack_progressive_decoder.cc:97
#19 0x00005571a838d231 in quic::QpackDecodedHeadersAccumulator::EndHeaderBlock (this=<optimized out>) at quiche/quic/core/qpack/qpack_decoded_headers_accumulator.cc:95
#20 0x00005571a83351de in quic::QuicSpdyStream::OnHeadersFrameEnd (this=<optimized out>) at quiche/quic/core/http/quic_spdy_stream.cc:1183
#21 0x00005571a8a10038 in quic::HttpDecoder::FinishParsing (this=<optimized out>) at quiche/quic/core/http/http_decoder.cc:475
#22 0x00005571a8a09f74 in quic::HttpDecoder::ProcessInput (this=<optimized out>, data=<optimized out>, len=<optimized out>) at quiche/quic/core/http/http_decoder.cc:128
--Type <RET> for more, q to quit, c to continue without paging--
#23 0x00005571a832f609 in quic::QuicSpdyStream::OnDataAvailable (this=<optimized out>) at quiche/quic/core/http/quic_spdy_stream.cc:872
#24 0x00005571a872d8c2 in quic::QuicStreamSequencer::OnFrameData (this=<optimized out>, byte_offset=<optimized out>, data_len=<optimized out>, data_buffer=<optimized out>)
    at quiche/quic/core/quic_stream_sequencer.cc:118
#25 0x00005571a872b7cd in quic::QuicStreamSequencer::OnStreamFrame (this=<optimized out>, frame=...) at quiche/quic/core/quic_stream_sequencer.cc:65
#26 0x00005571a86dc663 in quic::QuicStream::OnStreamFrame (this=<optimized out>, frame=...) at quiche/quic/core/quic_stream.cc:533
#27 0x00005571a8648ad1 in quic::QuicSession::OnStreamFrame (this=<optimized out>, frame=...) at quiche/quic/core/quic_session.cc:389
#28 0x00005571a8431ab8 in quic::QuicConnection::OnStreamFrame (this=<optimized out>, frame=...) at quiche/quic/core/quic_connection.cc:1458
#29 0x00005571a85382cd in quic::QuicFramer::ProcessIetfFrameData (this=<optimized out>, reader=<optimized out>, header=..., decrypted_level=<optimized out>)
    at quiche/quic/core/quic_framer.cc:2839
#30 0x00005571a852e33e in quic::QuicFramer::ProcessIetfDataPacket (this=<optimized out>, encrypted_reader=<optimized out>, header=<optimized out>, packet=..., 
    decrypted_buffer=<optimized out>, buffer_length=<optimized out>) at quiche/quic/core/quic_framer.cc:1920
#31 0x00005571a8527a4b in quic::QuicFramer::ProcessPacketInternal (this=<optimized out>, packet=...) at quiche/quic/core/quic_framer.cc:1536
#32 0x00005571a8526efe in quic::QuicFramer::ProcessPacket (this=<optimized out>, packet=...) at quiche/quic/core/quic_framer.cc:1475
#33 0x00005571a84585ab in quic::QuicConnection::ProcessUdpPacket (this=<optimized out>, self_address=..., peer_address=..., packet=...)
    at quiche/quic/core/quic_connection.cc:2816
#34 0x00005571a865e9fb in quic::QuicSession::ProcessUdpPacket (this=<optimized out>, self_address=..., peer_address=..., packet=...) at quiche/quic/core/quic_session.cc:1003
#35 0x00005571a818ba06 in quic::QuicPacketReader::ReadAndDispatchPackets (this=<optimized out>, fd=<optimized out>, port=<optimized out>, clock=..., processor=<optimized out>)
--Type <RET> for more, q to quit, c to continue without paging--
    at quiche/quic/core/quic_packet_reader.cc:118
#36 0x00005571a8151f5a in quic::QuicClientDefaultNetworkHelper::OnSocketEvent (this=<optimized out>, fd=<optimized out>, events=<optimized out>)
    at quiche/quic/tools/quic_client_default_network_helper.cc:158
#37 0x00005571a812f46c in quic::QuicPollEventLoop::RunReadyCallbacks (this=<optimized out>, ready_list=...) at quiche/quic/core/io/quic_poll_event_loop.cc:207
#38 0x00005571a812d9e8 in quic::QuicPollEventLoop::ProcessIoEvents (this=<optimized out>, start_time=..., timeout=...) at quiche/quic/core/io/quic_poll_event_loop.cc:174
#39 0x00005571a812cf7e in quic::QuicPollEventLoop::RunEventLoopOnce (this=0x50d000000110, default_timeout=...) at quiche/quic/core/io/quic_poll_event_loop.cc:89
#40 0x00005571a819ffd7 in quic::QuicClientBase::WaitForEvents (this=<optimized out>) at quiche/quic/tools/quic_client_base.cc:284
#41 0x00005571a81baa16 in quic::QuicSpdyClientBase::SendRequestAndWaitForResponse (this=0x51e000000080, headers=..., body=..., fin=<optimized out>)
    at quiche/quic/tools/quic_spdy_client_base.cc:129
#42 0x00005571a811bfe1 in quic::QuicToyClient::SendRequestsAndPrintResponses (this=<optimized out>, urls=...) at quiche/quic/tools/quic_toy_client.cc:560
#43 0x00005571a8115cc3 in main (argc=<optimized out>, argv=<optimized out>) at quiche/quic/tools/quic_client_bin.cc:67

Reproduce

The client can be built and started using the provided Dockerfile:

docker build -t google-quiche .
docker run -it \
    --init \
    --name google-quiche \
    -e SERVER_HOST="localhost" \
    -e SERVER_PORT="4433" \
    -e SERVER_PATH="/" \
    -e SERVER_CERT="/tmp/secrets/cert.pem" \
    -e SERVER_CERT_DER="/tmp/secrets/cert.der" \
    -v "$(pwd)/secrets:/tmp/secrets:ro" \
    --network host \
    -d \
    google-quiche:latest

We apply mutations to a QUIC server's source code during compilation. The mutated QUIC server can be found here: https://next.hessenbox.de/index.php/s/eq5iyQDp8gM38Cy

mutated-quic-server --cert secrets/cert.der --key secrets/key.der --listen "[::]:4433"

Dockerfile:

FROM debian:trixie-slim AS builder

RUN apt-get update && \
    apt-get install -y git clang llvm libc++-dev curl libicu-dev build-essential gcc g++ libc6-dev python3 unzip zip && \
    apt-get clean && rm -rf /var/lib/apt/lists/*

RUN curl -Lo /usr/local/bin/bazel https://github.com/bazelbuild/bazelisk/releases/latest/download/bazelisk-linux-amd64 && \
    chmod +x /usr/local/bin/bazel

WORKDIR /app

RUN git clone https://github.com/google/quiche && \
    cd quiche && \
    git checkout 46457a0876312ffe24ef55c43a7c9458631205c7 && \
    CC=clang CXX=clang++ bazel build -c opt \
    --copt=-O2 --cxxopt=-O2 \
    --cxxopt=-include --cxxopt=cstdint \
    --cxxopt=-g --cxxopt=-fno-omit-frame-pointer \
    --cxxopt=-fsanitize=address --linkopt=-fsanitize=address \
    --cxxopt=-fprofile-instr-generate --linkopt=-fprofile-instr-generate \
    --cxxopt=-fcoverage-mapping --linkopt=-fcoverage-mapping \
    --cxxopt=-mllvm \
    --cxxopt=-runtime-counter-relocation \
    --cxxopt=-fprofile-update=atomic \
    --cxxopt=-Qunused-arguments \
    //quiche:quic_client

FROM debian:trixie-slim

RUN apt-get update && \
    apt-get install -y ca-certificates libasan8 llvm clang libicu76 && \
    apt-get clean && rm -rf /var/lib/apt/lists/*

ENV ASAN_SYMBOLIZER_PATH=/usr/bin/llvm-symbolizer

WORKDIR /app

COPY --from=builder /app/quiche/bazel-bin/quiche/quic_client /app/google-quiche-client

COPY ./entrypoint.sh /app/entrypoint.sh
RUN chmod +x /app/entrypoint.sh

ENV LLVM_PROFILE_FILE="/coverage/google-quiche-%p%c.profraw"

ENTRYPOINT ["/app/entrypoint.sh"]

entrypoint.sh

#!/bin/sh

exec /app/google-quiche-client https://$SERVER_HOST:$SERVER_PORT/ --disable_certificate_verification --stderrthreshold=0 --minloglevel=0

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions