Skip to content

Commit 59a6666

Browse files
committed
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")
1 parent 421025a commit 59a6666

File tree

2 files changed

+17
-0
lines changed

2 files changed

+17
-0
lines changed

sys/net/if_ovpn.c

+9
Original file line numberDiff line numberDiff line change
@@ -255,6 +255,7 @@ static const char ovpnname[] = "ovpn";
255255
static const char ovpngroupname[] = "openvpn";
256256

257257
static MALLOC_DEFINE(M_OVPN, ovpnname, "OpenVPN DCO Interface");
258+
#define MTAG_OVPN_LOOP 0x6f76706e /* ovpn */
258259

259260
SYSCTL_DECL(_net_link);
260261
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,
18541855
if (af != 0)
18551856
BPF_MTAP2(ifp, &af, sizeof(af), m);
18561857

1858+
if (__predict_false(if_tunnel_check_nesting(ifp, m, MTAG_OVPN_LOOP, 3))) {
1859+
if (_ovpn_lock_trackerp != NULL)
1860+
OVPN_RUNLOCK(sc);
1861+
OVPN_COUNTER_ADD(sc, lost_data_pkts_out, 1);
1862+
m_freem(m);
1863+
return (ELOOP);
1864+
}
1865+
18571866
len = m->m_pkthdr.len;
18581867
MPASS(len <= ifp->if_mtu);
18591868

tests/sys/net/if_ovpn/if_ovpn.sh

+8
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,10 @@ atf_test_case "4in4" "cleanup"
9595

9696
echo 'foo' | jexec b nc -u -w 2 192.0.2.1 1194
9797
atf_check -s exit:0 -o ignore jexec b ping -c 3 198.51.100.1
98+
99+
# Test routing loop protection
100+
jexec b route add 192.0.2.1 198.51.100.1
101+
atf_check -s exit:2 -o ignore jexec b ping -t 1 -c 1 198.51.100.1
98102
}
99103

100104
4in4_cleanup()
@@ -404,6 +408,10 @@ atf_test_case "6in6" "cleanup"
404408

405409
atf_check -s exit:0 -o ignore jexec b ping6 -c 3 2001:db8:1::1
406410
atf_check -s exit:0 -o ignore jexec b ping6 -c 3 -z 16 2001:db8:1::1
411+
412+
# Test routing loop protection
413+
jexec b route add -6 2001:db8::1 2001:db8:1::1
414+
atf_check -s exit:2 -o ignore jexec b ping6 -t 1 -c 3 2001:db8:1::1
407415
}
408416

409417
6in6_cleanup()

0 commit comments

Comments
 (0)