domain: fix strncat buffer-size argument in is_rev_synth()

strncat(dst, src, n) truncates src to n bytes, but n should be the
remaining space in dst, not the total buffer size.  Passing MAXDNAME
as n allowed the combined prefix + address + "." + domain to overflow
the MAXDNAME-byte namebuff if c->domain was close to MAXDNAME chars.

Replace MAXDNAME with MAXDNAME - strlen(name) - 1 at each call site
(lines 178-179 for IPv4, 204 for the IPv6 hex-fragment loop, 208-209
for the IPv6 suffix) so the append is always bounded by actual
remaining capacity.

Security implications: strncat(name, c->domain, MAXDNAME) passes the
full buffer size instead of remaining space. Overflow requires a local
admin to configure a --synth-domain with a domain name > ~960 chars.
The actual exploitable window is narrow: the admin would need a
--synth-domain with a domain name close to 1024 chars (which check_name
permits) combined with a non-trivial prefix or IPv6 address.
Not remotely exploitable.

Signed-off-by: Dominik <dl6er@dl6er.de>
This commit is contained in:
Dominik authored and Simon Kelley committed 2026-03-30 20:06:43 +01:00
1 parent cd04c0ce20
commit c5f46412a3
1 file changed
+7 -7
+7 -7
View File
@@ -175,8 +175,8 @@ int is_rev_synth(int flag, union all_addr *addr, char *name)
*p = '-';
}
strncat(name, ".", MAXDNAME);
strncat(name, c->domain, MAXDNAME);
strncat(name, ".", MAXDNAME - strlen(name) - 1);
strncat(name, c->domain, MAXDNAME - strlen(name) - 1);
return 1;
}
@@ -201,16 +201,16 @@ int is_rev_synth(int flag, union all_addr *addr, char *name)
for (i = 0; i < 16; i += 2)
{
sprintf(frag, "%s%02x%02x", i == 0 ? "" : "-", addr->addr6.s6_addr[i], addr->addr6.s6_addr[i+1]);
strncat(name, frag, MAXDNAME);
strncat(name, frag, MAXDNAME - strlen(name) - 1);
}
}
strncat(name, ".", MAXDNAME);
strncat(name, c->domain, MAXDNAME);
strncat(name, ".", MAXDNAME - strlen(name) - 1);
strncat(name, c->domain, MAXDNAME - strlen(name) - 1);
return 1;
}
return 0;
}