Date: Tue, 14 May 2019 23:12:22 +0000 (UTC) From: Gordon Tetlow <gordon@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-releng@freebsd.org Subject: svn commit: r347593 - in releng: 11.2/sys/netpfil/pf 12.0/sys/netpfil/pf Message-ID: <201905142312.x4ENCMrM058466@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: gordon Date: Tue May 14 23:12:22 2019 New Revision: 347593 URL: https://svnweb.freebsd.org/changeset/base/347593 Log: Fix ICMP/ICMP6 packet filter bypass in pf. Approved by: so Security: FreeBSD-SA-19:06.pf Security: CVE-2019-5598 Modified: releng/11.2/sys/netpfil/pf/pf.c releng/12.0/sys/netpfil/pf/pf.c Modified: releng/11.2/sys/netpfil/pf/pf.c ============================================================================== --- releng/11.2/sys/netpfil/pf/pf.c Tue May 14 23:12:14 2019 (r347592) +++ releng/11.2/sys/netpfil/pf/pf.c Tue May 14 23:12:22 2019 (r347593) @@ -4550,7 +4550,7 @@ pf_test_state_icmp(struct pf_state **state, int direct { struct pf_addr *saddr = pd->src, *daddr = pd->dst; u_int16_t icmpid = 0, *icmpsum; - u_int8_t icmptype; + u_int8_t icmptype, icmpcode; int state_icmp = 0; struct pf_state_key_cmp key; @@ -4559,6 +4559,7 @@ pf_test_state_icmp(struct pf_state **state, int direct #ifdef INET case IPPROTO_ICMP: icmptype = pd->hdr.icmp->icmp_type; + icmpcode = pd->hdr.icmp->icmp_code; icmpid = pd->hdr.icmp->icmp_id; icmpsum = &pd->hdr.icmp->icmp_cksum; @@ -4573,6 +4574,7 @@ pf_test_state_icmp(struct pf_state **state, int direct #ifdef INET6 case IPPROTO_ICMPV6: icmptype = pd->hdr.icmp6->icmp6_type; + icmpcode = pd->hdr.icmp6->icmp6_code; icmpid = pd->hdr.icmp6->icmp6_id; icmpsum = &pd->hdr.icmp6->icmp6_cksum; @@ -4771,6 +4773,23 @@ pf_test_state_icmp(struct pf_state **state, int direct #endif /* INET6 */ } + if (PF_ANEQ(pd->dst, pd2.src, pd->af)) { + if (V_pf_status.debug >= PF_DEBUG_MISC) { + printf("pf: BAD ICMP %d:%d outer dst: ", + icmptype, icmpcode); + pf_print_host(pd->src, 0, pd->af); + printf(" -> "); + pf_print_host(pd->dst, 0, pd->af); + printf(" inner src: "); + pf_print_host(pd2.src, 0, pd2.af); + printf(" -> "); + pf_print_host(pd2.dst, 0, pd2.af); + printf("\n"); + } + REASON_SET(reason, PFRES_BADSTATE); + return (PF_DROP); + } + switch (pd2.proto) { case IPPROTO_TCP: { struct tcphdr th; @@ -4827,7 +4846,7 @@ pf_test_state_icmp(struct pf_state **state, int direct !SEQ_GEQ(seq, src->seqlo - (dst->max_win << dws)))) { if (V_pf_status.debug >= PF_DEBUG_MISC) { printf("pf: BAD ICMP %d:%d ", - icmptype, pd->hdr.icmp->icmp_code); + icmptype, icmpcode); pf_print_host(pd->src, 0, pd->af); printf(" -> "); pf_print_host(pd->dst, 0, pd->af); @@ -4840,7 +4859,7 @@ pf_test_state_icmp(struct pf_state **state, int direct } else { if (V_pf_status.debug >= PF_DEBUG_MISC) { printf("pf: OK ICMP %d:%d ", - icmptype, pd->hdr.icmp->icmp_code); + icmptype, icmpcode); pf_print_host(pd->src, 0, pd->af); printf(" -> "); pf_print_host(pd->dst, 0, pd->af); Modified: releng/12.0/sys/netpfil/pf/pf.c ============================================================================== --- releng/12.0/sys/netpfil/pf/pf.c Tue May 14 23:12:14 2019 (r347592) +++ releng/12.0/sys/netpfil/pf/pf.c Tue May 14 23:12:22 2019 (r347593) @@ -4588,7 +4588,7 @@ pf_test_state_icmp(struct pf_state **state, int direct { struct pf_addr *saddr = pd->src, *daddr = pd->dst; u_int16_t icmpid = 0, *icmpsum; - u_int8_t icmptype; + u_int8_t icmptype, icmpcode; int state_icmp = 0; struct pf_state_key_cmp key; @@ -4597,6 +4597,7 @@ pf_test_state_icmp(struct pf_state **state, int direct #ifdef INET case IPPROTO_ICMP: icmptype = pd->hdr.icmp->icmp_type; + icmpcode = pd->hdr.icmp->icmp_code; icmpid = pd->hdr.icmp->icmp_id; icmpsum = &pd->hdr.icmp->icmp_cksum; @@ -4611,6 +4612,7 @@ pf_test_state_icmp(struct pf_state **state, int direct #ifdef INET6 case IPPROTO_ICMPV6: icmptype = pd->hdr.icmp6->icmp6_type; + icmpcode = pd->hdr.icmp6->icmp6_code; icmpid = pd->hdr.icmp6->icmp6_id; icmpsum = &pd->hdr.icmp6->icmp6_cksum; @@ -4809,6 +4811,23 @@ pf_test_state_icmp(struct pf_state **state, int direct #endif /* INET6 */ } + if (PF_ANEQ(pd->dst, pd2.src, pd->af)) { + if (V_pf_status.debug >= PF_DEBUG_MISC) { + printf("pf: BAD ICMP %d:%d outer dst: ", + icmptype, icmpcode); + pf_print_host(pd->src, 0, pd->af); + printf(" -> "); + pf_print_host(pd->dst, 0, pd->af); + printf(" inner src: "); + pf_print_host(pd2.src, 0, pd2.af); + printf(" -> "); + pf_print_host(pd2.dst, 0, pd2.af); + printf("\n"); + } + REASON_SET(reason, PFRES_BADSTATE); + return (PF_DROP); + } + switch (pd2.proto) { case IPPROTO_TCP: { struct tcphdr th; @@ -4865,7 +4884,7 @@ pf_test_state_icmp(struct pf_state **state, int direct !SEQ_GEQ(seq, src->seqlo - (dst->max_win << dws)))) { if (V_pf_status.debug >= PF_DEBUG_MISC) { printf("pf: BAD ICMP %d:%d ", - icmptype, pd->hdr.icmp->icmp_code); + icmptype, icmpcode); pf_print_host(pd->src, 0, pd->af); printf(" -> "); pf_print_host(pd->dst, 0, pd->af); @@ -4878,7 +4897,7 @@ pf_test_state_icmp(struct pf_state **state, int direct } else { if (V_pf_status.debug >= PF_DEBUG_MISC) { printf("pf: OK ICMP %d:%d ", - icmptype, pd->hdr.icmp->icmp_code); + icmptype, icmpcode); pf_print_host(pd->src, 0, pd->af); printf(" -> "); pf_print_host(pd->dst, 0, pd->af);
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201905142312.x4ENCMrM058466>