summaryrefslogtreecommitdiffstats
path: root/drivers/net/tun.c
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2008-04-24 12:44:43 +0200
committerDavid S. Miller <davem@davemloft.net>2008-04-24 12:44:43 +0200
commit9edb74cc6ccb3a893c3d40727b7003c3c16f85a0 (patch)
tree8f45047eb778c13150809df837c1a1327a3f6c05 /drivers/net/tun.c
parent[NET]: Fix heavy stack usage in seq_file output routines. (diff)
downloadlinux-9edb74cc6ccb3a893c3d40727b7003c3c16f85a0.tar.xz
linux-9edb74cc6ccb3a893c3d40727b7003c3c16f85a0.zip
tun: Multicast handling in tun_chr_ioctl() needs proper locking.
Since these operations don't go through the normal device calls, we have to ensure we synchronize with those paths. Noticed by Alan Cox. Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to '')
-rw-r--r--drivers/net/tun.c10
1 files changed, 10 insertions, 0 deletions
diff --git a/drivers/net/tun.c b/drivers/net/tun.c
index d8b1ba15aa6f..0ce07a339c7e 100644
--- a/drivers/net/tun.c
+++ b/drivers/net/tun.c
@@ -741,7 +741,12 @@ static int tun_chr_ioctl(struct inode *inode, struct file *file,
case SIOCADDMULTI:
/** Add the specified group to the character device's multicast filter
* list. */
+ rtnl_lock();
+ netif_tx_lock_bh(tun->dev);
add_multi(tun->chr_filter, ifr.ifr_hwaddr.sa_data);
+ netif_tx_unlock_bh(tun->dev);
+ rtnl_unlock();
+
DBG(KERN_DEBUG "%s: add multi: %s\n",
tun->dev->name, print_mac(mac, ifr.ifr_hwaddr.sa_data));
return 0;
@@ -749,7 +754,12 @@ static int tun_chr_ioctl(struct inode *inode, struct file *file,
case SIOCDELMULTI:
/** Remove the specified group from the character device's multicast
* filter list. */
+ rtnl_lock();
+ netif_tx_lock_bh(tun->dev);
del_multi(tun->chr_filter, ifr.ifr_hwaddr.sa_data);
+ netif_tx_unlock_bh(tun->dev);
+ rtnl_unlock();
+
DBG(KERN_DEBUG "%s: del multi: %s\n",
tun->dev->name, print_mac(mac, ifr.ifr_hwaddr.sa_data));
return 0;