if_ovpn: cope with loops

User misconfiguration may lead to routing loops where we try to send the tunnel
packet into the tunnel. This eventually leads to stack overflows and panics.

Avoid this using if_tunnel_check_nesting(), which will drop the packet if we're
looping or we hit three layers of nested tunnels.

MFC after:	1 week
Sponsored by:	Rubicon Communications, LLC ("Netgate")
This commit is contained in:
Kristof Provost 2024-05-13 12:06:47 +02:00
parent 421025a274
commit 59a6666ec9
2 changed files with 17 additions and 0 deletions

View File

@ -255,6 +255,7 @@ static const char ovpnname[] = "ovpn";
static const char ovpngroupname[] = "openvpn";
static MALLOC_DEFINE(M_OVPN, ovpnname, "OpenVPN DCO Interface");
#define MTAG_OVPN_LOOP 0x6f76706e /* ovpn */
SYSCTL_DECL(_net_link);
static SYSCTL_NODE(_net_link, IFT_OTHER, openvpn, CTLFLAG_RW | CTLFLAG_MPSAFE, 0,
@ -1854,6 +1855,14 @@ ovpn_transmit_to_peer(struct ifnet *ifp, struct mbuf *m,
if (af != 0)
BPF_MTAP2(ifp, &af, sizeof(af), m);
if (__predict_false(if_tunnel_check_nesting(ifp, m, MTAG_OVPN_LOOP, 3))) {
if (_ovpn_lock_trackerp != NULL)
OVPN_RUNLOCK(sc);
OVPN_COUNTER_ADD(sc, lost_data_pkts_out, 1);
m_freem(m);
return (ELOOP);
}
len = m->m_pkthdr.len;
MPASS(len <= ifp->if_mtu);

View File

@ -95,6 +95,10 @@ atf_test_case "4in4" "cleanup"
echo 'foo' | jexec b nc -u -w 2 192.0.2.1 1194
atf_check -s exit:0 -o ignore jexec b ping -c 3 198.51.100.1
# Test routing loop protection
jexec b route add 192.0.2.1 198.51.100.1
atf_check -s exit:2 -o ignore jexec b ping -t 1 -c 1 198.51.100.1
}
4in4_cleanup()
@ -404,6 +408,10 @@ atf_test_case "6in6" "cleanup"
atf_check -s exit:0 -o ignore jexec b ping6 -c 3 2001:db8:1::1
atf_check -s exit:0 -o ignore jexec b ping6 -c 3 -z 16 2001:db8:1::1
# Test routing loop protection
jexec b route add -6 2001:db8::1 2001:db8:1::1
atf_check -s exit:2 -o ignore jexec b ping6 -t 1 -c 3 2001:db8:1::1
}
6in6_cleanup()