Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 16 May 2012 14:04:23 -0500
From:      Mark Felder <feld@feld.me>
To:        FreeBSD-gnats-submit@FreeBSD.org
Subject:   ports/167975: [PATCH] irc/inspircd: update to 2.0.5
Message-ID:  <E1SUjWJ-000Fhl-4g@feld.me>
Resent-Message-ID: <201205161910.q4GJA20k070381@freefall.freebsd.org>

next in thread | raw e-mail | index | archive | help

>Number:         167975
>Category:       ports
>Synopsis:       [PATCH] irc/inspircd: update to 2.0.5
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    freebsd-ports-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          update
>Submitter-Id:   current-users
>Arrival-Date:   Wed May 16 19:10:01 UTC 2012
>Closed-Date:
>Last-Modified:
>Originator:     feld
>Release:        FreeBSD 9.0-STABLE amd64
>Organization:
>Environment:
System: FreeBSD mwi1.coffeenet.org 9.0-STABLE FreeBSD 9.0-STABLE #3 r234963: Thu May  3 13:12:01
>Description:
- Update to 2.0.5
- Backport dns.cpp to resolve remote DoS vuln

Added file(s):
- files/patch-src_dns.cpp

Generated with FreeBSD Port Tools 0.99_5 (mode: update, diff: suffix)
>How-To-Repeat:
>Fix:

--- inspircd-2.0.5.patch begins here ---
diff -ruN --exclude=CVS ../inspircd.orig/Makefile ./Makefile
--- ../inspircd.orig/Makefile	2012-01-27 15:38:43.000000000 -0600
+++ ./Makefile	2012-05-15 21:52:21.000000000 -0500
@@ -6,15 +6,16 @@
 #
 
 PORTNAME=	inspircd
-PORTVERSION=	2.0.2
-PORTREVISION=	1
+PORTVERSION=	2.0.5
 CATEGORIES=	irc
-MASTER_SITES=	SF/${PORTNAME}/InspIRCd-2.0/${PORTVERSION}
+MASTER_SITES=	http://cloud.github.com/downloads/inspircd/inspircd/
 DISTNAME=	InspIRCd-${PORTVERSION}
 
 MAINTAINER=	ports@FreeBSD.org
 COMMENT=	A modular C++ IRC daemon
 
+CONFLICTS=	inspircd-1.*
+
 USE_BZIP2=	yes
 USE_RC_SUBR=	${PORTNAME}
 MAKEFILE=	BSDmakefile
