aboutsummaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorBjoern A. Zeeb <bz@FreeBSD.org>2011-04-09 10:53:36 +0000
committerBjoern A. Zeeb <bz@FreeBSD.org>2011-04-09 10:53:36 +0000
commitb979590a90aec1d2b81cf498fec9927e36397ef7 (patch)
tree82c55cf1ee5a8f4e1727c3f315b8b45da67ad32a /sys
parent376c7fd6c7206116474bc9c9a641c8e2047cbd89 (diff)
Notes
Diffstat (limited to 'sys')
-rw-r--r--sys/netipsec/xform_ipcomp.c21
1 files changed, 21 insertions, 0 deletions
diff --git a/sys/netipsec/xform_ipcomp.c b/sys/netipsec/xform_ipcomp.c
index d528d2abd609..d7a32017184b 100644
--- a/sys/netipsec/xform_ipcomp.c
+++ b/sys/netipsec/xform_ipcomp.c
@@ -141,8 +141,29 @@ ipcomp_input(struct mbuf *m, struct secasvar *sav, int skip, int protoff)
struct tdb_crypto *tc;
struct cryptodesc *crdc;
struct cryptop *crp;
+ struct ipcomp *ipcomp;
+ caddr_t addr;
int hlen = IPCOMP_HLENGTH;
+ /*
+ * 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) {
+ V_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);
+ V_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) {