From e6c929d473ea6fa69db37e6df56104ab2d4e4f24 Mon Sep 17 00:00:00 2001 From: "Eric W. Biederman" Date: Tue, 20 Jan 2009 11:02:28 +0000 Subject: [PATCH] --- yaml --- r: 133881 b: refs/heads/master c: 38231b7a8d1b74c920822640d1ce8eb8046377fb h: refs/heads/master i: 133879: 6e7624ac03e1278f96eca30b06807e0ea216722f v: v3 --- [refs] | 2 +- trunk/drivers/net/tun.c | 24 +++++++++++++++++------- 2 files changed, 18 insertions(+), 8 deletions(-) diff --git a/[refs] b/[refs] index 38a05ecb1c03..6631b68e7369 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 36b50bab53207daf34be63ca62fb8b0b08dc6e6b +refs/heads/master: 38231b7a8d1b74c920822640d1ce8eb8046377fb diff --git a/trunk/drivers/net/tun.c b/trunk/drivers/net/tun.c index dfbf58659771..fa93160bf522 100644 --- a/trunk/drivers/net/tun.c +++ b/trunk/drivers/net/tun.c @@ -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);