[ruby/resolv] Limit decompressed name length

RFC 1035 specifies the 255-octet maximum name length. This change set
checks the limit.

4c2f71b5e8
This commit is contained in:
Yusuke Endoh 2025-07-08 16:19:30 +09:00 committed by git
parent 680383c642
commit 9aa0300db2
2 changed files with 12 additions and 1 deletions

View file

@ -1679,6 +1679,7 @@ class Resolv
prev_index = @index prev_index = @index
save_index = nil save_index = nil
d = [] d = []
size = -1
while true while true
raise DecodeError.new("limit exceeded") if @limit <= @index raise DecodeError.new("limit exceeded") if @limit <= @index
case @data.getbyte(@index) case @data.getbyte(@index)
@ -1699,7 +1700,10 @@ class Resolv
end end
@index = idx @index = idx
else else
d << self.get_label l = self.get_label
d << l
size += 1 + l.string.bytesize
raise DecodeError.new("name label data exceed 255 octets") if size > 255
end end
end end
end end

View file

@ -627,6 +627,13 @@ class TestResolvDNS < Test::Unit::TestCase
assert_operator(2**14, :<, m.to_s.length) assert_operator(2**14, :<, m.to_s.length)
end end
def test_too_long_address
too_long_address_message = [0, 0, 1, 0, 0, 0].pack("n*") + "\x01x" * 129 + [0, 0, 0].pack("cnn")
assert_raise_with_message(Resolv::DNS::DecodeError, /name label data exceed 255 octets/) do
Resolv::DNS::Message.decode too_long_address_message
end
end
def assert_no_fd_leak def assert_no_fd_leak
socket = assert_throw(self) do |tag| socket = assert_throw(self) do |tag|
Resolv::DNS.stub(:bind_random_port, ->(s, *) {throw(tag, s)}) do Resolv::DNS.stub(:bind_random_port, ->(s, *) {throw(tag, s)}) do