* [PATCH] Fix infinite loop on dev_mc_unsync() @ 2007-11-09 15:11 Luis R. Rodriguez 2007-11-09 18:51 ` Luis R. Rodriguez 0 siblings, 1 reply; 8+ messages in thread From: Luis R. Rodriguez @ 2007-11-09 15:11 UTC (permalink / raw) To: netdev-u79uwXL29TY76Z2rM5mHXA Cc: linux-wireless-u79uwXL29TY76Z2rM5mHXA, Jeff Garzik While reviewing net/core/dev_mcast.c I found what I think is an infinite loop on dev_mc_unsync(). This fixes it. We make use of this guy on mac80211 in ieee80211_stop(). This is untested. Signed-off-by: Luis R. Rodriguez <mcgrof-NvJAj8134tRxEa0u/P/EHDe48wsgrGvP@public.gmane.org> diff --git a/net/core/dev_mcast.c b/net/core/dev_mcast.c index 15241cf..5373c03 100644 --- a/net/core/dev_mcast.c +++ b/net/core/dev_mcast.c @@ -168,8 +168,10 @@ void dev_mc_unsync(struct net_device *to, struct net_device *from) da = from->mc_list; while (da != NULL) { next = da->next; - if (!da->da_synced) + if (!da->da_synced) { + da = next; continue; + } __dev_addr_delete(&to->mc_list, &to->mc_count, da->da_addr, da->da_addrlen, 0); da->da_synced = 0; ^ permalink raw reply related [flat|nested] 8+ messages in thread
* Re: [PATCH] Fix infinite loop on dev_mc_unsync() 2007-11-09 15:11 [PATCH] Fix infinite loop on dev_mc_unsync() Luis R. Rodriguez @ 2007-11-09 18:51 ` Luis R. Rodriguez 2007-11-09 19:07 ` Joe Perches 0 siblings, 1 reply; 8+ messages in thread From: Luis R. Rodriguez @ 2007-11-09 18:51 UTC (permalink / raw) To: netdev-u79uwXL29TY76Z2rM5mHXA Cc: linux-wireless-u79uwXL29TY76Z2rM5mHXA, Jeff Garzik, David Miller Sorry, forgot to CC David. On Fri, Nov 09, 2007 at 10:11:35AM -0500, Luis R. Rodriguez wrote: While reviewing net/core/dev_mcast.c I found what I think is an infinite loop on dev_mc_unsync(). This fixes it. We make use of this guy on mac80211 in ieee80211_stop(). This is untested. Signed-off-by: Luis R. Rodriguez <mcgrof-NvJAj8134tRxEa0u/P/EHDe48wsgrGvP@public.gmane.org> diff --git a/net/core/dev_mcast.c b/net/core/dev_mcast.c index 15241cf..5373c03 100644 --- a/net/core/dev_mcast.c +++ b/net/core/dev_mcast.c @@ -168,8 +168,10 @@ void dev_mc_unsync(struct net_device *to, struct net_device *from) da = from->mc_list; while (da != NULL) { next = da->next; - if (!da->da_synced) + if (!da->da_synced) { + da = next; continue; + } __dev_addr_delete(&to->mc_list, &to->mc_count, da->da_addr, da->da_addrlen, 0); da->da_synced = 0; ^ permalink raw reply related [flat|nested] 8+ messages in thread
* Re: [PATCH] Fix infinite loop on dev_mc_unsync() 2007-11-09 18:51 ` Luis R. Rodriguez @ 2007-11-09 19:07 ` Joe Perches 2007-11-09 19:21 ` Luis R. Rodriguez 0 siblings, 1 reply; 8+ messages in thread From: Joe Perches @ 2007-11-09 19:07 UTC (permalink / raw) To: Luis R. Rodriguez Cc: netdev-u79uwXL29TY76Z2rM5mHXA, linux-wireless-u79uwXL29TY76Z2rM5mHXA, Jeff Garzik, David Miller On Fri, 2007-11-09 at 13:51 -0500, Luis R. Rodriguez wrote: > While reviewing net/core/dev_mcast.c I found what I think is an > infinite loop on dev_mc_unsync(). This fixes it. We make use of > this guy on mac80211 in ieee80211_stop(). This is untested. > > Signed-off-by: Luis R. Rodriguez <mcgrof-NvJAj8134tRxEa0u/P/EHDe48wsgrGvP@public.gmane.org> > > diff --git a/net/core/dev_mcast.c b/net/core/dev_mcast.c > index 15241cf..5373c03 100644 > --- a/net/core/dev_mcast.c > +++ b/net/core/dev_mcast.c > @@ -168,8 +168,10 @@ void dev_mc_unsync(struct net_device *to, struct net_device *from) > da = from->mc_list; > while (da != NULL) { > next = da->next; > - if (!da->da_synced) > + if (!da->da_synced) { > + da = next; > continue; > + } > __dev_addr_delete(&to->mc_list, &to->mc_count, > da->da_addr, da->da_addrlen, 0); > da->da_synced = 0; > - > To unsubscribe from this list: send the line "unsubscribe netdev" in > the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org > More majordomo info at http://vger.kernel.org/majordomo-info.html Perhaps this is clearer as: void dev_mc_unsync(struct net_device *to, struct net_device *from) { struct dev_addr_list *da; netif_tx_lock_bh(from); netif_tx_lock_bh(to); da = from->mc_list; while (da) { if (da->da_synced) { __dev_addr_delete(&to->mc_list, &to->mc_count, da->da_addr, da->da_addrlen, 0); __dev_addr_delete(&from->mc_list, &from->mc_count, da->da_addr, da->da_addrlen, 0); da->da_synced = 0; } da = da->next; } __dev_set_rx_mode(to); netif_tx_unlock_bh(to); netif_tx_unlock_bh(from); } EXPORT_SYMBOL(dev_mc_unsync); ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH] Fix infinite loop on dev_mc_unsync() 2007-11-09 19:07 ` Joe Perches @ 2007-11-09 19:21 ` Luis R. Rodriguez 2007-11-09 23:12 ` Patrick McHardy 0 siblings, 1 reply; 8+ messages in thread From: Luis R. Rodriguez @ 2007-11-09 19:21 UTC (permalink / raw) To: Joe Perches Cc: netdev-u79uwXL29TY76Z2rM5mHXA, linux-wireless-u79uwXL29TY76Z2rM5mHXA, Jeff Garzik, David Miller On Fri, Nov 09, 2007 at 11:07:16AM -0800, Joe Perches wrote: > On Fri, 2007-11-09 at 13:51 -0500, Luis R. Rodriguez wrote: > > While reviewing net/core/dev_mcast.c I found what I think is an > > infinite loop on dev_mc_unsync(). This fixes it. We make use of > > this guy on mac80211 in ieee80211_stop(). This is untested. > > > > Signed-off-by: Luis R. Rodriguez <mcgrof-NvJAj8134tRxEa0u/P/EHDe48wsgrGvP@public.gmane.org> > > > > diff --git a/net/core/dev_mcast.c b/net/core/dev_mcast.c > > index 15241cf..5373c03 100644 > > --- a/net/core/dev_mcast.c > > +++ b/net/core/dev_mcast.c > > @@ -168,8 +168,10 @@ void dev_mc_unsync(struct net_device *to, struct net_device *from) > > da = from->mc_list; > > while (da != NULL) { > > next = da->next; > > - if (!da->da_synced) > > + if (!da->da_synced) { > > + da = next; > > continue; > > + } > > __dev_addr_delete(&to->mc_list, &to->mc_count, > > da->da_addr, da->da_addrlen, 0); > > da->da_synced = 0; > > - > > To unsubscribe from this list: send the line "unsubscribe netdev" in > > the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org > > More majordomo info at http://vger.kernel.org/majordomo-info.html > > Perhaps this is clearer as: > > void dev_mc_unsync(struct net_device *to, struct net_device *from) > { > struct dev_addr_list *da; > > netif_tx_lock_bh(from); > netif_tx_lock_bh(to); > > da = from->mc_list; > while (da) { > if (da->da_synced) { > __dev_addr_delete(&to->mc_list, &to->mc_count, > da->da_addr, da->da_addrlen, 0); > __dev_addr_delete(&from->mc_list, &from->mc_count, > da->da_addr, da->da_addrlen, 0); > da->da_synced = 0; > } > da = da->next; > } > > __dev_set_rx_mode(to); > > netif_tx_unlock_bh(to); > netif_tx_unlock_bh(from); > } > EXPORT_SYMBOL(dev_mc_unsync); Sure, or better with a for loop and do away with next pointer then: void dev_mc_unsync(struct net_device *to, struct net_device *from) { struct dev_addr_list *da; netif_tx_lock_bh(from); netif_tx_lock_bh(to); for (da = from->mc_list; da; da = da->next) { if (!da->da_synced) continue; __dev_addr_delete(&to->mc_list, &to->mc_count, da->da_addr, da->da_addrlen, 0); da->da_synced = 0; __dev_addr_delete(&from->mc_list, &from->mc_count, da->da_addr, da->da_addrlen, 0); } __dev_set_rx_mode(to); netif_tx_unlock_bh(to); netif_tx_unlock_bh(from); } EXPORT_SYMBOL(dev_mc_unsync); Patch below. Signed-off-by: Luis R. Rodriguez <mcgrof-NvJAj8134tRxEa0u/P/EHDe48wsgrGvP@public.gmane.org> diff --git a/net/core/dev_mcast.c b/net/core/dev_mcast.c index 15241cf..2aea8e1 100644 --- a/net/core/dev_mcast.c +++ b/net/core/dev_mcast.c @@ -160,14 +160,12 @@ EXPORT_SYMBOL(dev_mc_sync); */ void dev_mc_unsync(struct net_device *to, struct net_device *from) { - struct dev_addr_list *da, *next; + struct dev_addr_list *da; netif_tx_lock_bh(from); netif_tx_lock_bh(to); - da = from->mc_list; - while (da != NULL) { - next = da->next; + for (da = from->mc_list; da; da = da->next) { if (!da->da_synced) continue; __dev_addr_delete(&to->mc_list, &to->mc_count, @@ -175,7 +173,6 @@ void dev_mc_unsync(struct net_device *to, struct net_device *from) da->da_synced = 0; __dev_addr_delete(&from->mc_list, &from->mc_count, da->da_addr, da->da_addrlen, 0); - da = next; } __dev_set_rx_mode(to); ^ permalink raw reply related [flat|nested] 8+ messages in thread
* Re: [PATCH] Fix infinite loop on dev_mc_unsync() 2007-11-09 19:21 ` Luis R. Rodriguez @ 2007-11-09 23:12 ` Patrick McHardy [not found] ` <4734E962.3010603-dcUjhNyLwpNeoWH0uzbU5w@public.gmane.org> 0 siblings, 1 reply; 8+ messages in thread From: Patrick McHardy @ 2007-11-09 23:12 UTC (permalink / raw) To: Luis R. Rodriguez Cc: Joe Perches, netdev, linux-wireless, Jeff Garzik, David Miller Luis R. Rodriguez wrote: > diff --git a/net/core/dev_mcast.c b/net/core/dev_mcast.c > index 15241cf..2aea8e1 100644 > --- a/net/core/dev_mcast.c > +++ b/net/core/dev_mcast.c > @@ -160,14 +160,12 @@ EXPORT_SYMBOL(dev_mc_sync); > */ > void dev_mc_unsync(struct net_device *to, struct net_device *from) > { > - struct dev_addr_list *da, *next; > + struct dev_addr_list *da; > > netif_tx_lock_bh(from); > netif_tx_lock_bh(to); > > - da = from->mc_list; > - while (da != NULL) { > - next = da->next; > + for (da = from->mc_list; da; da = da->next) { > This may cause a use-after-free since __dev_addr_delete frees the address when all references are gone. > if (!da->da_synced) > continue; > __dev_addr_delete(&to->mc_list, &to->mc_count, > @@ -175,7 +173,6 @@ void dev_mc_unsync(struct net_device *to, struct net_device *from) > da->da_synced = 0; > __dev_addr_delete(&from->mc_list, &from->mc_count, > da->da_addr, da->da_addrlen, 0); > - da = next; > } > ^ permalink raw reply [flat|nested] 8+ messages in thread
[parent not found: <4734E962.3010603-dcUjhNyLwpNeoWH0uzbU5w@public.gmane.org>]
* Re: [PATCH] Fix infinite loop on dev_mc_unsync() [not found] ` <4734E962.3010603-dcUjhNyLwpNeoWH0uzbU5w@public.gmane.org> @ 2007-11-10 0:08 ` Joe Perches 2007-11-10 0:13 ` Patrick McHardy 0 siblings, 1 reply; 8+ messages in thread From: Joe Perches @ 2007-11-10 0:08 UTC (permalink / raw) To: Patrick McHardy Cc: Luis R. Rodriguez, netdev-u79uwXL29TY76Z2rM5mHXA, linux-wireless-u79uwXL29TY76Z2rM5mHXA, Jeff Garzik, David Miller On Sat, 2007-11-10 at 00:12 +0100, Patrick McHardy wrote: > This may cause a use-after-free since __dev_addr_delete frees the address > when all references are gone. How about a comment then? Perhaps: diff --git a/net/core/dev_mcast.c b/net/core/dev_mcast.c index ae35405..63576aa 100644 --- a/net/core/dev_mcast.c +++ b/net/core/dev_mcast.c @@ -165,16 +165,23 @@ void dev_mc_unsync(struct net_device *to, struct net_device *from) netif_tx_lock_bh(from); netif_tx_lock_bh(to); + /* + This while loop can't be written as + for (da = from->mc_list; da; da = da->next) + da = from->mc_list and __dev_addr_delete can kfree(from->mc_list) + which could cause a use-after-free of da->next + */ + da = from->mc_list; while (da != NULL) { next = da->next; - if (!da->da_synced) - continue; - __dev_addr_delete(&to->mc_list, &to->mc_count, - da->da_addr, da->da_addrlen, 0); - da->da_synced = 0; - __dev_addr_delete(&from->mc_list, &from->mc_count, - da->da_addr, da->da_addrlen, 0); + if (da->da_synced) { + __dev_addr_delete(&to->mc_list, &to->mc_count, + da->da_addr, da->da_addrlen, 0); + da->da_synced = 0; + __dev_addr_delete(&from->mc_list, &from->mc_count, + da->da_addr, da->da_addrlen, 0); + } da = next; } __dev_set_rx_mode(to); ^ permalink raw reply related [flat|nested] 8+ messages in thread
* Re: [PATCH] Fix infinite loop on dev_mc_unsync() 2007-11-10 0:08 ` Joe Perches @ 2007-11-10 0:13 ` Patrick McHardy [not found] ` <4734F7B6.7060505-dcUjhNyLwpNeoWH0uzbU5w@public.gmane.org> 0 siblings, 1 reply; 8+ messages in thread From: Patrick McHardy @ 2007-11-10 0:13 UTC (permalink / raw) To: Joe Perches Cc: Luis R. Rodriguez, netdev-u79uwXL29TY76Z2rM5mHXA, linux-wireless-u79uwXL29TY76Z2rM5mHXA, Jeff Garzik, David Miller Joe Perches wrote: > On Sat, 2007-11-10 at 00:12 +0100, Patrick McHardy wrote: > >> This may cause a use-after-free since __dev_addr_delete frees the address >> when all references are gone. >> > > How about a comment then? Perhaps: > > diff --git a/net/core/dev_mcast.c b/net/core/dev_mcast.c > index ae35405..63576aa 100644 > --- a/net/core/dev_mcast.c > +++ b/net/core/dev_mcast.c > @@ -165,16 +165,23 @@ void dev_mc_unsync(struct net_device *to, struct net_device *from) > netif_tx_lock_bh(from); > netif_tx_lock_bh(to); > > + /* > + This while loop can't be written as > + for (da = from->mc_list; da; da = da->next) > + da = from->mc_list and __dev_addr_delete can kfree(from->mc_list) > + which could cause a use-after-free of da->next > + */ > Seems unnecessary to me, we also don't comment each list_for_each_entry_safe iteration. I consider the use of a seperate next variable self-explanatory. ^ permalink raw reply [flat|nested] 8+ messages in thread
[parent not found: <4734F7B6.7060505-dcUjhNyLwpNeoWH0uzbU5w@public.gmane.org>]
* Re: [PATCH] Fix infinite loop on dev_mc_unsync() [not found] ` <4734F7B6.7060505-dcUjhNyLwpNeoWH0uzbU5w@public.gmane.org> @ 2007-11-11 5:34 ` David Miller 0 siblings, 0 replies; 8+ messages in thread From: David Miller @ 2007-11-11 5:34 UTC (permalink / raw) To: kaber-dcUjhNyLwpNeoWH0uzbU5w Cc: joe-6d6DIl74uiNBDgjK7y7TUQ, mcgrof-Re5JQEeQqe8AvxtiuMwx3w, netdev-u79uwXL29TY76Z2rM5mHXA, linux-wireless-u79uwXL29TY76Z2rM5mHXA, jeff-o2qLIJkoznsdnm+yROfE0A From: Patrick McHardy <kaber-dcUjhNyLwpNeoWH0uzbU5w@public.gmane.org> Date: Sat, 10 Nov 2007 01:13:42 +0100 > Joe Perches wrote: > > On Sat, 2007-11-10 at 00:12 +0100, Patrick McHardy wrote: > > > >> This may cause a use-after-free since __dev_addr_delete frees the address > >> when all references are gone. > >> > > > > How about a comment then? Perhaps: > > > > diff --git a/net/core/dev_mcast.c b/net/core/dev_mcast.c > > index ae35405..63576aa 100644 > > --- a/net/core/dev_mcast.c > > +++ b/net/core/dev_mcast.c > > @@ -165,16 +165,23 @@ void dev_mc_unsync(struct net_device *to, struct net_device *from) > > netif_tx_lock_bh(from); > > netif_tx_lock_bh(to); > > > > + /* > > + This while loop can't be written as > > + for (da = from->mc_list; da; da = da->next) > > + da = from->mc_list and __dev_addr_delete can kfree(from->mc_list) > > + which could cause a use-after-free of da->next > > + */ > > > > Seems unnecessary to me, we also don't comment each list_for_each_entry_safe > iteration. I consider the use of a seperate next variable self-explanatory. Agreed, this comment is pointless. I'll apply Joe's patch without the comment. ^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2007-11-11 5:34 UTC | newest]
Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2007-11-09 15:11 [PATCH] Fix infinite loop on dev_mc_unsync() Luis R. Rodriguez
2007-11-09 18:51 ` Luis R. Rodriguez
2007-11-09 19:07 ` Joe Perches
2007-11-09 19:21 ` Luis R. Rodriguez
2007-11-09 23:12 ` Patrick McHardy
[not found] ` <4734E962.3010603-dcUjhNyLwpNeoWH0uzbU5w@public.gmane.org>
2007-11-10 0:08 ` Joe Perches
2007-11-10 0:13 ` Patrick McHardy
[not found] ` <4734F7B6.7060505-dcUjhNyLwpNeoWH0uzbU5w@public.gmane.org>
2007-11-11 5:34 ` David Miller
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).