diff -ruN --exclude=CVS ../inspircd.orig/distinfo ./distinfo
--- ../inspircd.orig/distinfo	2011-03-18 00:01:25.000000000 -0500
+++ ./distinfo	2012-05-15 21:45:17.000000000 -0500
@@ -1,2 +1,2 @@
-SHA256 (InspIRCd-2.0.2.tar.bz2) = 2ebd2af56da57d68f779c1f707c804b7a480d50c8c943d440f78732e416ab220
-SIZE (InspIRCd-2.0.2.tar.bz2) = 583791
+SHA256 (InspIRCd-2.0.5.tar.bz2) = 425bf79ae1348b398ce6d2348f6cc8baeebe8125f62337e98c136942223f4fc6
+SIZE (InspIRCd-2.0.5.tar.bz2) = 575852
diff -ruN --exclude=CVS ../inspircd.orig/files/patch-src_dns.cpp ./files/patch-src_dns.cpp
--- ../inspircd.orig/files/patch-src_dns.cpp	1969-12-31 18:00:00.000000000 -0600
+++ ./files/patch-src_dns.cpp	2012-05-16 08:29:59.000000000 -0500
@@ -0,0 +1,135 @@
+--- src/dns.cpp.orig	2012-05-15 21:45:31.840274636 -0500
++++ src/dns.cpp	2012-05-15 21:45:58.653278686 -0500
+@@ -38,6 +49,8 @@
+ #include "configreader.h"
+ #include "socket.h"
+ 
++#define DN_COMP_BITMASK	0xC000		/* highest 6 bits in a DN label header */
++
+ /** Masks to mask off the responses we get from the DNSRequest methods
+  */
+ enum QueryInfo
+@@ -98,7 +111,7 @@
+ 
+ 	DNSRequest(DNS* dns, int id, const std::string &original);
+ 	~DNSRequest();
+-	DNSInfo ResultIsReady(DNSHeader &h, int length);
++	DNSInfo ResultIsReady(DNSHeader &h, unsigned length);
+ 	int SendRequests(const DNSHeader *header, const int length, QueryType qt);
+ };
+ 
+@@ -161,7 +174,10 @@
+ /* Allocate the processing buffer */
+ DNSRequest::DNSRequest(DNS* dns, int rid, const std::string &original) : dnsobj(dns)
+ {
+-	res = new unsigned char[512];
++	/* hardening against overflow here:  make our work buffer twice the theoretical
++	 * maximum size so that hostile input doesn't screw us over.
++	 */
++	res = new unsigned char[sizeof(DNSHeader) * 2];
+ 	*res = 0;
+ 	orig = original;
+ 	RequestTimeout* RT = new RequestTimeout(ServerInstance->Config->dns_timeout ? ServerInstance->Config->dns_timeout : 5, this, rid);
+@@ -688,11 +704,11 @@
+ }
+ 
+ /** A result is ready, process it */
+-DNSInfo DNSRequest::ResultIsReady(DNSHeader &header, int length)
++DNSInfo DNSRequest::ResultIsReady(DNSHeader &header, unsigned length)
+ {
+-	int i = 0;
++	unsigned i = 0, o;
+ 	int q = 0;
+-	int curanswer, o;
++	int curanswer;
+ 	ResourceRecord rr;
+  	unsigned short ptr;
+ 
+@@ -755,7 +771,7 @@
+ 				else i += header.payload[i] + 1; /* skip length and label */
+ 			}
+ 		}
+-		if (length - i < 10)
++		if (static_cast<int>(length - i) < 10)
+ 			return std::make_pair((unsigned char*)NULL,"Incorrectly sized DNS reply");
+ 
+ 		/* XXX: We actually initialise 'rr' here including its ttl field */
+@@ -790,17 +806,37 @@
+ 
+ 	switch (rr.type)
+ 	{
++		/*
++		 * CNAME and PTR are compressed.  We need to decompress them.
++		 */
+ 		case DNS_QUERY_CNAME:
+-			/* CNAME and PTR have the same processing code */
+ 		case DNS_QUERY_PTR:
++		{
++			unsigned short lowest_pos = length;
+ 			o = 0;
+ 			q = 0;
+ 			while (q == 0 && i < length && o + 256 < 1023)
+ 			{
++				/* DN label found (byte over 63) */
+ 				if (header.payload[i] > 63)
+ 				{
+ 					memcpy(&ptr,&header.payload[i],2);
+-					i = ntohs(ptr) - 0xC000 - 12;
++
++					i = ntohs(ptr);
++
++					/* check that highest two bits are set. if not, we've been had */
++					if ((i & DN_COMP_BITMASK) != DN_COMP_BITMASK)
++						return std::make_pair((unsigned char *) NULL, "DN label decompression header is bogus");
++
++					/* mask away the two highest bits. */
++					i &= ~DN_COMP_BITMASK;
++
++					/* and decrease length by 12 bytes. */
++					i -= 12;
++
++					if (i >= lowest_pos)
++						return std::make_pair((unsigned char *) NULL, "Invalid decompression pointer");
++					lowest_pos = i;
+ 				}
+ 				else
+ 				{
+@@ -813,25 +849,35 @@
+ 						res[o] = 0;
+ 						if (o != 0)
+ 							res[o++] = '.';
+-						memcpy(&res[o],&header.payload[i + 1],header.payload[i]);
++
++						if (o + header.payload[i] > sizeof(DNSHeader))
++							return std::make_pair((unsigned char *) NULL, "DN label decompression is impossible -- malformed/hostile packet?");
++
++						memcpy(&res[o], &header.payload[i + 1], header.payload[i]);
+ 						o += header.payload[i];
+ 						i += header.payload[i] + 1;
+ 					}
+ 				}
+ 			}
+ 			res[o] = 0;
++		}
+ 		break;
+ 		case DNS_QUERY_AAAA:
++			if (rr.rdlength != sizeof(struct in6_addr))
++				return std::make_pair((unsigned char *) NULL, "rr.rdlength is larger than 16 bytes for an ipv6 entry -- malformed/hostile packet?");
++
+ 			memcpy(res,&header.payload[i],rr.rdlength);
+ 			res[rr.rdlength] = 0;
+ 		break;
+ 		case DNS_QUERY_A:
++			if (rr.rdlength != sizeof(struct in_addr))
++				return std::make_pair((unsigned char *) NULL, "rr.rdlength is larger than 4 bytes for an ipv4 entry -- malformed/hostile packet?");
++
+ 			memcpy(res,&header.payload[i],rr.rdlength);
+ 			res[rr.rdlength] = 0;
+ 		break;
+ 		default:
+-			memcpy(res,&header.payload[i],rr.rdlength);
+-			res[rr.rdlength] = 0;
++			return std::make_pair((unsigned char *) NULL, "don't know how to handle undefined type (" + ConvToStr(rr.type) + ") -- rejecting");
+ 		break;
+ 	}
+ 	return std::make_pair(res,"No error");
--- inspircd-2.0.5.patch ends here ---

>Release-Note:
>Audit-Trail:
>Unformatted:



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?E1SUjWJ-000Fhl-4g>