svn commit: r345378 - stable/11/sys/netpfil/pf
Kristof Provost
kp at FreeBSD.org
Thu Mar 21 14:17:13 UTC 2019
Author: kp
Date: Thu Mar 21 14:17:12 2019
New Revision: 345378
URL: https://svnweb.freebsd.org/changeset/base/345378
Log:
MFC r345366:
pf: Ensure that IP addresses match in ICMP error packets
States in pf(4) let ICMP and ICMP6 packets pass if they have a
packet in their payload that matches an exiting connection. It was
not checked whether the outer ICMP packet has the same destination
IP as the source IP of the inner protocol packet. Enforce that
these addresses match, to prevent ICMP packets that do not make
sense.
Reported by: Nicolas Collignon, Corentin Bayet, Eloi Vanderbeken, Luca Moro at Synacktiv
Obtained from: OpenBSD
Security: CVE-2019-5598
Modified:
stable/11/sys/netpfil/pf/pf.c
Directory Properties:
stable/11/ (props changed)
Modified: stable/11/sys/netpfil/pf/pf.c
==============================================================================
--- stable/11/sys/netpfil/pf/pf.c Thu Mar 21 14:17:10 2019 (r345377)
+++ stable/11/sys/netpfil/pf/pf.c Thu Mar 21 14:17:12 2019 (r345378)
@@ -4578,7 +4578,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;
@@ -4587,6 +4587,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;
@@ -4601,6 +4602,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;
@@ -4799,6 +4801,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;
@@ -4855,7 +4874,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);
@@ -4868,7 +4887,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);
More information about the svn-src-stable-11
mailing list