Tidy and fix cache->uid handling.

Some CNAMES left the value of ->uid undefined.

Since there are now special values if this, for CNAMES
to interface names, that could cause a crash
if the undefined value hit the special value.

Also ensure that the special value can't arise
when the uid is encoding the source of an F_CONFIG
record, in case there's a CNAME to it.
This commit is contained in:
Simon Kelley committed 2014-03-18 22:38:30 +00:00
1 parent d5082158ee
commit 19c51cfa49
3 files changed
+27 -15

No files matched your search

+15 -10
View File
@@ -79,7 +79,7 @@ static unsigned int next_uid(void)
uid++;
/* uid == 0 used to indicate CNAME to interface name. */
if (uid == 0)
if (uid == SRC_INTERFACE)
uid++;
return uid;
@@ -265,7 +265,7 @@ char *cache_get_name(struct crec *crecp)
char *cache_get_cname_target(struct crec *crecp)
{
if (crecp->addr.cname.uid != 0)
if (crecp->addr.cname.uid != SRC_INTERFACE)
return cache_get_name(crecp->addr.cname.target.cache);
return crecp->addr.cname.target.int_name->name;
@@ -783,13 +783,14 @@ static void add_hosts_cname(struct crec *target)
crec->name.namep = a->alias;
crec->addr.cname.target.cache = target;
crec->addr.cname.uid = target->uid;
crec->uid = next_uid();
cache_hash(crec);
add_hosts_cname(crec); /* handle chains */
}
}
static void add_hosts_entry(struct crec *cache, struct all_addr *addr, int addrlen,
int index, struct crec **rhash, int hashsz)
unsigned int index, struct crec **rhash, int hashsz)
{
struct crec *lookup = cache_find_by_name(NULL, cache_get_name(cache), 0, cache->flags & (F_IPV4 | F_IPV6));
int i, nameexists = 0;
@@ -893,7 +894,7 @@ static int gettok(FILE *f, char *token)
}
}
static int read_hostsfile(char *filename, int index, int cache_size, struct crec **rhash, int hashsz)
static int read_hostsfile(char *filename, unsigned int index, int cache_size, struct crec **rhash, int hashsz)
{
FILE *f = fopen(filename, "r");
char *token = daemon->namebuff, *domain_suffix = NULL;
@@ -1043,7 +1044,8 @@ void cache_reload(void)
cache->flags = F_FORWARD | F_NAMEP | F_CNAME | F_IMMORTAL | F_CONFIG;
cache->name.namep = a->alias;
cache->addr.cname.target.int_name = intr;
cache->addr.cname.uid = 0;
cache->addr.cname.uid = SRC_INTERFACE;
cache->uid = next_uid();
cache_hash(cache);
add_hosts_cname(cache); /* handle chains */
}
@@ -1079,7 +1081,7 @@ void cache_reload(void)
{
cache->name.namep = nl->name;
cache->flags = F_HOSTS | F_IMMORTAL | F_FORWARD | F_REVERSE | F_IPV4 | F_NAMEP | F_CONFIG;
add_hosts_entry(cache, (struct all_addr *)&hr->addr, INADDRSZ, 0, (struct crec **)daemon->packet, revhashsz);
add_hosts_entry(cache, (struct all_addr *)&hr->addr, INADDRSZ, SRC_CONFIG, (struct crec **)daemon->packet, revhashsz);
}
#ifdef HAVE_IPV6
if (!IN6_IS_ADDR_UNSPECIFIED(&hr->addr6) &&
@@ -1087,7 +1089,7 @@ void cache_reload(void)
{
cache->name.namep = nl->name;
cache->flags = F_HOSTS | F_IMMORTAL | F_FORWARD | F_REVERSE | F_IPV6 | F_NAMEP | F_CONFIG;
add_hosts_entry(cache, (struct all_addr *)&hr->addr6, IN6ADDRSZ, 0, (struct crec **)daemon->packet, revhashsz);
add_hosts_entry(cache, (struct all_addr *)&hr->addr6, IN6ADDRSZ, SRC_CONFIG, (struct crec **)daemon->packet, revhashsz);
}
#endif
}
@@ -1100,7 +1102,7 @@ void cache_reload(void)
}
if (!option_bool(OPT_NO_HOSTS))
total_size = read_hostsfile(HOSTSFILE, 0, total_size, (struct crec **)daemon->packet, revhashsz);
total_size = read_hostsfile(HOSTSFILE, SRC_HOSTS, total_size, (struct crec **)daemon->packet, revhashsz);
daemon->addn_hosts = expand_filelist(daemon->addn_hosts);
for (ah = daemon->addn_hosts; ah; ah = ah->next)
@@ -1164,6 +1166,7 @@ static void add_dhcp_cname(struct crec *target, time_t ttd)
aliasc->name.namep = a->alias;
aliasc->addr.cname.target.cache = target;
aliasc->addr.cname.uid = target->uid;
aliasc->uid = next_uid();
cache_hash(aliasc);
add_dhcp_cname(aliasc, ttd);
}
@@ -1377,11 +1380,13 @@ void dump_cache(time_t now)
}
}
char *record_source(int index)
char *record_source(unsigned int index)
{
struct hostsfile *ah;
if (index == 0)
if (index == SRC_CONFIG)
return "config";
else if (index == SRC_HOSTS)
return HOSTSFILE;
for (ah = daemon->addn_hosts; ah; ah = ah->next)