Commit Graph
169 Commits
Author SHA1 Message Date
Simon Kelley 014e909f78 Rework storage allocation for domain names. CVE-2026-2291
This is the stable release fix for CVE-2026-2291

Dnsmasq recieves and sends domain names within DNS packets in RFC-1035
format, a string of counted labels terminated by a zero length label.
Internally to dnsmasq, domain names are represented as zero-terminated C strings
with the labels seperated by '.' characters, like the normal presentation
format for domain names.

The RFC-1035 limit for a domain name in wire format is 255 octets, and
when converted to presentation format, this makes a string of
maximum 253 characters. However dnsmasq needs to be able to
represent any 8-bit character within a label, and this causes
problems with /000 (which would terminate the c-string early) and
'.' (which would terminate a label early). To avoid this, dnsmasq
escapes both of these characters, which means that they take two bytes
in the string. The domain name with must charaters in it has four labels
and the 255 octet wire length limits these four labels to a total of
250 characters. The other five octets are the four label length bytes
and the zero length byte terminator. If all 250 characters need escaping
that makes the maximum length of the dnsmasq internal format 503
characters (250 escaped characters in labels, amd three dots between
four labels) Since this format is zero-terminated c-string, buffers
have to be allocated as 504 bytes.

This arrangement grew in a somewhat ad-hoc manner and early dnsmasq
didn't do the escaping trick, and didn't really differentiate between
the lengths of the wire format and the presentation format, since
they were very similar. It also, for reasons lost in time, inherited
a defintion for MAXDNAME from early BIND headers, set at 1025 bytes.
This value was used as the buffer size for both wire and presentation
formats.

This patch makes everything consistent. It declares two constants

MAXDNAME 255     /* max size of wire format domain name */
MAXDNAMESTR 503  /* max size of internal format created from a 255 octet wire format name */

All internal name buffers are allocated as MAXDNAMESTR+1 bytes,
to hold a maximum size internal format name and zero termination.

