]> git.ipfire.org Git - ipfire-2.x.git/blame - src/patches/dnsmasq/0017-Fix-crash-in-DNSSEC-code-when-attempting-to-verify-l.patch
dnsmasq: Import patches from upstream
[ipfire-2.x.git] / src / patches / dnsmasq / 0017-Fix-crash-in-DNSSEC-code-when-attempting-to-verify-l.patch
CommitLineData
6644c1c7
MT
1From 094b5c3d904bae9aeb3206d9f3b8348926b84975 Mon Sep 17 00:00:00 2001
2From: Simon Kelley <simon@thekelleys.org.uk>
3Date: Sun, 21 Dec 2014 16:11:52 +0000
888c41de 4Subject: [PATCH 17/98] Fix crash in DNSSEC code when attempting to verify
6644c1c7
MT
5 large RRs.
6
7---
8 CHANGELOG | 3 +++
9 src/dnssec.c | 27 +++++++++++++++++++--------
10 2 files changed, 22 insertions(+), 8 deletions(-)
11
12diff --git a/CHANGELOG b/CHANGELOG
13index 01f5208ec006..956b71a151db 100644
14--- a/CHANGELOG
15+++ b/CHANGELOG
16@@ -19,6 +19,9 @@ version 2.73
17 the answers given by --interface-name. Note that reverse queries
18 (ie looking for names, given addresses) are not affected.
19 Thanks to Michael Gorbach for the suggestion.
20+
21+ Fix crash in DNSSEC code with long RRs. Thanks to Marco Davids
22+ for the bug report.
23
24
25 version 2.72
26diff --git a/src/dnssec.c b/src/dnssec.c
27index 69bfc29e355f..3208ac701149 100644
28--- a/src/dnssec.c
29+++ b/src/dnssec.c
30@@ -456,16 +456,27 @@ static u16 *get_desc(int type)
31
32 /* Return bytes of canonicalised rdata, when the return value is zero, the remaining
33 data, pointed to by *p, should be used raw. */
34-static int get_rdata(struct dns_header *header, size_t plen, unsigned char *end, char *buff,
35+static int get_rdata(struct dns_header *header, size_t plen, unsigned char *end, char *buff, int bufflen,
36 unsigned char **p, u16 **desc)
37 {
38 int d = **desc;
39
40- (*desc)++;
41-
42 /* No more data needs mangling */
43 if (d == (u16)-1)
44- return 0;
45+ {
46+ /* If there's more data than we have space for, just return what fits,
47+ we'll get called again for more chunks */
48+ if (end - *p > bufflen)
49+ {
50+ memcpy(buff, *p, bufflen);
51+ *p += bufflen;
52+ return bufflen;
53+ }
54+
55+ return 0;
56+ }
57+
58+ (*desc)++;
59
60 if (d == 0 && extract_name(header, plen, p, buff, 1, 0))
61 /* domain-name, canonicalise */
62@@ -560,7 +571,7 @@ static void sort_rrset(struct dns_header *header, size_t plen, u16 *rr_desc, int
63 if (left1 != 0)
64 memmove(buff1, buff1 + len1 - left1, left1);
65
66- if ((len1 = get_rdata(header, plen, end1, buff1 + left1, &p1, &dp1)) == 0)
67+ if ((len1 = get_rdata(header, plen, end1, buff1 + left1, MAXDNAME - left1, &p1, &dp1)) == 0)
68 {
69 quit = 1;
70 len1 = end1 - p1;
71@@ -571,7 +582,7 @@ static void sort_rrset(struct dns_header *header, size_t plen, u16 *rr_desc, int
72 if (left2 != 0)
73 memmove(buff2, buff2 + len2 - left2, left2);
74
75- if ((len2 = get_rdata(header, plen, end2, buff2 + left2, &p2, &dp2)) == 0)
76+ if ((len2 = get_rdata(header, plen, end2, buff2 + left2, MAXDNAME - left2, &p2, &dp2)) == 0)
77 {
78 quit = 1;
79 len2 = end2 - p2;
80@@ -808,7 +819,7 @@ static int validate_rrset(time_t now, struct dns_header *header, size_t plen, in
81 /* canonicalise rdata and calculate length of same, use name buffer as workspace */
82 cp = p;
83 dp = rr_desc;
84- for (len = 0; (seg = get_rdata(header, plen, end, name, &cp, &dp)) != 0; len += seg);
85+ for (len = 0; (seg = get_rdata(header, plen, end, name, MAXDNAME, &cp, &dp)) != 0; len += seg);
86 len += end - cp;
87 len = htons(len);
88 hash->update(ctx, 2, (unsigned char *)&len);
89@@ -816,7 +827,7 @@ static int validate_rrset(time_t now, struct dns_header *header, size_t plen, in
90 /* Now canonicalise again and digest. */
91 cp = p;
92 dp = rr_desc;
93- while ((seg = get_rdata(header, plen, end, name, &cp, &dp)))
94+ while ((seg = get_rdata(header, plen, end, name, MAXDNAME, &cp, &dp)))
95 hash->update(ctx, seg, (unsigned char *)name);
96 if (cp != end)
97 hash->update(ctx, end - cp, cp);
98--
992.1.0
100