Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 9 Apr 2011 11:03:04 +0000 (UTC)
From:      "Bjoern A. Zeeb" <bz@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-6@freebsd.org
Subject:   svn commit: r220485 - in stable/6/sys: netinet6 netipsec
Message-ID:  <201104091103.p39B34tx011757@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: bz
Date: Sat Apr  9 11:03:04 2011
New Revision: 220485
URL: http://svn.freebsd.org/changeset/base/220485

Log:
  MFC r220247:
  
    Do not allow directly recursive RFC3173 IPComp payload.
  
    While IPv6 does count iterations over next headers in ip6_input,
    we still disallow directly recursive IPComp payload in the KAME code.
  
  Security:	CVE-2011-1547

Modified:
  stable/6/sys/netinet6/ipcomp_input.c
  stable/6/sys/netipsec/xform_ipcomp.c
Directory Properties:
  stable/6/sys/   (props changed)
  stable/6/sys/contrib/pf/   (props changed)
  stable/6/sys/dev/cxgb/   (props changed)

Modified: stable/6/sys/netinet6/ipcomp_input.c
==============================================================================
--- stable/6/sys/netinet6/ipcomp_input.c	Sat Apr  9 10:58:38 2011	(r220484)
+++ stable/6/sys/netinet6/ipcomp_input.c	Sat Apr  9 11:03:04 2011	(r220485)
@@ -117,8 +117,21 @@ ipcomp4_input(m, off)
 		goto fail;
 	}
 	ipcomp = mtod(md, struct ipcomp *);
-	ip = mtod(m, struct ip *);
 	nxt = ipcomp->comp_nxt;
+
+	/*
+	 * Check that the next header of the IPComp is not IPComp again, before
+	 * doing any real work.  Given it is not possible to do double
+	 * compression it means someone is playing tricks on us.
+	 */
+	if (nxt == IPPROTO_IPCOMP) {
+		ipseclog((LOG_ERR, "IPv4 IPComp input: "
+		    "recursive compression detected."));
+		ipsecstat.in_inval++;
+		goto fail;
+	}
+
+	ip = mtod(m, struct ip *);
 #ifdef _IP_VHL
 	hlen = IP_VHL_HL(ip->ip_vhl) << 2;
 #else
@@ -269,6 +282,18 @@ ipcomp6_input(mp, offp, proto)
 	ip6 = mtod(m, struct ip6_hdr *);
 	nxt = ipcomp->comp_nxt;
 
+	/*
+	 * Check that the next header of the IPComp is not IPComp again, before
+	 * doing any real work.  Given it is not possible to do double
+	 * compression it means someone is playing tricks on us.
+	 */
+	if (nxt == IPPROTO_IPCOMP) {
+		ipseclog((LOG_ERR, "IPv6 IPComp input: "
+		    "recursive compression detected."));
+		ipsecstat.in_inval++;
+		goto fail;
+	}
+
 	cpi = ntohs(ipcomp->comp_cpi);
 
 	if (cpi >= IPCOMP_CPI_NEGOTIATE_MIN) {

Modified: stable/6/sys/netipsec/xform_ipcomp.c
==============================================================================
--- stable/6/sys/netipsec/xform_ipcomp.c	Sat Apr  9 10:58:38 2011	(r220484)
+++ stable/6/sys/netipsec/xform_ipcomp.c	Sat Apr  9 11:03:04 2011	(r220485)
@@ -139,10 +139,31 @@ ipcomp_input(struct mbuf *m, struct seca
 	struct tdb_crypto *tc;
 	struct cryptodesc *crdc;
 	struct cryptop *crp;
+	struct ipcomp *ipcomp;
+	caddr_t addr;
 	int hlen = IPCOMP_HLENGTH;
 
 	IPSEC_SPLASSERT_SOFTNET(__func__);
 
+	/*
+	 * Check that the next header of the IPComp is not IPComp again, before
+	 * doing any real work.  Given it is not possible to do double
+	 * compression it means someone is playing tricks on us.
+	 */
+	if (m->m_len < skip + hlen && (m = m_pullup(m, skip + hlen)) == NULL) {
+		ipcompstat.ipcomps_hdrops++;		/*XXX*/
+		DPRINTF(("%s: m_pullup failed\n", __func__));
+		return (ENOBUFS);
+	}
+	addr = (caddr_t) mtod(m, struct ip *) + skip;
+	ipcomp = (struct ipcomp *)addr;
+	if (ipcomp->comp_nxt == IPPROTO_IPCOMP) {
+		m_freem(m);
+		ipcompstat.ipcomps_pdrops++;	/* XXX have our own stats? */
+		DPRINTF(("%s: recursive compression detected\n", __func__));
+		return (EINVAL);
+	}
+
 	/* Get crypto descriptors */
 	crp = crypto_getreq(1);
 	if (crp == NULL) {



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201104091103.p39B34tx011757>