Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 14d9ead0 authored by Jeff Dike's avatar Jeff Dike Committed by Linus Torvalds
Browse files

[PATCH] uml: balance list_add and list_del in the network driver



The network driver added an interface to the "opened" list when it was
configured, not when it was brought up, and removed it when it was taken down.
 A sequence of ifconfig up, ifconfig down, ...  caused it to be removed
multiple times from the list without being added in between, resulting in a
crash.  This patch moves the add to when the interface is brought up.

Signed-off-by: default avatarJeff Dike <jdike@addtoit.com>
Cc: Paolo 'Blaisorblade' Giarrusso <blaisorblade@yahoo.it>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent 1d2ddcfb
Loading
Loading
Loading
Loading
+19 −10
Original line number Original line Diff line number Diff line
@@ -131,9 +131,8 @@ static int uml_net_open(struct net_device *dev)
			     SA_INTERRUPT | SA_SHIRQ, dev->name, dev);
			     SA_INTERRUPT | SA_SHIRQ, dev->name, dev);
	if(err != 0){
	if(err != 0){
		printk(KERN_ERR "uml_net_open: failed to get irq(%d)\n", err);
		printk(KERN_ERR "uml_net_open: failed to get irq(%d)\n", err);
		if(lp->close != NULL) (*lp->close)(lp->fd, &lp->user);
		lp->fd = -1;
		err = -ENETUNREACH;
		err = -ENETUNREACH;
		goto out_close;
	}
	}


	lp->tl.data = (unsigned long) &lp->user;
	lp->tl.data = (unsigned long) &lp->user;
@@ -145,9 +144,19 @@ static int uml_net_open(struct net_device *dev)
	 */
	 */
	while((err = uml_net_rx(dev)) > 0) ;
	while((err = uml_net_rx(dev)) > 0) ;


	spin_unlock(&lp->lock);

	spin_lock(&opened_lock);
	list_add(&lp->list, &opened);
	spin_unlock(&opened_lock);

	return 0;
out_close:
	if(lp->close != NULL) (*lp->close)(lp->fd, &lp->user);
	lp->fd = -1;
out:
out:
	spin_unlock(&lp->lock);
	spin_unlock(&lp->lock);
	return(err);
	return err;
}
}


static int uml_net_close(struct net_device *dev)
static int uml_net_close(struct net_device *dev)
@@ -161,9 +170,13 @@ static int uml_net_close(struct net_device *dev)
	if(lp->close != NULL)
	if(lp->close != NULL)
		(*lp->close)(lp->fd, &lp->user);
		(*lp->close)(lp->fd, &lp->user);
	lp->fd = -1;
	lp->fd = -1;
	list_del(&lp->list);


	spin_unlock(&lp->lock);
	spin_unlock(&lp->lock);

	spin_lock(&opened_lock);
	list_del(&lp->list);
	spin_unlock(&opened_lock);

	return 0;
	return 0;
}
}


@@ -410,11 +423,7 @@ static int eth_configure(int n, void *init, char *mac,
	if (device->have_mac)
	if (device->have_mac)
		set_ether_mac(dev, device->mac);
		set_ether_mac(dev, device->mac);


	spin_lock(&opened_lock);
	return 0;
	list_add(&lp->list, &opened);
	spin_unlock(&opened_lock);

	return(0);
}
}


static struct uml_net *find_device(int n)
static struct uml_net *find_device(int n)