diff options
author | 2019-12-08 11:08:22 +0000 | |
---|---|---|
committer | 2019-12-08 11:08:22 +0000 | |
commit | 144d7e8ec45c41ef58c8b309e276b5f35ab67b6e (patch) | |
tree | 7957cff8319010db3b77ca153f72a75656121031 /sys/netinet | |
parent | have DEBUG_PKG_CACHE also apply to already installed packages, to (diff) | |
download | wireguard-openbsd-144d7e8ec45c41ef58c8b309e276b5f35ab67b6e.tar.xz wireguard-openbsd-144d7e8ec45c41ef58c8b309e276b5f35ab67b6e.zip |
Make sure packet destination address matches interface address,
where such packet is bound to. This check is enforced if and only
IP forwarding is disabled.
Change discussed with bluhm@, claudio@, deraadt@, markus@, tobhe@
OK bluhm@, claudio@, tobhe@
Diffstat (limited to 'sys/netinet')
-rw-r--r-- | sys/netinet/ip_carp.h | 16 | ||||
-rw-r--r-- | sys/netinet/ip_input.c | 28 | ||||
-rw-r--r-- | sys/netinet/ip_var.h | 4 |
3 files changed, 44 insertions, 4 deletions
diff --git a/sys/netinet/ip_carp.h b/sys/netinet/ip_carp.h index 8911e9170e2..8466ee9bb9d 100644 --- a/sys/netinet/ip_carp.h +++ b/sys/netinet/ip_carp.h @@ -1,4 +1,4 @@ -/* $OpenBSD: ip_carp.h,v 1.47 2018/05/21 15:52:22 bluhm Exp $ */ +/* $OpenBSD: ip_carp.h,v 1.48 2019/12/08 11:08:22 sashan Exp $ */ /* * Copyright (c) 2002 Michael Shalayeff. All rights reserved. @@ -163,6 +163,7 @@ struct carpreq { #ifdef _KERNEL +#include <net/if_types.h> #include <sys/percpu.h> enum carpstat_counters { @@ -193,6 +194,19 @@ carpstat_inc(enum carpstat_counters c) counters_inc(carpcounters, c); } +/* + * If two carp interfaces share same physical interface, then we pretend all IP + * addresses belong to single interface. + */ +static inline int +carp_strict_addr_chk(struct ifnet *ifp_a, struct ifnet *ifp_b) +{ + return ((ifp_a->if_type == IFT_CARP && ifp_b == ifp_a->if_carpdev) || + (ifp_b->if_type == IFT_CARP && ifp_a == ifp_b->if_carpdev) || + (ifp_a->if_type == IFT_CARP && ifp_b->if_type == IFT_CARP && + ifp_a->if_carpdev == ifp_b->if_carpdev)); +} + int carp_proto_input(struct mbuf **, int *, int, int); void carp_carpdev_state(void *); void carp_group_demote_adj(struct ifnet *, int, char *); diff --git a/sys/netinet/ip_input.c b/sys/netinet/ip_input.c index 4aa2f13e566..1a7b9910c41 100644 --- a/sys/netinet/ip_input.c +++ b/sys/netinet/ip_input.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ip_input.c,v 1.344 2019/08/06 22:57:54 bluhm Exp $ */ +/* $OpenBSD: ip_input.c,v 1.345 2019/12/08 11:08:22 sashan Exp $ */ /* $NetBSD: ip_input.c,v 1.30 1996/03/16 23:53:58 christos Exp $ */ /* @@ -341,7 +341,10 @@ ip_input_if(struct mbuf **mp, int *offp, int nxt, int af, struct ifnet *ifp) goto out; } - if (in_ouraddr(m, ifp, &rt)) { + switch(in_ouraddr(m, ifp, &rt)) { + case 2: + goto bad; + case 1: nxt = ip_ours(mp, offp, nxt, af); goto out; } @@ -749,6 +752,27 @@ in_ouraddr(struct mbuf *m, struct ifnet *ifp, struct rtentry **prt) break; } } + } else if (ipforwarding == 0 && rt->rt_ifidx != ifp->if_index && + !((ifp->if_flags & IFF_LOOPBACK) || (ifp->if_type == IFT_ENC))) { + /* received on wrong interface. */ +#if NCARP > 0 + struct ifnet *out_if; + + /* + * Virtual IPs on carp interfaces need to be checked also + * against the parent interface and other carp interfaces + * sharing the same parent. + */ + out_if = if_get(rt->rt_ifidx); + if (!(out_if && carp_strict_addr_chk(out_if, ifp))) { + ipstat_inc(ips_wrongif); + match = 2; + } + if_put(out_if); +#else + ipstat_inc(ips_wrongif); + match = 2; +#endif } return (match); diff --git a/sys/netinet/ip_var.h b/sys/netinet/ip_var.h index 4cd91694140..b54e687110b 100644 --- a/sys/netinet/ip_var.h +++ b/sys/netinet/ip_var.h @@ -1,4 +1,4 @@ -/* $OpenBSD: ip_var.h,v 1.85 2017/11/15 11:48:59 mpi Exp $ */ +/* $OpenBSD: ip_var.h,v 1.86 2019/12/08 11:08:22 sashan Exp $ */ /* $NetBSD: ip_var.h,v 1.16 1996/02/13 23:43:20 christos Exp $ */ /* @@ -87,6 +87,7 @@ struct ipstat { u_long ips_inswcsum; /* software checksummed on input */ u_long ips_outswcsum; /* software checksummed on output */ u_long ips_notmember; /* multicasts for unregistered groups */ + u_long ips_wrongif; /* packet received on wrong interface */ }; struct ipoption { @@ -131,6 +132,7 @@ enum ipstat_counters { ips_inswcsum, /* software checksummed on input */ ips_outswcsum, /* software checksummed on output */ ips_notmember, /* multicasts for unregistered groups */ + ips_wrongif, /* packet received on wrong interface */ ips_ncounters }; |