diff options
author | Alexander Bluhm <bluhm@cvs.openbsd.org> | 2017-12-14 14:26:51 +0000 |
---|---|---|
committer | Alexander Bluhm <bluhm@cvs.openbsd.org> | 2017-12-14 14:26:51 +0000 |
commit | 180e58c91ba2c116ad7da261ab12aa3ab6995859 (patch) | |
tree | 7aac0ed766ba2023dec49e6a79b62d5af69f503b /sys/netinet | |
parent | 90d0c98dce164ac8e0de0b86b92b04a2547c7430 (diff) |
The pf code marks ICMP packets belonging to an TCP or UDP divert
state as diverted. This is necessary for IP input to accept the
packet as ours. But it must not be used to match the ICMP packet
to a raw socket. Clear the PF_TAG_DIVERTED mbuf pf flag for the
special ICMP and ICMP6 packets in icmp_input_if() and icmp6_input().
The m_tag_delete_chain() caused an inconsistent PF_TAG_DIVERTED
mbuf pf flag and PACKET_TAG_PF_DIVERT mbuf tag which triggered an
assert in rip_input(). Deleting all mbuf tags can have undesired
side effects and is not necessary anymore since icmp_reflect() calls
m_resethdr(). Do not touch the mbuf tags and adjust the mbuf pf
flags for the correct behavior of rip_input() and rip6_input().
reported by Chris Eidem, James Turner, vicviq, Scott Vanderbilt
OK mpi@
Diffstat (limited to 'sys/netinet')
-rw-r--r-- | sys/netinet/ip_icmp.c | 30 |
1 files changed, 12 insertions, 18 deletions
diff --git a/sys/netinet/ip_icmp.c b/sys/netinet/ip_icmp.c index f218b6f428e..b71e8738da2 100644 --- a/sys/netinet/ip_icmp.c +++ b/sys/netinet/ip_icmp.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ip_icmp.c,v 1.173 2017/10/18 17:01:14 bluhm Exp $ */ +/* $OpenBSD: ip_icmp.c,v 1.174 2017/12/14 14:26:50 bluhm Exp $ */ /* $NetBSD: ip_icmp.c,v 1.19 1996/02/13 23:42:22 christos Exp $ */ /* @@ -378,6 +378,12 @@ icmp_input_if(struct ifnet *ifp, struct mbuf **mp, int *offp, int proto, int af) #if NPF > 0 if (m->m_pkthdr.pf.flags & PF_TAG_DIVERTED) { switch (icp->icmp_type) { + /* + * As pf_icmp_mapping() considers redirects belonging to a + * diverted connection, we must include it here. + */ + case ICMP_REDIRECT: + /* FALLTHROUGH */ /* * These ICMP types map to other connections. They must be * delivered to pr_ctlinput() also for diverted connections. @@ -386,12 +392,11 @@ icmp_input_if(struct ifnet *ifp, struct mbuf **mp, int *offp, int proto, int af) case ICMP_TIMXCEED: case ICMP_PARAMPROB: case ICMP_SOURCEQUENCH: - break; - /* - * Although pf_icmp_mapping() considers redirects belonging - * to a diverted connection, we must process it here anyway. - */ - case ICMP_REDIRECT: + /* + * Do not use the divert-to property of the TCP or UDP + * rule when doing the PCB lookup for the raw socket. + */ + m->m_pkthdr.pf.flags &=~ PF_TAG_DIVERTED; break; default: goto raw; @@ -454,10 +459,6 @@ icmp_input_if(struct ifnet *ifp, struct mbuf **mp, int *offp, int proto, int af) goto badcode; code = PRC_QUENCH; deliver: - /* Free packet atttributes */ - if (m->m_flags & M_PKTHDR) - m_tag_delete_chain(m); - /* * Problem with datagram; advise higher level routines. */ @@ -585,10 +586,6 @@ reflect: &ip->ip_dst.s_addr, 1)) goto freeit; #endif - /* Free packet atttributes */ - if (m->m_flags & M_PKTHDR) - m_tag_delete_chain(m); - icmpstat_inc(icps_reflect); icmpstat_inc(icps_outhist + icp->icmp_type); if (!icmp_reflect(m, &opts, NULL)) { @@ -604,9 +601,6 @@ reflect: struct sockaddr_in ssrc; struct rtentry *newrt = NULL; - /* Free packet atttributes */ - if (m->m_flags & M_PKTHDR) - m_tag_delete_chain(m); if (icmp_rediraccept == 0 || ipforwarding == 1) goto freeit; if (code > 3) |