ndb-dns-redistrib-size: one large UDP query kills the ndb/dns UDP server
sys/src/cmd/ndb/dnudpserver.c reads each datagram into a buffer of
Udphdrsize+Maxpayload bytes, then redistrib() copies it into a
static 1500-byte buffer behind
assert(len <= sizeof outpkt);
A datagram with more than 1448 bytes of DNS payload fails the
assertion and the UDP server aborts. It is forked RFNOWAIT and
nothing restarts it; TCP service carries on. redistrib() runs
whether or not -T is given, so every ndb/dns -s is exposed.
The fix sizes outpkt like every other UDP buffer in ndb/dns.
Apply
cd /
ape/patch -p0 < /path/to/ndb-dns-redistrib-size/ndb-dns-redistrib-size.diff
Rebuild
cd /sys/src/cmd/ndb && mk dns.safeinstall
The old binary is kept as /$objtype/bin/ndb/odns. Then restart
ndb/dns; rebooting is simplest.
Verification
python3 -c "import socket; socket.socket(socket.AF_INET,
socket.SOCK_DGRAM).sendto(b'\0'*1600, ('<server>', 53))"
dig SOA <your-zone> @<server>
The datagram must leave in one piece; nc(1) may split its
input into several smaller datagrams.
Before: the console prints the assertion and dig times out.
After: dig is answered.
|