Names parsed out of incoming packets are rejected if their
wire format is greater than 255 bytes, which ensures that
their internal representation cannot exceed 503 characters.
Names inserted into outgoing packets are failed similarly if
they exceed 255 bytes. (this would in theory be possible
for a legal internal-representaion name if it has at least
one unescaped character in a label.
2026-05-10 21:49:39 +01:00
Simon Kelley d158aeca75 Increase default limit on TCP handler processes from 20 to 30.
There's evidence that modern Chrome may need this. It has been 20
forever, and hardware inflation would support an increase.

https://lists.thekelleys.org.uk/pipermail/dnsmasq-discuss/2026q2/018450.html
2026-04-21 22:27:07 +01:00
Simon Kelley cfc2244c2a Bump copyrights to 2026. 2026-04-08 12:08:18 +01:00
Simon Kelley ceab392c60 Improve memory allocation for /etc/hosts etc.
Clearing and reloading the DNS cache involved freeing and re-allocating
many small memory blocks. Doing this frequently with a significant
number of static DNS configuraions or DHCP leases could result
in excessive heap fragmentation and memory use.

This patch extends the pool memory allocation technique used
else where to this memory. On cache clear, the memory is not
freed, but added to a pool of useable but unused data structures
which get re-used to store the new data.
2026-02-05 13:26:08 +00:00
Matthias Andree e1faf705c9 Support Inotify in FreeBSD.
FreeBSD 15.0 has added Linux-compatible inotify support, so
enable it by looking if the version matches. Since FreeBSD inotify has
seen a few bug fixes in 2025H2, so only enable it if
__FreeBSD_version >= 1500068.  The latter can be checked through
osreldate.h or sys/param.h; the latter defines more macros that clash
with dnsmasq's, such as MIN and MAX, so use the former.
2026-01-14 20:08:41 +00:00
Simon Kelley bceb5287b9 Fix FTBFS on MacOS.
Fallout from 98189ff988

Thanks to Travis Rayan for the bug report.
2025-07-07 17:58:41 +01:00
Simon Kelley 2b19285724 Fix breakage of ipset on *BSD.
Regression introduced in 98189ff988

Thanks to Harper Andrews for spotting this.
2025-06-20 15:48:47 +01:00
Simon Kelley ebef27f321 Add TFTP options windowsize (RFC 7440) and timeout (RFC 2349). 2025-05-24 14:41:40 +01:00
Simon Kelley 98189ff988 Fix problems with ipset or nftset and TCP DNS transport.
If DNS is happening over TCP, the query is handled by a forked
process. Of ipset ot nftset is configured, this might include
inserting addresses in the *sets. Before this update, that
was done by the forked process using handles inherited from the
parent "master" process.

This is inherently racy. If the master process or another
child process tries to do updates at the same time, the
updates can clash and fail.

To see this, you need a busy server doing lots of DNS
queries over TCP, and ipset or nftset configured.

Going forward, we use the already established pipe to send the
updates from the child back to the master process, which
serialises them.
2025-05-08 16:07:19 +01:00
Simon Kelley 57f0489f38 Redesign the interaction between DNSSEC vaildation and per-domain servers.
This should just work in all cases now. If the normal chain-of-trust exists into
the delegated domain then whether the domain is signed or not, DNSSEC
validation will function normally. In the case the delgated domain
is an "overlay" on top of the global DNS and no NS and/or DS records
exist connecting it to the global dns, then if the domain is
unsigned the situation will be handled by synthesising a
proof-of-non-existance-of-DS for the domain and queries will be
answered unvalidated; this action will be logged. A signed domain
without chain-of-trust can be validated if a suitable trust-anchor
is provided using --trust-anchor.

Thanks to Uwe Kleine-König for prompting this change, and contributing
valuable insights into what could be improved.
2025-03-14 15:12:45 +00:00
Simon Kelley 6e6a45a7d9 Bump copyrights to 2025. 2025-01-23 17:08:39 +00:00
Simon Kelley 5d894620b4 Extend build fingerprinting to include CFLAGS.
If the value of CFLAGS is changed between builds, the makefile
will rebuid, in the same way as for COPTS.
2025-01-17 16:48:08 +00:00
Simon Kelley 509afcd1d2 Refactor poll() loop.
Handling events on file descriptors can result in new file
descriptors being created or old ones being deleted. As such
the results of the last call to poll() become invalid in subtle
ways.

After handling each file descriptor in  check_dns_listeners()
return, to go around the poll() loop again and get valid data
for the new situation.

Thanks to Dominik Derigs for his indefatigable sleuthing of this one.
2025-01-12 21:36:09 +00:00
Simon Kelley b58276a73c Return EDE OTHER error when DNSSEC validation abandoned.
This distinguishes the case where we found a message was bogus
from cases where the process failed.
2025-01-12 16:00:09 +00:00
Simon Kelley 32a8f3e009 Finesse TCP timeouts for upstream connections.
Timeouts for TCP connections to non-responive servers are very long.
This in not appropriate for DNS connections.

Set timeouts for connection setup, sending data and recieving data.
The timeouts for connection setup and sending data are set at 5 seconds.
For recieving the reply this is doubled, to take into account the
time for usptream to actually get the answer.

Thanks to Petr Menšík for pointing out this problem, and finding a better
and more portable solution than the one in place heretofore.
2024-11-25 23:18:07 +00:00
Simon Kelley f04cf8506a Simplify EDNS0 packet size handling.
In the post 2020 flag-day world, we limit UDP packets to 1232 bytes
which can go anywhere, so the dodgy code to try and determine the
functional maxmimum packet size on the path from upstream servers
is obsolete.
2024-11-24 23:06:22 +00:00
Simon Kelley 1b76e1c8ec Remove hash-questions.c - no longer required. 2024-11-02 21:29:47 +00:00
Simon Kelley 3ae7f1ab0d Add --dnssec-limits option. 2024-02-12 23:11:35 +00:00
Simon Kelley 3c91bca943 Better stats and logging from DNSSEC resource limiting. 2024-02-12 23:11:35 +00:00
Simon Kelley 6f23a0a75e Rework validate-by-DS to avoid DoS vuln without arbitrary limits.
By calculating the hash of a DNSKEY once for each digest algo,
we reduce the hashing work from (no. DS) x (no. DNSKEY) to
(no. DNSKEY) x (no. distinct digests)

The number of distinct digests can never be more than 255 and
it's limited by which hashes we implement, so currently only 4.
2024-02-12 23:11:35 +00:00
Simon Kelley c5aa221e44 Parameterise work limits for DNSSEC validation. 2024-02-12 23:11:35 +00:00
Simon Kelley b5820d1fd8 Bump copyright to 2024. 2024-01-13 22:20:04 +00:00
Damian Sawicki 416390f996 Add --max-tcp-connections option to make this dynamically configurable. 2023-11-04 23:33:28 +00:00
Simon Kelley df242de5c6 Bump copyrights to 2023. 2023-04-05 12:34:34 +01:00
Simon Kelley eb92fb32b7 Set the default maximum DNS UDP packet size to 1232.
http://www.dnsflagday.net/2020/ refers.

Thanks to Xiang Li for the prompt.
2023-03-07 22:21:21 +00:00
Dominik Derigs efbf80be58 Make max staleness of stale cache entries configurable and default to one day. 2022-11-26 21:18:34 +00:00
Simon Kelley 9a9f6e147c Make fast-retry more configurable and do exponential backoff. 2022-09-15 19:29:49 +01:00
Simon Kelley c0e731d545 Further optimisation of --port-limit.
No longer try and fail to open every port when the port range
is in complete use; go straight to re-using an existing socket.

Die at startup if port range is smaller than --port-limit, since
the code behaves badly in this case.
2022-09-09 23:15:50 +01:00
Simon Kelley c6d4c33d61 Bump copyright to 2022. 2022-01-24 15:19:00 +00:00
Dominik Derigs 4308236262 Minimum safe size is recommended to be 1232. See https://dnsflagday.net/2020/
Signed-off-by: DL6ER <dl6er@dl6er.de>
2022-01-13 00:31:54 +00:00
Simon Kelley 47aefca5e4 Add --nftset option, like --ipset but for the newer nftables.
Thanks to Chen Zhenge for the original patch, which I've
reworked. Any bugs down to SRK.
2021-09-27 21:49:28 +01:00
Simon Kelley 3236f358f8 Revise resource handling for number of concurrent DNS queries.
This used to have a global limit, but that has a problem when using
different servers for different upstream domains. Queries which are
routed by domain to an upstream server which is not responding will
build up and trigger the limit, which breaks DNS service for all other
domains which could be handled by other servers. The change is to make
the limit per server-group, where a server group is the set of servers
configured for a particular domain. In the common case, where only
default servers are declared, there is no effective change.
2021-06-13 21:29:22 +01:00
Simon Kelley b082842ee7 Add NO_LOOP to config.h docs. 2021-04-12 17:43:59 +01:00
Geert Stappers 3573ca0eec Chomp file ends
Removed empty lines from end of src/*.[ch] files.
If the new last line became '#endif'
was the condition of the '#if' added.
2021-04-09 17:27:36 +01:00
Simon Kelley ea28d0ef8a Scale the DNS random scket pool on the value of dns-forward-max. 2021-03-26 22:02:04 +00:00
Simon Kelley c8e8f5c204 Bump copyright notices for 2021. Happy New Year! 2021-01-24 21:59:37 +00:00
Simon Kelley a69b017902 Change HAVE_NETTLEHASH compile-time to HAVE_CRYPTOHASH.
HAVE_NETTLEHASH is retained for backwards compatibility, but deprecated.
2021-01-24 21:53:28 +00:00
Petr Menšík 2024f97297 Support hash function from nettle (only)
Unlike COPTS=-DHAVE_DNSSEC, allow usage of just sha256 function from
nettle, but keep DNSSEC disabled at build time. Skips use of internal
hash implementation without support for validation built-in.
2020-12-16 15:49:03 +00:00
Simon Kelley 4d85e409cd Change default lease time for DHCPv6 to one day.
Also remove floor on valid and preffered times in RA when
no time is specified.
2020-07-12 22:45:46 +01:00
Simon Kelley 7e194a0a7d Apply floor of 60s to TTL of DNSKEY and DS records in cache.
Short TTLs and specifically zero TTLs can mess up DNSSEC validation.
2020-07-12 17:43:25 +01:00
Oldřich Jedlička d162bee356 Allow overriding of ubus service name.
Same as for the dbus, allow specifying ubus service name (namespace) on
the command line as an optional argument to --enable-ubus option.

Signed-off-by: Oldřich Jedlička <oldium.pro@gmail.com>
2020-03-28 18:16:53 +00:00
Simon Kelley 2a8710ac2f Update copyrights to 2020. 2020-01-05 16:40:06 +00:00
Simon Kelley e198fe833a Compilation fix for MacOS.
Thanks to Pal Lockheart <ex@palx.org> for the original patch.
2019-08-22 23:23:29 +01:00
Jan Willem Janssen a2b8220f4e Improved UBus supported
- aligned the handling of UBus connections with the DBus code as it
makes it a bit easier to comprehend;
- added logging to the various UBus calls to aid debugging from an
enduser point of view, but be careful to not flood the logs;
- show the (lack of) support for UBus in the configuration string.
2019-04-04 15:58:07 +01:00
Simon Kelley 48d12f14c9 Remove the NO_FORK compile-time option, and support for uclinux.
In an era where everything has an MMU, this looks like
an anachronism, and it adds to (Ok, multiplies!) the
combinatorial explosion of compile-time options.
2018-11-02 21:55:04 +00:00
Simon Kelley ee8750451b Remove ability to compile without IPv6 support.
This was the source of a large number of #ifdefs, originally
included for use with old embedded libc versions. I'm
sure no-one wants or needs IPv6-free code these days, so this
is a move towards more maintainable code.
2018-10-23 22:10:17 +01:00
Julian Kornberger caf4d571e6 Add OpenWRT ubus patch
Originally written by John Crispin <john@phrozen.org>
2018-07-21 21:45:03 +01:00
Simon Kelley 6b17335209 Add packet-dump debugging facility. 2018-05-08 18:32:14 +01:00
Simon Kelley 94b6878821 Tidy crypto.c of old library compat. Now need libnettle 3. 2018-03-17 18:39:23 +00:00
Simon Kelley c1a4e257a3 Try to be a little more clever at falling back to smaller DNS packet sizes. 2018-01-19 22:00:05 +00:00