diff options
author | David S. Miller <davem@davemloft.net> | 2008-04-24 14:44:43 +0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2008-04-24 14:44:43 +0400 |
commit | 9edb74cc6ccb3a893c3d40727b7003c3c16f85a0 (patch) | |
tree | 8f45047eb778c13150809df837c1a1327a3f6c05 /drivers/net | |
parent | 5e659e4cb0eedacdc1f621a61e400a4611ddef8a (diff) | |
download | linux-9edb74cc6ccb3a893c3d40727b7003c3c16f85a0.tar.xz |
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 'drivers/net')
-rw-r--r-- | drivers/net/tun.c | 10 |
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; |