From owner-svn-src-head@freebsd.org Fri Aug 17 15:00:11 2018 Return-Path: Delivered-To: svn-src-head@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 162131071770; Fri, 17 Aug 2018 15:00:11 +0000 (UTC) (envelope-from kp@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client CN "mxrelay.nyi.freebsd.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id C11A381C40; Fri, 17 Aug 2018 15:00:10 +0000 (UTC) (envelope-from kp@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 898FB1E3F; Fri, 17 Aug 2018 15:00:10 +0000 (UTC) (envelope-from kp@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id w7HF0AZL074066; Fri, 17 Aug 2018 15:00:10 GMT (envelope-from kp@FreeBSD.org) Received: (from kp@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id w7HF0AU6074065; Fri, 17 Aug 2018 15:00:10 GMT (envelope-from kp@FreeBSD.org) Message-Id: <201808171500.w7HF0AU6074065@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: kp set sender to kp@FreeBSD.org using -f From: Kristof Provost Date: Fri, 17 Aug 2018 15:00:10 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r337969 - head/sys/netpfil/pf X-SVN-Group: head X-SVN-Commit-Author: kp X-SVN-Commit-Paths: head/sys/netpfil/pf X-SVN-Commit-Revision: 337969 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.27 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 17 Aug 2018 15:00:11 -0000 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);