Check for infinite recursion possible on some broken PPTP/L2TP/... VPN setups.

Mark packets with mbuf_tag on first interface passage and drop on second.

PR:		ports/129625, ports/125303,
MFC after:	2 weeks
This commit is contained in:
Alexander Motin 2009-01-20 22:26:09 +00:00
parent 127a7d3f89
commit 575573fb08
2 changed files with 21 additions and 0 deletions

View File

@ -356,6 +356,7 @@ static int
ng_iface_output(struct ifnet *ifp, struct mbuf *m, ng_iface_output(struct ifnet *ifp, struct mbuf *m,
struct sockaddr *dst, struct rtentry *rt0) struct sockaddr *dst, struct rtentry *rt0)
{ {
struct m_tag *mtag;
uint32_t af; uint32_t af;
int error; int error;
@ -366,6 +367,23 @@ ng_iface_output(struct ifnet *ifp, struct mbuf *m,
return (ENETDOWN); return (ENETDOWN);
} }
/* Protect from deadly infinite recursion. */
while ((mtag = m_tag_locate(m, MTAG_NGIF, MTAG_NGIF_CALLED, NULL))) {
if (*(struct ifnet **)(mtag + 1) == ifp) {
log(LOG_NOTICE, "Loop detected on %s\n", ifp->if_xname);
m_freem(m);
return (EDEADLK);
}
}
mtag = m_tag_alloc(MTAG_NGIF, MTAG_NGIF_CALLED, sizeof(struct ifnet *),
M_NOWAIT);
if (mtag == NULL) {
m_freem(m);
return (ENOMEM);
}
*(struct ifnet **)(mtag + 1) = ifp;
m_tag_prepend(m, mtag);
/* BPF writes need to be handled specially. */ /* BPF writes need to be handled specially. */
if (dst->sa_family == AF_UNSPEC) { if (dst->sa_family == AF_UNSPEC) {
bcopy(dst->sa_data, &af, sizeof(af)); bcopy(dst->sa_data, &af, sizeof(af));

View File

@ -72,4 +72,7 @@ enum {
NGM_IFACE_GET_IFINDEX, NGM_IFACE_GET_IFINDEX,
}; };
#define MTAG_NGIF NGM_IFACE_COOKIE
#define MTAG_NGIF_CALLED 0 | MTAG_PERSISTENT
#endif /* _NETGRAPH_NG_IFACE_H_ */ #endif /* _NETGRAPH_NG_IFACE_H_ */