Skip to content

Commit 18c38ed

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") (cherry picked from commit 59a6666)
1 parent ab135e1 commit 18c38ed

File tree

2 files changed

+17
-0
lines changed

2 files changed

+17
-0
lines changed

Diff for: 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,
@@ -1858,6 +1859,14 @@ ovpn_transmit_to_peer(struct ifnet *ifp, struct mbuf *m,
18581859
if (af != 0)
18591860
BPF_MTAP2(ifp, &af, sizeof(af), m);
18601861

1862+
if (__predict_false(if_tunnel_check_nesting(ifp, m, MTAG_OVPN_LOOP, 3))) {
1863+
if (_ovpn_lock_trackerp != NULL)
1864+
OVPN_RUNLOCK(sc);
1865+
OVPN_COUNTER_ADD(sc, lost_data_pkts_out, 1);
1866+
m_freem(m);
1867+
return (ELOOP);
1868+
}
1869+
18611870
len = m->m_pkthdr.len;
18621871
MPASS(len <= ifp->if_mtu);
18631872

Diff for: 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()
@@ -386,6 +390,10 @@ atf_test_case "6in6" "cleanup"
386390

387391
atf_check -s exit:0 -o ignore jexec b ping6 -c 3 2001:db8:1::1
388392
atf_check -s exit:0 -o ignore jexec b ping6 -c 3 -z 16 2001:db8:1::1
393+
394+
# Test routing loop protection
395+
jexec b route add -6 2001:db8::1 2001:db8:1::1
396+
atf_check -s exit:2 -o ignore jexec b ping6 -t 1 -c 3 2001:db8:1::1
389397
}
390398

391399
6in6_cleanup()

0 commit comments

Comments
 (0)