From f46106f1f378bf3c931756ea447169cbea7ded17 Mon Sep 17 00:00:00 2001 From: bluhm Date: Tue, 9 Apr 2024 11:05:05 +0000 Subject: [PATCH] Plug route leak in IP output. If no struct route is passed to ip_output() or ip6_output(), it uses its own iproute on the stack. In that case any route entry in the local route cache has to be freed. After pf decides to reroute, struct route is reset to NULL. Then the route reference counter has to be released. Call rtfree() without needless NULL check. OK mvs@ --- sys/netinet/ip_output.c | 6 ++++-- sys/netinet6/ip6_output.c | 9 +++++---- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/sys/netinet/ip_output.c b/sys/netinet/ip_output.c index 0a606960376..3154be3494c 100644 --- a/sys/netinet/ip_output.c +++ b/sys/netinet/ip_output.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ip_output.c,v 1.396 2024/02/22 14:25:58 bluhm Exp $ */ +/* $OpenBSD: ip_output.c,v 1.397 2024/04/09 11:05:05 bluhm Exp $ */ /* $NetBSD: ip_output.c,v 1.28 1996/02/13 23:43:07 christos Exp $ */ /* @@ -417,6 +417,8 @@ sendit: else if (m->m_pkthdr.pf.flags & PF_TAG_REROUTE) { /* tag as generated to skip over pf_test on rerun */ m->m_pkthdr.pf.flags |= PF_TAG_GENERATED; + if (ro == &iproute) + rtfree(ro->ro_rt); ro = NULL; if_put(ifp); /* drop reference since target changed */ ifp = NULL; @@ -481,7 +483,7 @@ sendit: ipstat_inc(ips_fragmented); done: - if (ro == &iproute && ro->ro_rt) + if (ro == &iproute) rtfree(ro->ro_rt); if_put(ifp); #ifdef IPSEC diff --git a/sys/netinet6/ip6_output.c b/sys/netinet6/ip6_output.c index 94519429cf0..a2ba550fa5a 100644 --- a/sys/netinet6/ip6_output.c +++ b/sys/netinet6/ip6_output.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ip6_output.c,v 1.288 2024/02/28 10:57:20 bluhm Exp $ */ +/* $OpenBSD: ip6_output.c,v 1.289 2024/04/09 11:05:05 bluhm Exp $ */ /* $KAME: ip6_output.c,v 1.172 2001/03/25 09:55:56 itojun Exp $ */ /* @@ -635,6 +635,8 @@ reroute: /* tag as generated to skip over pf_test on rerun */ m->m_pkthdr.pf.flags |= PF_TAG_GENERATED; finaldst = ip6->ip6_dst; + if (ro == &iproute) + rtfree(ro->ro_rt); ro = NULL; if_put(ifp); /* drop reference since destination changed */ ifp = NULL; @@ -758,11 +760,10 @@ reroute: bad: m_freem(m); done: - if (ro == &iproute && ro->ro_rt) { + if (ro == &iproute) rtfree(ro->ro_rt); - } else if (ro_pmtu == &iproute && ro_pmtu->ro_rt) { + else if (ro_pmtu == &iproute) rtfree(ro_pmtu->ro_rt); - } if_put(ifp); #ifdef IPSEC tdb_unref(tdb); -- 2.20.1