Dmytro Shteflyuk created THRIFT-6131:
----------------------------------------
Summary: Bound Ruby HeaderTransport varint32 parsing
Key: THRIFT-6131
URL: https://issues.apache.org/jira/browse/THRIFT-6131
Project: Thrift
Issue Type: Bug
Components: Ruby - Library
Reporter: Dmytro Shteflyuk
Assignee: Dmytro Shteflyuk
h3. Problem
Ruby HeaderTransport accepts a variable-length uint32 until the Header boundary
rather than enforcing the five-byte width of a uint32. A malformed Header with
continuation bytes can therefore be read across the full Header area before
rejection.
h3. Client impact
A malformed Header frame can spend unnecessary time in Ruby parsing before it
is rejected. HeaderTransport should reject an overlong or out-of-range uint32
at the fifth byte while retaining valid five-byte values.
h3. Reproduction
On an unpatched checkout, from the repository root, run:
{code:sh}
cd lib/rb
bundle exec ruby -Ilib -e '
require "thrift"
header_data = "\x80".b * 65_532
frame = [10 + header_data.bytesize].pack("N")
frame << [Thrift::HeaderTransport::HEADER_MAGIC].pack("n")
frame << [0].pack("n")
frame << [0].pack("N")
frame << [header_data.bytesize / 4].pack("n")
frame << header_data
transport =
Thrift::HeaderTransport.new(Thrift::MemoryBufferTransport.new(frame))
started = Process.clock_gettime(Process::CLOCK_MONOTONIC)
begin
transport.read(1)
rescue Thrift::TransportException => error
elapsed = Process.clock_gettime(Process::CLOCK_MONOTONIC) - started
puts "#{error.message}; elapsed=#{format("%.4f", elapsed)}s"
end
'
{code}
The pre-change reader was executed from base {{4e9e407e}} against this frame in
the dedicated pure-Ruby container. It consumed all 65,532 continuation bytes
and printed:
{code}
Trying to read past header boundary; elapsed=0.0085s
{code}
h3. Expected behavior
HeaderTransport accepts at most five varint32 bytes. The fifth byte must
terminate and contain only {{0x00..0x0f}}. A fifth-byte continuation is
rejected as overlong, and a terminating fifth byte above {{0x0f}} is rejected
as a uint32 overflow.
--
This message was sent by Atlassian Jira
(v8.20.10#820010)