summaryrefslogtreecommitdiffstats
path: root/sys/netinet
diff options
context:
space:
mode:
authorsashan <sashan@openbsd.org>2019-12-08 11:08:22 +0000
committersashan <sashan@openbsd.org>2019-12-08 11:08:22 +0000
commit144d7e8ec45c41ef58c8b309e276b5f35ab67b6e (patch)
tree7957cff8319010db3b77ca153f72a75656121031 /sys/netinet
parenthave DEBUG_PKG_CACHE also apply to already installed packages, to (diff)
downloadwireguard-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.h16
-rw-r--r--sys/netinet/ip_input.c28
-rw-r--r--sys/netinet/ip_var.h4
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
};