Commit | Line | Data |
---|---|---|
b4588d5c GP |
1 | From a7e94dd5f99a7e63af8fb2ce0406e294703814b7 Mon Sep 17 00:00:00 2001 |
2 | From: Gerrit Pape <pape@smarden.org> | |
3 | Date: Tue, 10 Mar 2009 13:35:38 +0000 | |
4 | Subject: [PATCH] dnscache.c: allow a maximum of 20 concurrent outgoing SOA queries | |
5 | ||
6 | dnscache doesn't cache SOA records, and doesn't merge outgoing queries | |
7 | to the same servers. This commit limits the concurrent outgoing SOA | |
8 | queries to 20 to make birthday attacks as described in CVE-2008-4392 | |
9 | more difficult. | |
10 | --- | |
11 | dnscache.c | 15 +++++++++++++++ | |
12 | log.c | 6 ++++++ | |
13 | 2 files changed, 21 insertions(+), 0 deletions(-) | |
14 | ||
15 | diff --git a/dnscache.c b/dnscache.c | |
16 | index abcba69..2366ecc 100644 | |
17 | --- a/dnscache.c | |
18 | +++ b/dnscache.c | |
19 | @@ -72,11 +72,15 @@ static struct udpclient { | |
20 | } u[MAXUDP]; | |
21 | int uactive = 0; | |
22 | ||
23 | +#define MAXSOA 20 | |
24 | +int soaactive = 0; | |
25 | + | |
26 | void u_drop(int j) | |
27 | { | |
28 | if (!u[j].active) return; | |
29 | log_querydrop(&u[j].active); | |
30 | u[j].active = 0; --uactive; | |
31 | + if (byte_equal(u[j].q.type,2,DNS_T_SOA)) --soaactive; | |
32 | } | |
33 | ||
34 | void u_respond(int j) | |
35 | @@ -87,6 +91,7 @@ void u_respond(int j) | |
36 | socket_send6(udp53,response,response_len,u[j].ip,u[j].port,u[j].scope_id); | |
37 | log_querydone(&u[j].active,response_len); | |
38 | u[j].active = 0; --uactive; | |
39 | + if (byte_equal(u[j].q.type,2,DNS_T_SOA)) --soaactive; | |
40 | } | |
41 | ||
42 | void u_new(void) | |
43 | @@ -125,6 +130,16 @@ void u_new(void) | |
44 | ||
45 | x->active = ++numqueries; ++uactive; | |
46 | log_query(&x->active,x->ip,x->port,x->id,q,qtype); | |
47 | + | |
48 | + if (byte_equal(qtype,2,DNS_T_SOA)) { | |
49 | + if (soaactive >= MAXSOA) { | |
50 | + log_querydropmaxsoa(&x->active); | |
51 | + x->active = 0; --uactive; | |
52 | + return; | |
53 | + } | |
54 | + ++soaactive; | |
55 | + } | |
56 | + | |
57 | switch(query_start(&x->q,q,qtype,qclass,myipoutgoing,interface)) { | |
58 | case -1: | |
59 | u_drop(j); | |
60 | diff --git a/log.c b/log.c | |
61 | index df465e2..a651607 100644 | |
62 | --- a/log.c | |
63 | +++ b/log.c | |
64 | @@ -118,6 +118,12 @@ void log_querydrop(uint64 *qnum) | |
65 | line(); | |
66 | } | |
67 | ||
68 | +void log_querydropmaxsoa(uint64 *qnum) | |
69 | +{ | |
70 | + string("drop "); number(*qnum); space(); string("maxsoa"); | |
71 | + line(); | |
72 | +} | |
73 | + | |
74 | void log_tcpopen(const char client[16],unsigned int port) | |
75 | { | |
76 | string("tcpopen "); | |
77 | -- | |
78 | 1.6.2 | |
79 |