Fix b6f926fbefcd2471699599e44f32b8d25b87b471 to not SEGV on startup (rarely).
Many thanks to Kristian Evensen for finding and diagnosing this.
We can't copy the whole of a crec structure in make_non_terminals, since
crec structures allocated to represent /etc/hosts entries are allocated with
just enough space for the actual name they contain, not the full
SMALLDNAME bytes declared in struct crec. Using structure copy therefore
copies beyond the end of the allocated source and, just occaisionally,
into unmapped memory, resulting in a SEGV.
Since the crecs we're making here always have F_NAMEP set, we're not
interested in copying the name field from the source anyway, we use the
namep part of the union and set it to point some way into the name
of the source crec to get the super-domain that we're representing.
The fix is therefore to copy the relevant fields of the crec, rather
than copying the whole and overwriting.
diff --git a/src/cache.c b/src/cache.c
index 5a38c21..68cdc85 100644
--- a/src/cache.c
+++ b/src/cache.c
@@ -1436,9 +1436,8 @@
if (crecp)
{
- *crecp = *source;
- crecp->flags &= ~(F_IPV4 | F_IPV6 | F_CNAME | F_DNSKEY | F_DS | F_REVERSE);
- crecp->flags |= F_NAMEP;
+ crecp->flags = (source->flags | F_NAMEP) & ~(F_IPV4 | F_IPV6 | F_CNAME | F_DNSKEY | F_DS | F_REVERSE);
+ crecp->ttd = source->ttd;
crecp->name.namep = name;
cache_hash(crecp);