[Dnsmasq-discuss] possible overflow while constructing SRV record name
Simon Kelley
simon at thekelleys.org.uk
Tue Jul 15 14:19:49 UTC 2025
On 7/11/25 13:31, Mikhail Dmitrichenko wrote:
> Hello!
>
> First of all, I want to clarify that I'm new to dnsmasq, so please
> excuse me if my message seems silly.
>
> My question is about constructing srv record name in function src/
> option.c/read_opts, v2.91. Specifically, this part:
>
> if (daemon->domain_suffix)
> {
> /* add domain for any srv record without one. */
> struct mx_srv_record *srv;
>
> for (srv = daemon->mxnames; srv; srv = srv->next)
> if (srv->issrv &&
> strchr(srv->name, '.') &&
> strchr(srv->name, '.') == strrchr(srv->name, '.'))
> {
> strcpy(buff, srv->name);
> strcat(buff, ".");
> strcat(buff, daemon->domain_suffix);
> free(srv->name);
> srv->name = opt_string_alloc(buff);
> }
> }
>
> Here, `buff` is a buffer of length ((MAXDNAME * 2) + 1) bytes. If I
> understand it correctly, after lines:
>
> strcpy(buff, srv->name);
> strcat(buff, ".");
>
> maximum len of `buff` will be (MAXDNAME + 1) bytes. My concern is about
> next line:
>
> strcat(buff, daemon->domain_suffix);
>
> As I see it, there is a possible scenario, where domain name in
> `resolv.conf` contains non-ASCII symbols. If IDN library is present,
> this name will be encoded and set as `daemon->domain_suffix` value. I
> noticed that in function src/util.c/canonicalise, there is a call to
> `check_name`, which checks len of given non-encoded input string. If it
> exceeds `MAXDNAME`, NULL will be returned, so `daemon->domain_suffix`
> will be NULL.
>
> But what if encoded string exceeds `MAXDNAME`? I haven't found any check
> for that. If this happens, it could cause overflow in the line
>
> strcat(buff, daemon->domain_suffix);
>
> because `buff` may already contain (`MAXDNAME` + 1) bytes, leaving only
> `MAXDNAME` bytes free. Do you think it will be useful to add a check of
> encoded domain name length to prevent such an overflow? Any response
> would be appreciated.
>
> I'm aware that such long domain names are unusual and described scenario
> is unlikely in real life, but I still wanted to highlight it.
>
> Thank you in advance for your time and expertise!
First, the code that appends the domain to SRV records. This is a good
point, but note that the both the domain and the name of SRV records
come from the configuration of dnsmasq, they are not untrusted data from
the internet. The anyone who can manipulate them has root on the machine
running dnsmasq, so this it not a security problem. The worst case
scenario is that a somewhat bizarre configuration causes dnsmasq to crah
on startup. The fix is to check for overflow, and exit with an suitable
error message, so it's easy to find and correct.
Aside: the buffer length is (MAXDNAME*2)+1 because dnsmasq uses an
escape method to represent a few special characters in domain names. For
instance '.' could appear in a valid label, but dnsmasq uses '.' in the
obvious way as a label delimited. '.' in a label is therefore
represented as the escape byte followed by a second byte. In theory, and
name could require an escape character for each character, and a domain
name is limited to MAXDNAME characters, hence the MAXDNAME * 2. The
added one is for the zero terminator.
Second, the problem with returned encoded names from libidn - the
documentation for idn2 states that domain names are limited to 255
characters, which is less that MAXDNAME - I'm not sure why. libida is
even more restrictive and 63 characters. I don't think that this a
therefore a problem.
I've pushed a commit to make the check on the first issue.
Cheers,
Simon.
>
> _______________________________________________
> Dnsmasq-discuss mailing list
> Dnsmasq-discuss at lists.thekelleys.org.uk
> https://lists.thekelleys.org.uk/cgi-bin/mailman/listinfo/dnsmasq-discuss
More information about the Dnsmasq-discuss
mailing list