From ab2f82959db5c9850423130b77a2950dcdcff9b8 Mon Sep 17 00:00:00 2001 From: bluhm Date: Tue, 20 Jun 2017 11:12:13 +0000 Subject: [PATCH] Do not use the interface pointer after if_put(). Rename ipip_input_gif() to ipip_input_if() and always pass the ifp. Only dump the packet to bpf if we are called with a gif(4) interface. OK mpi@ --- sys/net/if_gif.c | 6 +++--- sys/netinet/ip_ipip.c | 45 +++++++++++++++++++++++-------------------- sys/netinet/ip_ipip.h | 4 ++-- 3 files changed, 29 insertions(+), 26 deletions(-) diff --git a/sys/net/if_gif.c b/sys/net/if_gif.c index 051cbcf3309..3b46296a63e 100644 --- a/sys/net/if_gif.c +++ b/sys/net/if_gif.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_gif.c,v 1.97 2017/06/19 17:58:49 bluhm Exp $ */ +/* $OpenBSD: if_gif.c,v 1.98 2017/06/20 11:12:13 bluhm Exp $ */ /* $KAME: if_gif.c,v 1.43 2001/02/20 08:51:07 itojun Exp $ */ /* @@ -751,7 +751,7 @@ in_gif_input(struct mbuf **mp, int *offp, int proto, int af) gifp->if_ipackets++; gifp->if_ibytes += m->m_pkthdr.len; /* We have a configured GIF */ - return ipip_input_gif(mp, offp, proto, af, gifp); + return ipip_input_if(mp, offp, proto, af, gifp); } inject: @@ -876,7 +876,7 @@ int in6_gif_input(struct mbuf **mp, int *offp, int proto, int af) m->m_pkthdr.ph_ifidx = gifp->if_index; gifp->if_ipackets++; gifp->if_ibytes += m->m_pkthdr.len; - return ipip_input_gif(mp, offp, proto, af, gifp); + return ipip_input_if(mp, offp, proto, af, gifp); } inject: diff --git a/sys/netinet/ip_ipip.c b/sys/netinet/ip_ipip.c index 214d4c31b16..a7de3254c7a 100644 --- a/sys/netinet/ip_ipip.c +++ b/sys/netinet/ip_ipip.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ip_ipip.c,v 1.84 2017/06/19 17:58:49 bluhm Exp $ */ +/* $OpenBSD: ip_ipip.c,v 1.85 2017/06/20 11:12:13 bluhm Exp $ */ /* * The authors of this code are John Ioannidis (ji@tla.org), * Angelos D. Keromytis (kermit@csd.uch.gr) and @@ -39,6 +39,8 @@ * IP-inside-IP processing */ +#include "bpfilter.h" +#include "gif.h" #include "pf.h" #include @@ -48,6 +50,7 @@ #include #include +#include #include #include #include @@ -64,8 +67,6 @@ #include #endif -#include "bpfilter.h" - #if NPF > 0 #include #endif @@ -91,11 +92,13 @@ ipip_init(void) } /* - * Really only a wrapper for ipip_input_gif(), for use with pr_input. + * Really only a wrapper for ipip_input_if(), for use with pr_input. */ int -ipip_input(struct mbuf **mp, int *offp, int proto, int af) +ipip_input(struct mbuf **mp, int *offp, int nxt, int af) { + struct ifnet *ifp; + /* If we do not accept IP-in-IP explicitly, drop. */ if (!ipip_allow && ((*mp)->m_flags & (M_AUTH|M_CONF)) == 0) { DPRINTF(("%s: dropped due to policy\n", __func__)); @@ -104,7 +107,15 @@ ipip_input(struct mbuf **mp, int *offp, int proto, int af) return IPPROTO_DONE; } - return ipip_input_gif(mp, offp, proto, af, NULL); + ifp = if_get((*mp)->m_pkthdr.ph_ifidx); + if (ifp == NULL) { + m_freemp(mp); + return IPPROTO_DONE; + } + nxt = ipip_input_if(mp, offp, nxt, af, ifp); + if_put(ifp); + + return nxt; } /* @@ -116,12 +127,11 @@ ipip_input(struct mbuf **mp, int *offp, int proto, int af) */ int -ipip_input_gif(struct mbuf **mp, int *offp, int proto, int oaf, - struct ifnet *gifp) +ipip_input_if(struct mbuf **mp, int *offp, int proto, int oaf, + struct ifnet *ifp) { struct mbuf *m = *mp; struct sockaddr_in *sin; - struct ifnet *ifp; struct ip *ip; #ifdef INET6 struct sockaddr_in6 *sin6; @@ -224,8 +234,7 @@ ipip_input_gif(struct mbuf **mp, int *offp, int proto, int oaf, hlen = ip->ip_hl << 2; if (m->m_pkthdr.len < hlen) { ipipstat_inc(ipips_hdrops); - m_freem(m); - return IPPROTO_DONE; + goto bad; } itos = ip->ip_tos; mode = m->m_flags & (M_AUTH|M_CONF) ? @@ -258,14 +267,10 @@ ipip_input_gif(struct mbuf **mp, int *offp, int proto, int oaf, } /* Check for local address spoofing. */ - ifp = if_get(m->m_pkthdr.ph_ifidx); - if (((ifp == NULL) || !(ifp->if_flags & IFF_LOOPBACK)) && - ipip_allow != 2) { + if (!(ifp->if_flags & IFF_LOOPBACK) && ipip_allow != 2) { struct sockaddr_storage ss; struct rtentry *rt; - if_put(ifp); - memset(&ss, 0, sizeof(ss)); if (ip) { @@ -288,16 +293,14 @@ ipip_input_gif(struct mbuf **mp, int *offp, int proto, int oaf, goto bad; } rtfree(rt); - } else { - if_put(ifp); } /* Statistics */ ipipstat_add(ipips_ibytes, m->m_pkthdr.len - hlen); -#if NBPFILTER > 0 - if (gifp && gifp->if_bpf) - bpf_mtap_af(gifp->if_bpf, iaf, m, BPF_DIRECTION_IN); +#if NBPFILTER > 0 && NGIF > 0 + if (ifp->if_type == IFT_GIF && ifp->if_bpf != NULL) + bpf_mtap_af(ifp->if_bpf, iaf, m, BPF_DIRECTION_IN); #endif #if NPF > 0 pf_pkt_addr_changed(m); diff --git a/sys/netinet/ip_ipip.h b/sys/netinet/ip_ipip.h index 2b8dc9144a5..3ff6d1e1aaa 100644 --- a/sys/netinet/ip_ipip.h +++ b/sys/netinet/ip_ipip.h @@ -1,4 +1,4 @@ -/* $OpenBSD: ip_ipip.h,v 1.9 2017/05/18 10:56:45 bluhm Exp $ */ +/* $OpenBSD: ip_ipip.h,v 1.10 2017/06/20 11:12:13 bluhm Exp $ */ /* * The authors of this code are John Ioannidis (ji@tla.org), * Angelos D. Keromytis (kermit@csd.uch.gr) and @@ -106,7 +106,7 @@ ipipstat_add(enum ipipstat_counters c, uint64_t v) void ipip_init(void); int ipip_input(struct mbuf **, int *, int, int); -int ipip_input_gif(struct mbuf **, int *, int, int, struct ifnet *); +int ipip_input_if(struct mbuf **, int *, int, int, struct ifnet *); int ipip_output(struct mbuf *, struct tdb *, struct mbuf **, int, int); int ipip_sysctl(int *, u_int, void *, size_t *, void *, size_t); -- 2.20.1