Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 17 Aug 2018 15:00:10 +0000 (UTC)
From:      Kristof Provost <kp@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r337969 - head/sys/netpfil/pf
Message-ID:  <201808171500.w7HF0AU6074065@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: kp
Date: Fri Aug 17 15:00:10 2018
New Revision: 337969
URL: https://svnweb.freebsd.org/changeset/base/337969

Log:
  pf: Limit the maximum number of fragments per packet
  
  Similar to the network stack issue fixed in r337782 pf did not limit the number
  of fragments per packet, which could be exploited to generate high CPU loads
  with a crafted series of packets.
  
  Limit each packet to no more than 64 fragments. This should be sufficient on
  typical networks to allow maximum-sized IP frames.
  
  This addresses the issue for both IPv4 and IPv6.
  
  MFC after:	3 days
  Security:	CVE-2018-5391
  Sponsored by:	Klara Systems

Modified:
  head/sys/netpfil/pf/pf_norm.c

Modified: head/sys/netpfil/pf/pf_norm.c
==============================================================================
--- head/sys/netpfil/pf/pf_norm.c	Fri Aug 17 14:57:13 2018	(r337968)
+++ head/sys/netpfil/pf/pf_norm.c	Fri Aug 17 15:00:10 2018	(r337969)
@@ -91,8 +91,10 @@ struct pf_fragment {
 	TAILQ_ENTRY(pf_fragment) frag_next;
 	uint32_t	fr_timeout;
 	uint16_t	fr_maxlen;	/* maximum length of single fragment */
+	uint16_t	fr_entries;	/* Total number of pf_fragment entries */
 	TAILQ_HEAD(pf_fragq, pf_frent) fr_queue;
 };
+#define PF_MAX_FRENT_PER_FRAGMENT	64
 
 struct pf_fragment_tag {
 	uint16_t	ft_hdrlen;	/* header length of reassembled pkt */
@@ -384,6 +386,7 @@ pf_fillup_fragment(struct pf_fragment_cmp *key, struct
 		*(struct pf_fragment_cmp *)frag = *key;
 		frag->fr_timeout = time_uptime;
 		frag->fr_maxlen = frent->fe_len;
+		frag->fr_entries = 0;
 		TAILQ_INIT(&frag->fr_queue);
 
 		RB_INSERT(pf_frag_tree, &V_pf_frag_tree, frag);
@@ -395,6 +398,9 @@ pf_fillup_fragment(struct pf_fragment_cmp *key, struct
 		return (frag);
 	}
 
+	if (frag->fr_entries >= PF_MAX_FRENT_PER_FRAGMENT)
+		goto bad_fragment;
+
 	KASSERT(!TAILQ_EMPTY(&frag->fr_queue), ("!TAILQ_EMPTY()->fr_queue"));
 
 	/* Remember maximum fragment len for refragmentation. */
@@ -466,6 +472,8 @@ pf_fillup_fragment(struct pf_fragment_cmp *key, struct
 		TAILQ_INSERT_HEAD(&frag->fr_queue, frent, fr_next);
 	else
 		TAILQ_INSERT_AFTER(&frag->fr_queue, prev, frent, fr_next);
+
+	frag->fr_entries++;
 
 	return (frag);
 



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