Merge lp:~jtaylor/ubuntu/oneiric/inspircd/CVE-2012-1836 into lp:ubuntu/oneiric/inspircd

Proposed by Julian Taylor
Status: Merged
Merge reported by: Martin Pitt
Merged at revision: not available
Proposed branch: lp:~jtaylor/ubuntu/oneiric/inspircd/CVE-2012-1836
Merge into: lp:ubuntu/oneiric/inspircd
Diff against target: 157 lines (+137/-0)
3 files modified
debian/changelog (+9/-0)
debian/patches/00list (+1/-0)
debian/patches/06_CVE-2012-1836.dpatch (+127/-0)
To merge this branch: bzr merge lp:~jtaylor/ubuntu/oneiric/inspircd/CVE-2012-1836
Reviewer Review Type Date Requested Status
Ubuntu branches Pending
Review via email: mp+102037@code.launchpad.net
To post a comment you must log in.
13. By Julian Taylor

add missing patch

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'debian/changelog'
--- debian/changelog 2011-09-12 14:07:29 +0000
+++ debian/changelog 2012-04-15 19:06:27 +0000
@@ -1,3 +1,12 @@
1inspircd (1.1.22+dfsg-4ubuntu1.1) oneiric-security; urgency=low
2
3 * SECURITY UPDATE: remote code execution (LP: #982509)
4 - debian/patches/06_CVE-2012-1836.dpatch:
5 Fix buffer overflow in dns.cpp, thanks to Jonathan Wiltshire
6 - CVE-2012-1836
7
8 -- Julian Taylor <jtaylor@ubuntu.com> Sun, 15 Apr 2012 20:33:41 +0200
9
1inspircd (1.1.22+dfsg-4ubuntu1) oneiric; urgency=low10inspircd (1.1.22+dfsg-4ubuntu1) oneiric; urgency=low
211
3 * Fix link order to list libraries after the objects that require them12 * Fix link order to list libraries after the objects that require them
413
=== modified file 'debian/patches/00list'
--- debian/patches/00list 2011-09-12 14:07:29 +0000
+++ debian/patches/00list 2012-04-15 19:06:27 +0000
@@ -3,3 +3,4 @@
303_use_pkg-config_gnutls.dpatch303_use_pkg-config_gnutls.dpatch
404_gcc44_fixes.dpatch 404_gcc44_fixes.dpatch
505_link_order.dpatch505_link_order.dpatch
606_CVE-2012-1836.dpatch
67
=== added file 'debian/patches/06_CVE-2012-1836.dpatch'
--- debian/patches/06_CVE-2012-1836.dpatch 1970-01-01 00:00:00 +0000
+++ debian/patches/06_CVE-2012-1836.dpatch 2012-04-15 19:06:27 +0000
@@ -0,0 +1,127 @@
1#! /bin/sh /usr/share/dpatch/dpatch-run
2## 06_CVE-2012-1836.dpatch by Jonathan Wiltshire <jmw@debian.org>
3##
4## All lines beginning with `## DP:' are a description of the patch.
5## DP: Protect against buffer overflow in src/dns.cpp
6## DP: CVE-2012-1836 (#667914)
7
8@DPATCH@
9diff -urNad '--exclude=CVS' '--exclude=.svn' '--exclude=.git' '--exclude=.arch' '--exclude=.hg' '--exclude=_darcs' '--exclude=.bzr' inspircd-1.1.22+dfsg~/src/dns.cpp inspircd-1.1.22+dfsg/src/dns.cpp
10--- inspircd-1.1.22+dfsg~/src/dns.cpp 2012-04-07 23:14:55.000000000 +0100
11+++ inspircd-1.1.22+dfsg/src/dns.cpp 2012-04-07 23:16:01.292193775 +0100
12@@ -45,6 +45,8 @@
13 using irc::sockets::OpenTCPSocket;
14 using irc::sockets::NonBlocking;
15
16+#define DN_COMP_BITMASK 0xC000 /* highest 6 bits in a DN label header */
17+
18 /** Masks to mask off the responses we get from the DNSRequest methods
19 */
20 enum QueryInfo
21@@ -105,7 +107,7 @@
22
23 DNSRequest(InspIRCd* Instance, DNS* dns, int id, const std::string &original);
24 ~DNSRequest();
25- DNSInfo ResultIsReady(DNSHeader &h, int length);
26+ DNSInfo ResultIsReady(DNSHeader &h, unsigned length);
27 int SendRequests(const DNSHeader *header, const int length, QueryType qt);
28 };
29
30@@ -155,7 +157,10 @@
31 /* Allocate the processing buffer */
32 DNSRequest::DNSRequest(InspIRCd* Instance, DNS* dns, int id, const std::string &original) : dnsobj(dns)
33 {
34- res = new unsigned char[512];
35+ /* hardening against overflow here: make our work buffer twice the theoretical
36+ * maximum size so that hostile input doesn't screw us over.
37+ */
38+ res = new unsigned char[sizeof(DNSHeader) * 2];
39 *res = 0;
40 orig = original;
41 RequestTimeout* RT = new RequestTimeout(Instance->Config->dns_timeout ? Instance->Config->dns_timeout : 5, Instance, this, id);
42@@ -776,11 +781,11 @@
43 }
44
45 /** A result is ready, process it */
46-DNSInfo DNSRequest::ResultIsReady(DNSHeader &header, int length)
47+DNSInfo DNSRequest::ResultIsReady(DNSHeader &header, unsigned length)
48 {
49- int i = 0;
50+ unsigned i = 0, o;
51 int q = 0;
52- int curanswer, o;
53+ int curanswer;
54 ResourceRecord rr;
55 unsigned short ptr;
56
57@@ -875,17 +880,31 @@
58
59 switch (rr.type)
60 {
61+ /*
62+ * CNAME and PTR are compressed. We need to decompress them.
63+ */
64 case DNS_QUERY_CNAME:
65- /* CNAME and PTR have the same processing code */
66 case DNS_QUERY_PTR:
67 o = 0;
68 q = 0;
69 while (q == 0 && i < length && o + 256 < 1023)
70 {
71+ /* DN label found (byte over 63) */
72 if (header.payload[i] > 63)
73 {
74 memcpy(&ptr,&header.payload[i],2);
75- i = ntohs(ptr) - 0xC000 - 12;
76+
77+ i = ntohs(ptr);
78+
79+ /* check that highest two bits are set. if not, we've been had */
80+ if (!(i & DN_COMP_BITMASK))
81+ return std::make_pair((unsigned char *) NULL, "DN label decompression header is bogus");
82+
83+ /* mask away the two highest bits. */
84+ i &= ~DN_COMP_BITMASK;
85+
86+ /* and decrease length by 12 bytes. */
87+ i =- 12;
88 }
89 else
90 {
91@@ -898,7 +917,11 @@
92 res[o] = 0;
93 if (o != 0)
94 res[o++] = '.';
95- memcpy(&res[o],&header.payload[i + 1],header.payload[i]);
96+
97+ if (o + header.payload[i] > sizeof(DNSHeader))
98+ return std::make_pair((unsigned char *) NULL, "DN label decompression is impossible -- malformed/hostile packet?");
99+
100+ memcpy(&res[o], &header.payload[i + 1], header.payload[i]);
101 o += header.payload[i];
102 i += header.payload[i] + 1;
103 }
104@@ -907,16 +930,21 @@
105 res[o] = 0;
106 break;
107 case DNS_QUERY_AAAA:
108+ if (rr.rdlength != sizeof(struct in6_addr))
109+ return std::make_pair((unsigned char *) NULL, "rr.rdlength is larger than 16 bytes for an ipv6 entry -- malformed/hostile packet?");
110+
111 memcpy(res,&header.payload[i],rr.rdlength);
112 res[rr.rdlength] = 0;
113 break;
114 case DNS_QUERY_A:
115+ if (rr.rdlength != sizeof(struct in_addr))
116+ return std::make_pair((unsigned char *) NULL, "rr.rdlength is larger than 4 bytes for an ipv4 entry -- malformed/hostile packet?");
117+
118 memcpy(res,&header.payload[i],rr.rdlength);
119 res[rr.rdlength] = 0;
120 break;
121 default:
122- memcpy(res,&header.payload[i],rr.rdlength);
123- res[rr.rdlength] = 0;
124+ return std::make_pair((unsigned char *) NULL, "don't know how to handle undefined type (" + ConvToStr(rr.type) + ") -- rejecting");
125 break;
126 }
127 return std::make_pair(res,"No error");;

Subscribers

People subscribed via source and target branches

to all changes: