From c5f46412a3e79b6637061d3415cdd38ffdfc854a Mon Sep 17 00:00:00 2001 From: Dominik Date: Thu, 19 Mar 2026 23:41:22 +0100 Subject: [PATCH] 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 --- src/domain.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/domain.c b/src/domain.c index ce4929b..4814435 100644 --- a/src/domain.c +++ b/src/domain.c @@ -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; }