resolv
resolv copied to clipboard
crash when query long TXT RRs
Reproducible code
irb(main):001:0> require 'resolv'
irb(main):002:0> Resolv::DNS.new.getresources('google.com', Resolv::DNS::Resource::IN::TXT)
Expected result:
Returns TXT records (see below)
Actual result:
.../resolv.rb:898:in `recv_reply': undefined method `unpack' for nil:NilClass (NoMethodError)
from .../resolv.rb:687:in `request'
from .../resolv.rb:531:in `block in fetch_resource'
from .../lib/resolv.rb:1125:in `block (3 levels) in resolv'
from .../lib/resolv.rb:1123:in `each'
from .../lib/resolv.rb:1123:in `block (2 levels) in resolv'
from .../lib/resolv.rb:1122:in `each'
from .../lib/resolv.rb:1122:in `block in resolv'
from .../lib/resolv.rb:1120:in `each'
from .../lib/resolv.rb:1120:in `resolv'
from .../lib/resolv.rb:521:in `fetch_resource'
from .../lib/resolv.rb:507:in `each_resource'
from .../lib/resolv.rb:498:in `getresources'
from (irb):2:in `<main>'
Current TXT records of google.com
$ dig txt google.com
; <<>> DiG 9.16.1-Ubuntu <<>> txt google.com
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 5232
;; flags: qr rd ra; QUERY: 1, ANSWER: 9, AUTHORITY: 0, ADDITIONAL: 1
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 1232
;; QUESTION SECTION:
;google.com. IN TXT
;; ANSWER SECTION:
google.com. 3600 IN TXT "docusign=1b0a6754-49b1-4db5-8540-d2c12664b289"
google.com. 3600 IN TXT "facebook-domain-verification=22rm551cu4k0ab0bxsw536tlds4h95"
google.com. 3600 IN TXT "v=spf1 include:_spf.google.com ~all"
google.com. 3600 IN TXT "globalsign-smime-dv=CDYX+XFHUw2wml6/Gb8+59BsH31KzUr6c1l2BPvqKX8="
google.com. 3600 IN TXT "MS=E4A68B9AB2BB9670BCE15412F62916164C0B20BB"
google.com. 3600 IN TXT "apple-domain-verification=30afIBcvSuDV2PLX"
google.com. 3600 IN TXT "docusign=05958488-4752-4ef2-95eb-aa7ba8a3bd0e"
google.com. 3600 IN TXT "google-site-verification=wD8N7i1JTNTkezJ49swvWW48f8_9xveREV4oB-0Hf5o"
google.com. 3600 IN TXT "google-site-verification=TV9-DBe4R80X4v0M4U_bd_J9cpOJM0nikft0jAgjmsQ"
;; Query time: 48 msec
;; SERVER: 127.0.0.53#53(127.0.0.53)
;; WHEN: 水 9月 08 15:29:15 JST 2021
;; MSG SIZE rcvd: 625
I was unable to reproduce this error in the current master of resolv and Ruby 3.2.
The error is caused by a failure to read the length of TCP message so it looks related to TCP fallback, but is not the same problem as #6, which fails to decode the truncated UDP message.
As the dig
result shows SERVER: 127.0.0.53#53(127.0.0.53)
, the direct nameserver seems to be systemd-resolved's stub listener. IIRC, it had bugs regarding truncation or TCP fallback in the past (I can't find the exact report or fix, but https://github.com/systemd/systemd/pull/6988 may be related).
The reported exception suggests that the TCP socket was closed before sending the message length, and resolv does't handle such a protocol violation. Here we need to check if read(2)
actually returns 2 octets:
https://github.com/ruby/resolv/blob/b25c63cf7cef2b298a47634fcb50ae1ec288d7df/lib/resolv.rb#L899-L903