diff options
author | kmacy <kmacy@FreeBSD.org> | 2012-02-23 18:21:37 +0000 |
---|---|---|
committer | kmacy <kmacy@FreeBSD.org> | 2012-02-23 18:21:37 +0000 |
commit | a99e9d281db6624cf9b88f07759a77f7b2d96a33 (patch) | |
tree | 3a2da57fb6f6af971e7fb849770dc0f9b231bca2 /sys/netinet6 | |
parent | ffbbf1cb2c6c124090347c8c43c4eefb65ae1bd5 (diff) | |
download | FreeBSD-src-a99e9d281db6624cf9b88f07759a77f7b2d96a33.zip FreeBSD-src-a99e9d281db6624cf9b88f07759a77f7b2d96a33.tar.gz |
When using flowtable llentrys can outlive the interface with which they're associated
at which the lle_tbl pointer points to freed memory and the llt_free pointer is no longer
valid.
Move the free pointer in to the llentry itself and update the initalization sites.
MFC after: 2 weeks
Diffstat (limited to 'sys/netinet6')
-rw-r--r-- | sys/netinet6/in6.c | 30 |
1 files changed, 15 insertions, 15 deletions
diff --git a/sys/netinet6/in6.c b/sys/netinet6/in6.c index 0b22a1c..ca491b8 100644 --- a/sys/netinet6/in6.c +++ b/sys/netinet6/in6.c @@ -2439,6 +2439,20 @@ struct in6_llentry { struct sockaddr_in6 l3_addr6; }; +/* + * Deletes an address from the address table. + * This function is called by the timer functions + * such as arptimer() and nd6_llinfo_timer(), and + * the caller does the locking. + */ +static void +in6_lltable_free(struct lltable *llt, struct llentry *lle) +{ + LLE_WUNLOCK(lle); + LLE_LOCK_DESTROY(lle); + free(lle, M_LLTABLE); +} + static struct llentry * in6_lltable_new(const struct sockaddr *l3addr, u_int flags) { @@ -2451,6 +2465,7 @@ in6_lltable_new(const struct sockaddr *l3addr, u_int flags) lle->l3_addr6 = *(const struct sockaddr_in6 *)l3addr; lle->base.lle_refcnt = 1; + lle->base.lle_free = in6_lltable_free; LLE_LOCK_INIT(&lle->base); callout_init_rw(&lle->base.ln_timer_ch, &lle->base.lle_lock, CALLOUT_RETURNUNLOCKED); @@ -2458,20 +2473,6 @@ in6_lltable_new(const struct sockaddr *l3addr, u_int flags) return &lle->base; } -/* - * Deletes an address from the address table. - * This function is called by the timer functions - * such as arptimer() and nd6_llinfo_timer(), and - * the caller does the locking. - */ -static void -in6_lltable_free(struct lltable *llt, struct llentry *lle) -{ - LLE_WUNLOCK(lle); - LLE_LOCK_DESTROY(lle); - free(lle, M_LLTABLE); -} - static void in6_lltable_prefix_free(struct lltable *llt, const struct sockaddr *prefix, @@ -2713,7 +2714,6 @@ in6_domifattach(struct ifnet *ifp) ext->scope6_id = scope6_ifattach(ifp); ext->lltable = lltable_init(ifp, AF_INET6); if (ext->lltable != NULL) { - ext->lltable->llt_free = in6_lltable_free; ext->lltable->llt_prefix_free = in6_lltable_prefix_free; ext->lltable->llt_lookup = in6_lltable_lookup; ext->lltable->llt_dump = in6_lltable_dump; |