Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Make Start of Authority(SOA) responses cache-able.

This patch fixes dnscache to cache SOA responses sent to clients.
This fixes one of the cache poisoning vulnerability reported by
Mr Mark Johnson -> https://bugzilla.redhat.com/show_bug.cgi?id=838965.

Nonetheless the original patch for this issue was created by
Mr Jeff king -> http://www.your.org/dnscache/

Sincere thanks to Mr Mark for reporting this issue and Mr Jeff for
creating the patch and releasing it under public domain.
  • Loading branch information...
commit ef1875907a0e3cf632f66c3add91f08543c74f3c 1 parent 9119bbb
@pjps authored
Showing with 53 additions and 4 deletions.
  1. +53 −4 query.c
View
57 query.c
@@ -450,9 +450,46 @@ doit (struct query *z, int state)
}
}
+ if (typematch (DNS_T_SOA, dtype))
+ {
+ byte_copy (key, 2, DNS_T_SOA);
+ cached = cache_get (key, dlen + 2, &cachedlen, &ttl);
+ if (cached && (cachedlen || byte_diff (dtype, 2, DNS_T_ANY)))
+ {
+ log_cachedanswer (d, DNS_T_SOA);
+ if (!rqa (z))
+ goto DIE;
+
+ pos = 0;
+ while (pos = dns_packet_copy(cached, cachedlen, pos, misc, 20))
+ {
+ pos = dns_packet_getname (cached, cachedlen, pos, &t2);
+ if (!pos)
+ break;
+
+ pos = dns_packet_getname (cached, cachedlen, pos, &t3);
+ if (!pos)
+ break;
+
+ if (!response_rstart (d, DNS_T_SOA, ttl))
+ goto DIE;
+ if (!response_addname (t2))
+ goto DIE;
+ if (!response_addname (t3))
+ goto DIE;
+ if (!response_addbytes(misc, 20))
+ goto DIE;
+
+ response_rfinish (RESPONSE_ANSWER);
+ }
+ cleanup (z);
+ return 1;
+ }
+ }
+
if (typematch (DNS_T_A, dtype))
{
- byte_copy (key,2,DNS_T_A);
+ byte_copy (key, 2, DNS_T_A);
cached = cache_get (key, dlen + 2, &cachedlen, &ttl);
if (cached && (cachedlen || byte_diff (dtype, 2, DNS_T_ANY)))
{
@@ -504,7 +541,8 @@ doit (struct query *z, int state)
&& !typematch (DNS_T_NS, dtype)
&& !typematch (DNS_T_PTR, dtype)
&& !typematch (DNS_T_A, dtype)
- && !typematch (DNS_T_MX, dtype))
+ && !typematch (DNS_T_MX, dtype)
+ && !typematch (DNS_T_SOA, dtype))
{
byte_copy (key, 2, dtype);
cached = cache_get (key, dlen + 2, &cachedlen, &ttl);
@@ -853,6 +891,8 @@ doit (struct query *z, int state)
;
else if (byte_equal (type, 2, DNS_T_SOA))
{
+ int non_authority = 0;
+ save_start ();
while (i < j)
{
pos = dns_packet_skipname (buf, len, records[i]);
@@ -867,10 +907,19 @@ doit (struct query *z, int state)
pos = dns_packet_copy (buf, len, pos, misc, 20);
if (!pos)
goto DIE;
- if (records[i] < posauthority && debug_level > 2)
- log_rrsoa (whichserver, t1, t2, t3, misc, ttl);
+ if (records[i] < posauthority)
+ {
+ if (debug_level > 2)
+ log_rrsoa (whichserver, t1, t2, t3, misc, ttl);
+ save_data (misc, 20);
+ save_data (t2, dns_domain_length (t2));
+ save_data (t3, dns_domain_length (t3));
+ non_authority++;
+ }
++i;
}
+ if (non_authority)
+ save_finish (DNS_T_SOA, t1, ttl);
}
else if (byte_equal (type, 2, DNS_T_CNAME))
{
Please sign in to comment.
Something went wrong with that request. Please try again.