summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authorbluhm <bluhm@openbsd.org>2021-01-09 14:55:21 +0000
committerbluhm <bluhm@openbsd.org>2021-01-09 14:55:21 +0000
commitc11d769847158f602e4679ab235305bcfb99b511 (patch)
tree11172985e8aa030e007564da42f33e70582bf5ca /sys
parentRemove locally imposed limit on sockets. (diff)
downloadwireguard-openbsd-c11d769847158f602e4679ab235305bcfb99b511.tar.xz
wireguard-openbsd-c11d769847158f602e4679ab235305bcfb99b511.zip
Syzkaller has found a stack overflow in socket splicing. Broadcast
packets were resent through simplex broadcast delivery and socket splicing. Although there is an M_LOOP check in somove(9), it did not take effect. if_input_local() cleared the M_BCAST and M_MCAST flags with m_resethdr(). As if_input_local() is used for broadcast and multicast delivery, it was a mistake to delete them. Keep the M_BCAST and M_MCAST mbuf flags when packets are reinjected into the network stack. Reported-by: syzbot+a43ace363f1b663238f8@syzkaller.appspotmail.com OK anton@; discussed with claudio@
Diffstat (limited to 'sys')
-rw-r--r--sys/net/if.c7
1 files changed, 5 insertions, 2 deletions
diff --git a/sys/net/if.c b/sys/net/if.c
index e96e4994564..0206594d787 100644
--- a/sys/net/if.c
+++ b/sys/net/if.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if.c,v 1.623 2021/01/04 21:21:41 kn Exp $ */
+/* $OpenBSD: if.c,v 1.624 2021/01/09 14:55:21 bluhm Exp $ */
/* $NetBSD: if.c,v 1.35 1996/05/07 05:26:04 thorpej Exp $ */
/*
@@ -740,6 +740,8 @@ if_input(struct ifnet *ifp, struct mbuf_list *ml)
int
if_input_local(struct ifnet *ifp, struct mbuf *m, sa_family_t af)
{
+ int keepflags;
+
#if NBPFILTER > 0
/*
* Only send packets to bpf if they are destinated to local
@@ -755,8 +757,9 @@ if_input_local(struct ifnet *ifp, struct mbuf *m, sa_family_t af)
bpf_mtap_af(if_bpf, af, m, BPF_DIRECTION_OUT);
}
#endif
+ keepflags = m->m_flags & (M_BCAST|M_MCAST);
m_resethdr(m);
- m->m_flags |= M_LOOP;
+ m->m_flags |= M_LOOP | keepflags;
m->m_pkthdr.ph_ifidx = ifp->if_index;
m->m_pkthdr.ph_rtableid = ifp->if_rdomain;