trafficserver
trafficserver copied to clipboard
Quic crash in XpackDynamicTable::lookup, division by 0
I reproduced the following crash via gdb in docs running ATS 10 with Alt-Svc:
(gdb) bt
#0 0x000055555659ec46 in XpackDynamicTable::lookup (this=0x61200008e710, name=0x6190001072a2 "date", name_len=4,
value=0x6250006a2021 "Thu, 22 Feb 2024 21:01:35 GMT\r\nEtag: \"106f0-611fa4b0e79c0\"\r\nConnection: keep-alive\r\nStrict-Transport-Security: max-age=17280000\r\nVia: http/1.1 traffic_server (ApacheTrafficServer/10.0.0 [cHs f ])\r\nSer"...,
value_len=29) at /home/bneradt/src/trafficserver_10/src/proxy/hdrs/XPACK.cc:268
#1 0x0000555556ac6007 in QPACK::_encode_header (this=0x61200008e6c0, field=..., base_index=0, compressed_header=0x607000082150, referred_index=@0x7fffef6c55a0: 0) at /home/bneradt/src/trafficserver_10/src/proxy/http3/QPACK.cc:371
#2 0x0000555556ac4b4e in QPACK::encode (this=0x61200008e6c0, stream_id=12, header_set=..., header_block=0x61100003d800, header_block_len=@0x61100003c6b0: 0) at /home/bneradt/src/trafficserver_10/src/proxy/http3/QPACK.cc:230
#3 0x0000555556ab7206 in Http3HeaderFramer::_generate_header_block (this=0x61100003c680) at /home/bneradt/src/trafficserver_10/src/proxy/http3/Http3HeaderFramer.cc:106
#4 0x0000555556ab68bf in Http3HeaderFramer::generate_frame (this=0x61100003c680) at /home/bneradt/src/trafficserver_10/src/proxy/http3/Http3HeaderFramer.cc:58
#5 0x0000555556aae964 in Http3FrameCollector::on_write_ready (this=0x626000248b90, stream_id=12, writer=..., nwritten=@0x7fffef6c5a80: 0, all_done=@0x7fffef6c5a70: true)
at /home/bneradt/src/trafficserver_10/src/proxy/http3/Http3FrameCollector.cc:39
#6 0x0000555556aa8af6 in Http3Transaction::_process_write_vio (this=0x626000246100) at /home/bneradt/src/trafficserver_10/src/proxy/http3/Http3Transaction.cc:604
#7 0x0000555556aa2865 in HQTransaction::do_io_write (this=0x626000246100, c=0x62600024aa58, nbytes=281, buf=0x61100003d700, owner=false) at /home/bneradt/src/trafficserver_10/src/proxy/http3/Http3Transaction.cc:152
#8 0x000055555630738b in HttpTunnel::producer_run (this=0x62600024aa58, p=0x62600024ae28) at /home/bneradt/src/trafficserver_10/src/proxy/http/HttpTunnel.cc:995
#9 0x0000555556304edb in HttpTunnel::tunnel_run (this=0x62600024aa58, p_arg=0x62600024ae28) at /home/bneradt/src/trafficserver_10/src/proxy/http/HttpTunnel.cc:735
#10 0x0000555556236698 in HttpSM::setup_internal_transfer (this=0x626000249100, handler_arg=(int (HttpSM::*)(HttpSM * const, int, void *)) 0x55555620cb94 <HttpSM::tunnel_handler(int, void*)>)
at /home/bneradt/src/trafficserver_10/src/proxy/http/HttpSM.cc:6900
#11 0x00005555561fe8b5 in HttpSM::handle_api_return (this=0x626000249100) at /home/bneradt/src/trafficserver_10/src/proxy/http/HttpSM.cc:1646
#12 0x00005555561fd673 in HttpSM::state_api_callout (this=0x626000249100, event=60000, data=0x0) at /home/bneradt/src/trafficserver_10/src/proxy/http/HttpSM.cc:1483
#13 0x00005555561fbc89 in HttpSM::state_api_callback (this=0x626000249100, event=60000, data=0x0) at /home/bneradt/src/trafficserver_10/src/proxy/http/HttpSM.cc:1287
#14 0x00007ffff74a07c1 in TSHttpTxnReenable (BFD: reopening /opt/ats/var/trafficserver/99436728-1cf6-4fbe-9afa-9bbe39c07051/opt/ats/libexec/trafficserver/conf_remap.so: No such file or directory
...
#15 0x00007fffeb713379 in cont_rewrite_headers (contp=0x7fffeffee800, event=25184, edata=0x60400004fb50) at /home/bneradt/src/trafficserver_10/plugins/header_rewrite/header_rewrite.cc:308
#16 0x00005555562a03dd in HttpTransact::HandleRequestAuthorized (s=0x61000001aa60) at /home/bneradt/src/trafficserver_10/src/proxy/http/HttpTransact.cc:2082
#17 0x0000555556b037a3 in INKContInternal::handle_event (this=0x61000001aa40, event=60007, edata=0x626000249100) at /home/bneradt/src/trafficserver_10/src/api/InkContInternal.cc:153
#18 0x00005555560b73f7 in Continuation::handleEvent (this=0x61000001aa40, event=60007, data=0x626000249100) at /home/bneradt/src/trafficserver_10/include/iocore/eventsystem/Continuation.h:228
#19 0x0000555556b06819 in APIHook::invoke (this=0x60400004fc50, event=60007, edata=0x626000249100) at /home/bneradt/src/trafficserver_10/src/api/APIHook.cc:60
#20 0x00005555561fce80 in HttpSM::state_api_callout (this=0x626000249100, event=60000, data=0x0) at /home/bneradt/src/trafficserver_10/src/proxy/http/HttpSM.cc:1407
#21 0x00005555561fbc89 in HttpSM::state_api_callback (this=0x626000249100, event=60000, data=0x0) at /home/bneradt/src/trafficserver_10/src/proxy/http/HttpSM.cc:1287
#22 0x00007ffff74a07c1 in TSHttpTxnReenable (txnp=0x626000249100, event=TS_EVENT_HTTP_CONTINUE) at /home/bneradt/src/trafficserver_10/src/api/InkAPI.cc:4930
#23 0x00007fffeb713379 in cont_rewrite_headers (contp=0x7fffeffee800, event=25184, edata=0x7fffef6c69a8) at /home/bneradt/src/trafficserver_10/plugins/header_rewrite/header_rewrite.cc:308
This is running 10.0.x with the commits from https://github.com/apache/trafficserver/pull/11088 applied on top of fbd21285153c7a2814724bf2cb1cd8a0cde45cc3.
Looks like the problem is a division by zero here:
(gdb) p *this
$2 = {static ADDITIONAL_32_BYTES = 32 ' ', _maximum_size = 0, _available = 0, _entries_inserted = 0, _entries = 0x0, _max_entries = 0, _entries_head = 4294967295, _entries_tail = 4294967295, _storage = {_overwrite_threshold = 0, _data = 0x0,
_data_size = 0, _head = 4294967295, _tail = 4294967295}}
(gdb) l
263 const XpackLookupResult
264 XpackDynamicTable::lookup(const char *name, size_t name_len, const char *value, size_t value_len) const
265 {
266 XPACKDebug("Lookup entry: name=%.*s, value=%.*s", static_cast<int>(name_len), name, static_cast<int>(value_len), value);
267 XpackLookupResult::MatchType match_type = XpackLookupResult::MatchType::NONE;
268 uint32_t i = (this->_entries_tail + 1) % this->_max_entries;
269 uint32_t end = (this->_entries_head + 1) % this->_max_entries;
270 uint32_t candidate_index = 0;
271 const char *tmp_name = nullptr;
272 const char *tmp_value = nullptr;
(gdb) f
#0 0x000055555659ec46 in XpackDynamicTable::lookup (this=0x61200008e710, name=0x6190001072a2 "date", name_len=4,
value=0x6250006a2021 "Thu, 22 Feb 2024 21:01:35 GMT\r\nEtag: \"106f0-611fa4b0e79c0\"\r\nConnection: keep-alive\r\nStrict-Transport-Security: max-age=17280000\r\nVia: http/1.1 traffic_server (ApacheTrafficServer/10.0.0 [cHs f ])\r\nSer"...,
value_len=29) at /home/bneradt/src/trafficserver_10/src/proxy/hdrs/XPACK.cc:268
268 uint32_t i = (this->_entries_tail + 1) % this->_max_entries;
(gdb) p this->_max_entries
$3 = 0
To provide a bit more context in case it's helpful:
(gdb) f 1
#1 0x0000555556ac6007 in QPACK::_encode_header (this=0x61200008e6c0, field=..., base_index=0, compressed_header=0x607000082150, referred_index=@0x7fffef6c55a0: 0) at /home/bneradt/src/trafficserver_10/src/proxy/http3/QPACK.cc:371
371 lookup_result_dynamic = this->_dynamic_table.lookup(lowered_name, name_len, value, value_len);
(gdb) p *this
$6 = {<QUICApplication> = {<Continuation> = {<force_VFPT_to_top> = {_vptr.force_VFPT_to_top = 0x5555572cb7b0 <vtable for QPACK+16>}, handler = (int (Continuation::*)(Continuation * const, int,
void *)) 0x555556ac4748 <QPACK::event_handler(int, Event*)>, handler_name = 0x55555706b520 "&QPACK::event_handler", mutex = {m_ptr = 0x60c000034600}, link = {<SLink<Continuation>> = {next = 0x0}, prev = 0x0}, control_flags = {raw_flags = 0},
thread_affinity = 0x0}, _qc = 0x61b000041ec8}, _dynamic_table = {static ADDITIONAL_32_BYTES = 32 ' ', _maximum_size = 0, _available = 0, _entries_inserted = 0, _entries = 0x0, _max_entries = 0, _entries_head = 4294967295,
_entries_tail = 4294967295, _storage = {_overwrite_threshold = 0, _data = 0x0, _data_size = 0, _head = 4294967295, _tail = 4294967295}}, _references = std::map with 0 elements, _max_field_section_size = 4294967295, _max_table_size = 0,
_max_blocking_streams = 0, _event_handler = 0x0, _invalid = false, _blocked_list = {_head = 0x0, _tail = 0x0, _count = 0}, _largest_known_received_index = 0, _encoder_stream_id = 0, _decoder_stream_id = 9999,
_encoder_stream_sending_instructions = 0x61100003b140, _decoder_stream_sending_instructions = 0x61100003b280, _encoder_stream_sending_instructions_reader = 0x61100003b158, _decoder_stream_sending_instructions_reader = 0x61100003b298, _arena = {
m_blocks = 0x619000107280}}