Skip to content

Commit

Permalink
[NET]: Fix crash in dev_mc_sync()/dev_mc_unsync()
Browse files Browse the repository at this point in the history
This patch fixes a crash that may occur when the routine dev_mc_sync()
deletes an address from the list it is currently going through. It
saves the pointer to the next element before deleting the current one.
The problem may also exist in dev_mc_unsync().

Signed-off-by: Benjamin Thery <benjamin.thery@bull.net>
Acked-by: Patrick McHardy <kaber@trash.net>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Benjamin Thery authored and David S. Miller committed Aug 27, 2007
1 parent f424bb9 commit aaa53c4
Showing 1 changed file with 10 additions and 4 deletions.
14 changes: 10 additions & 4 deletions net/core/dev_mcast.c
Original file line number Diff line number Diff line change
Expand Up @@ -116,11 +116,13 @@ int dev_mc_add(struct net_device *dev, void *addr, int alen, int glbl)
*/
int dev_mc_sync(struct net_device *to, struct net_device *from)
{
struct dev_addr_list *da;
struct dev_addr_list *da, *next;
int err = 0;

netif_tx_lock_bh(to);
for (da = from->mc_list; da != NULL; da = da->next) {
da = from->mc_list;
while (da != NULL) {
next = da->next;
if (!da->da_synced) {
err = __dev_addr_add(&to->mc_list, &to->mc_count,
da->da_addr, da->da_addrlen, 0);
Expand All @@ -134,6 +136,7 @@ int dev_mc_sync(struct net_device *to, struct net_device *from)
__dev_addr_delete(&from->mc_list, &from->mc_count,
da->da_addr, da->da_addrlen, 0);
}
da = next;
}
if (!err)
__dev_set_rx_mode(to);
Expand All @@ -156,19 +159,22 @@ EXPORT_SYMBOL(dev_mc_sync);
*/
void dev_mc_unsync(struct net_device *to, struct net_device *from)
{
struct dev_addr_list *da;
struct dev_addr_list *da, *next;

netif_tx_lock_bh(from);
netif_tx_lock_bh(to);

for (da = from->mc_list; da != NULL; da = 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);
da = next;
}
__dev_set_rx_mode(to);

Expand Down

0 comments on commit aaa53c4

Please sign in to comment.