From 5be92c41e0d487d4f729db568001df91612dc3b0 Mon Sep 17 00:00:00 2001 From: dxbjavid Date: Sat, 13 Jun 2026 17:39:53 +0530 Subject: [PATCH] fix off-by-ten header bounds check in readHeaderFormat --- .../src/thrift/transport/THeaderTransport.cpp | 5 +++- lib/cpp/test/ThrifttReadCheckTests.cpp | 23 +++++++++++++++++++ 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/lib/cpp/src/thrift/transport/THeaderTransport.cpp b/lib/cpp/src/thrift/transport/THeaderTransport.cpp index 70510d95c45..cdf29cf3d53 100644 --- a/lib/cpp/src/thrift/transport/THeaderTransport.cpp +++ b/lib/cpp/src/thrift/transport/THeaderTransport.cpp @@ -222,7 +222,10 @@ void THeaderTransport::readHeaderFormat(uint16_t headerSize, uint32_t sz) { } headerSize *= 4; const uint8_t* const headerBoundary = ptr + headerSize; - if (headerSize > sz) { + // ptr already skips the 10-byte common header, so the header section has to + // fit in the remaining sz - 10 bytes; comparing against sz alone let the + // boundary sit up to 10 bytes past the receive buffer. + if (headerSize > sz - 10) { throw TTransportException(TTransportException::CORRUPTED_DATA, "Header size is larger than frame"); } diff --git a/lib/cpp/test/ThrifttReadCheckTests.cpp b/lib/cpp/test/ThrifttReadCheckTests.cpp index d62f66330ad..7abcff8bd32 100644 --- a/lib/cpp/test/ThrifttReadCheckTests.cpp +++ b/lib/cpp/test/ThrifttReadCheckTests.cpp @@ -31,6 +31,7 @@ #include #include #include +#include #include #include #include @@ -317,4 +318,26 @@ BOOST_AUTO_TEST_CASE(test_tthriftjsonprotocol_read_check_exception) { protocol->readMapEnd(); } +BOOST_AUTO_TEST_CASE(test_theadertransport_header_size_exceeds_frame) { + using apache::thrift::transport::THeaderTransport; + // Header-format frame whose declared header size (3 * 4 = 12) leaves fewer + // than the 10 common-header bytes inside the 14-byte frame. The trailing + // varint bytes are all continuation bytes, so the reader used to run off the + // end of the receive buffer. + uint8_t frame[] = { + 0x00, 0x00, 0x00, 0x0E, // frame length = 14 + 0x0F, 0xFF, 0x00, 0x00, // header magic + 0x00, 0x00, 0x00, 0x00, // seqId + 0x00, 0x03, // header size field (3 -> 12 bytes) + 0x02, // protocol id varint + 0x00, // num transforms = 0 + 0x80, 0x80 // info-header varint, all continuation + }; + std::shared_ptr buffer(new TMemoryBuffer(frame, sizeof(frame))); + std::shared_ptr trans(new THeaderTransport(buffer)); + + uint8_t out[1]; + BOOST_CHECK_THROW(trans->read(out, sizeof(out)), TTransportException); +} + BOOST_AUTO_TEST_SUITE_END()