tun: Make tun_net_xmit atomic wrt tun_attach && tun_detach
Currently this small race allows for a packet to be received when we detach from an tun device and still be enqueued. Not especially important but not what the code is trying to do. Signed-off-by: Eric W. Biederman <ebiederm@aristanetworks.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
36b50bab53
commit
38231b7a8d
|
@ -115,25 +115,33 @@ static int tun_attach(struct tun_struct *tun, struct file *file)
|
|||
{
|
||||
struct tun_file *tfile = file->private_data;
|
||||
const struct cred *cred = current_cred();
|
||||
int err;
|
||||
|
||||
ASSERT_RTNL();
|
||||
|
||||
if (tfile->tun)
|
||||
return -EINVAL;
|
||||
|
||||
if (tun->tfile)
|
||||
return -EBUSY;
|
||||
|
||||
/* Check permissions */
|
||||
if (((tun->owner != -1 && cred->euid != tun->owner) ||
|
||||
(tun->group != -1 && cred->egid != tun->group)) &&
|
||||
!capable(CAP_NET_ADMIN))
|
||||
return -EPERM;
|
||||
|
||||
netif_tx_lock_bh(tun->dev);
|
||||
|
||||
err = -EINVAL;
|
||||
if (tfile->tun)
|
||||
goto out;
|
||||
|
||||
err = -EBUSY;
|
||||
if (tun->tfile)
|
||||
goto out;
|
||||
|
||||
err = 0;
|
||||
tfile->tun = tun;
|
||||
tun->tfile = tfile;
|
||||
|
||||
return 0;
|
||||
out:
|
||||
netif_tx_unlock_bh(tun->dev);
|
||||
return err;
|
||||
}
|
||||
|
||||
static void __tun_detach(struct tun_struct *tun)
|
||||
|
@ -141,8 +149,10 @@ static void __tun_detach(struct tun_struct *tun)
|
|||
struct tun_file *tfile = tun->tfile;
|
||||
|
||||
/* Detach from net device */
|
||||
netif_tx_lock_bh(tun->dev);
|
||||
tfile->tun = NULL;
|
||||
tun->tfile = NULL;
|
||||
netif_tx_unlock_bh(tun->dev);
|
||||
|
||||
/* Drop read queue */
|
||||
skb_queue_purge(&tun->readq);
|
||||
|
|
Loading…
Reference in New Issue