summaryrefslogtreecommitdiffstats
path: root/sys/netinet6
diff options
context:
space:
mode:
authoremax <emax@FreeBSD.org>2012-06-03 07:36:59 +0000
committeremax <emax@FreeBSD.org>2012-06-03 07:36:59 +0000
commit0985bae1a69e048d46a55a0df544685bd4dd0e7e (patch)
tree62766bdd20ec65bd20b8b997478c0f46f7966afe /sys/netinet6
parent1a57e2d650f9091a0630b89dcbbb1d8920106f98 (diff)
downloadFreeBSD-src-0985bae1a69e048d46a55a0df544685bd4dd0e7e.zip
FreeBSD-src-0985bae1a69e048d46a55a0df544685bd4dd0e7e.tar.gz
Plug reference leak.
Interface routes are refcounted as packets move through the stack, and there's garbage collection tied to it so that route changes can safely propagate while traffic is flowing. In our setup, we weren't changing or deleting any routes, but the refcounting logic in ip6_input() was wrong and caused a reference leak on every inbound V6 packet. This eventually caused a 32bit overflow, and the resulting 0 value caused the garbage collection to run on the active route. That then snowballed into the panic. Reviewed by: scottl MFC after: 3 days
Diffstat (limited to 'sys/netinet6')
-rw-r--r--sys/netinet6/ip6_input.c24
1 files changed, 14 insertions, 10 deletions
diff --git a/sys/netinet6/ip6_input.c b/sys/netinet6/ip6_input.c
index 0451888..e984534 100644
--- a/sys/netinet6/ip6_input.c
+++ b/sys/netinet6/ip6_input.c
@@ -879,19 +879,23 @@ passin:
* as our interface address (e.g. multicast addresses, addresses
* within FAITH prefixes and such).
*/
- if (deliverifp && !ip6_getdstifaddr(m)) {
+ if (deliverifp) {
struct in6_ifaddr *ia6;
- ia6 = in6_ifawithifp(deliverifp, &ip6->ip6_dst);
- if (ia6) {
- if (!ip6_setdstifaddr(m, ia6)) {
- /*
- * XXX maybe we should drop the packet here,
- * as we could not provide enough information
- * to the upper layers.
- */
- }
+ if ((ia6 = ip6_getdstifaddr(m)) != NULL) {
ifa_free(&ia6->ia_ifa);
+ } else {
+ ia6 = in6_ifawithifp(deliverifp, &ip6->ip6_dst);
+ if (ia6) {
+ if (!ip6_setdstifaddr(m, ia6)) {
+ /*
+ * XXX maybe we should drop the packet here,
+ * as we could not provide enough information
+ * to the upper layers.
+ */
+ }
+ ifa_free(&ia6->ia_ifa);
+ }
}
}
OpenPOWER on IntegriCloud