* [PATCH V2 0/3] some fixes of tuntap
@ 2013-01-12 2:59 Jason Wang
2013-01-12 2:59 ` [PATCH V2 1/3] tuntap: switch to use rtnl_dereference() Jason Wang
` (3 more replies)
0 siblings, 4 replies; 5+ messages in thread
From: Jason Wang @ 2013-01-12 2:59 UTC (permalink / raw)
To: davem, mst, netdev, linux-kernel; +Cc: edumazet, stefanha, Jason Wang
Hi all:
There series fixes two issues:
- Don't allow calling TUNSETIFF when a file is detached which may cause kernel
data structure corrupt.
- Fix the reference count leaking of sock and module.
Plus a suggestion from Eric to use rtnl_dereference() instead of the open code.
Changes from v1:
- don't use rcu to dereference tfile->detached as it was already protected by
rtnl lock.
- add a patch of switching to use rtnl_dereference().
Jason Wang (3):
tuntap: switch to use rtnl_dereference()
tuntap: forbid calling TUNSETIFF when detached
tuntap: fix leaking reference count
drivers/net/tun.c | 44 ++++++++++++++++++++++----------------------
1 files changed, 22 insertions(+), 22 deletions(-)
^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH V2 1/3] tuntap: switch to use rtnl_dereference()
2013-01-12 2:59 [PATCH V2 0/3] some fixes of tuntap Jason Wang
@ 2013-01-12 2:59 ` Jason Wang
2013-01-12 2:59 ` [PATCH V2 2/3] tuntap: forbid calling TUNSETIFF when detached Jason Wang
` (2 subsequent siblings)
3 siblings, 0 replies; 5+ messages in thread
From: Jason Wang @ 2013-01-12 2:59 UTC (permalink / raw)
To: davem, mst, netdev, linux-kernel; +Cc: edumazet, stefanha, Jason Wang
Switch to use rtnl_dereference() instead of the open code, suggested by Eric.
Cc: Eric Dumazet <edumazet@google.com>
Signed-off-by: Jason Wang <jasowang@redhat.com>
---
drivers/net/tun.c | 27 ++++++++++-----------------
1 files changed, 10 insertions(+), 17 deletions(-)
diff --git a/drivers/net/tun.c b/drivers/net/tun.c
index 99b58d8..aa963c4 100644
--- a/drivers/net/tun.c
+++ b/drivers/net/tun.c
@@ -404,8 +404,8 @@ static void __tun_detach(struct tun_file *tfile, bool clean)
struct tun_struct *tun;
struct net_device *dev;
- tun = rcu_dereference_protected(tfile->tun,
- lockdep_rtnl_is_held());
+ tun = rtnl_dereference(tfile->tun);
+
if (tun) {
u16 index = tfile->queue_index;
BUG_ON(index >= tun->numqueues);
@@ -414,8 +414,7 @@ static void __tun_detach(struct tun_file *tfile, bool clean)
rcu_assign_pointer(tun->tfiles[index],
tun->tfiles[tun->numqueues - 1]);
rcu_assign_pointer(tfile->tun, NULL);
- ntfile = rcu_dereference_protected(tun->tfiles[index],
- lockdep_rtnl_is_held());
+ ntfile = rtnl_dereference(tun->tfiles[index]);
ntfile->queue_index = index;
--tun->numqueues;
@@ -458,8 +457,7 @@ static void tun_detach_all(struct net_device *dev)
int i, n = tun->numqueues;
for (i = 0; i < n; i++) {
- tfile = rcu_dereference_protected(tun->tfiles[i],
- lockdep_rtnl_is_held());
+ tfile = rtnl_dereference(tun->tfiles[i]);
BUG_ON(!tfile);
wake_up_all(&tfile->wq.wait);
rcu_assign_pointer(tfile->tun, NULL);
@@ -469,8 +467,7 @@ static void tun_detach_all(struct net_device *dev)
synchronize_net();
for (i = 0; i < n; i++) {
- tfile = rcu_dereference_protected(tun->tfiles[i],
- lockdep_rtnl_is_held());
+ tfile = rtnl_dereference(tun->tfiles[i]);
/* Drop read queue */
skb_queue_purge(&tfile->sk.sk_receive_queue);
sock_put(&tfile->sk);
@@ -489,7 +486,7 @@ static int tun_attach(struct tun_struct *tun, struct file *file)
int err;
err = -EINVAL;
- if (rcu_dereference_protected(tfile->tun, lockdep_rtnl_is_held()))
+ if (rtnl_dereference(tfile->tun))
goto out;
if (tfile->detached && tun != tfile->detached)
goto out;
@@ -1740,8 +1737,7 @@ static void tun_detach_filter(struct tun_struct *tun, int n)
struct tun_file *tfile;
for (i = 0; i < n; i++) {
- tfile = rcu_dereference_protected(tun->tfiles[i],
- lockdep_rtnl_is_held());
+ tfile = rtnl_dereference(tun->tfiles[i]);
sk_detach_filter(tfile->socket.sk);
}
@@ -1754,8 +1750,7 @@ static int tun_attach_filter(struct tun_struct *tun)
struct tun_file *tfile;
for (i = 0; i < tun->numqueues; i++) {
- tfile = rcu_dereference_protected(tun->tfiles[i],
- lockdep_rtnl_is_held());
+ tfile = rtnl_dereference(tun->tfiles[i]);
ret = sk_attach_filter(&tun->fprog, tfile->socket.sk);
if (ret) {
tun_detach_filter(tun, i);
@@ -1773,8 +1768,7 @@ static void tun_set_sndbuf(struct tun_struct *tun)
int i;
for (i = 0; i < tun->numqueues; i++) {
- tfile = rcu_dereference_protected(tun->tfiles[i],
- lockdep_rtnl_is_held());
+ tfile = rtnl_dereference(tun->tfiles[i]);
tfile->socket.sk->sk_sndbuf = tun->sndbuf;
}
}
@@ -1794,8 +1788,7 @@ static int tun_set_queue(struct file *file, struct ifreq *ifr)
else
ret = tun_attach(tun, file);
} else if (ifr->ifr_flags & IFF_DETACH_QUEUE) {
- tun = rcu_dereference_protected(tfile->tun,
- lockdep_rtnl_is_held());
+ tun = rtnl_dereference(tfile->tun);
if (!tun || !(tun->flags & TUN_TAP_MQ))
ret = -EINVAL;
else
--
1.7.1
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [PATCH V2 2/3] tuntap: forbid calling TUNSETIFF when detached
2013-01-12 2:59 [PATCH V2 0/3] some fixes of tuntap Jason Wang
2013-01-12 2:59 ` [PATCH V2 1/3] tuntap: switch to use rtnl_dereference() Jason Wang
@ 2013-01-12 2:59 ` Jason Wang
2013-01-12 2:59 ` [PATCH V2 3/3] tuntap: fix leaking reference count Jason Wang
2013-01-12 3:42 ` [PATCH V2 0/3] some fixes of tuntap David Miller
3 siblings, 0 replies; 5+ messages in thread
From: Jason Wang @ 2013-01-12 2:59 UTC (permalink / raw)
To: davem, mst, netdev, linux-kernel; +Cc: edumazet, stefanha, Jason Wang
Michael points out that even after Stefan's fix the TUNSETIFF is still allowed
to create a new tap device. This because we only check tfile->tun but the
tfile->detached were introduced. Fix this by failing early in tun_set_iff() if
the file is detached. After this fix, there's no need to do the check again in
tun_set_iff(), so this patch removes it.
Cc: Michael S. Tsirkin <mst@redhat.com>
Cc: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Jason Wang <jasowang@redhat.com>
---
drivers/net/tun.c | 5 +++--
1 files changed, 3 insertions(+), 2 deletions(-)
diff --git a/drivers/net/tun.c b/drivers/net/tun.c
index aa963c4..a36b56f 100644
--- a/drivers/net/tun.c
+++ b/drivers/net/tun.c
@@ -488,8 +488,6 @@ static int tun_attach(struct tun_struct *tun, struct file *file)
err = -EINVAL;
if (rtnl_dereference(tfile->tun))
goto out;
- if (tfile->detached && tun != tfile->detached)
- goto out;
err = -EBUSY;
if (!(tun->flags & TUN_TAP_MQ) && tun->numqueues == 1)
@@ -1543,6 +1541,9 @@ static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr)
struct net_device *dev;
int err;
+ if (tfile->detached)
+ return -EINVAL;
+
dev = __dev_get_by_name(net, ifr->ifr_name);
if (dev) {
if (ifr->ifr_flags & IFF_TUN_EXCL)
--
1.7.1
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [PATCH V2 3/3] tuntap: fix leaking reference count
2013-01-12 2:59 [PATCH V2 0/3] some fixes of tuntap Jason Wang
2013-01-12 2:59 ` [PATCH V2 1/3] tuntap: switch to use rtnl_dereference() Jason Wang
2013-01-12 2:59 ` [PATCH V2 2/3] tuntap: forbid calling TUNSETIFF when detached Jason Wang
@ 2013-01-12 2:59 ` Jason Wang
2013-01-12 3:42 ` [PATCH V2 0/3] some fixes of tuntap David Miller
3 siblings, 0 replies; 5+ messages in thread
From: Jason Wang @ 2013-01-12 2:59 UTC (permalink / raw)
To: davem, mst, netdev, linux-kernel; +Cc: edumazet, stefanha, Jason Wang
Reference count leaking of both module and sock were found:
- When a detached file were closed, its sock refcnt from device were not
released, solving this by add the sock_put().
- The module were hold or drop unconditionally in TUNSETPERSIST, which means we
if we set the persist flag for N times, we need unset it for another N
times. Solving this by only hold or drop an reference when there's a flag
change and also drop the reference count when the persist device is deleted.
Signed-off-by: Jason Wang <jasowang@redhat.com>
---
drivers/net/tun.c | 12 +++++++++---
1 files changed, 9 insertions(+), 3 deletions(-)
diff --git a/drivers/net/tun.c b/drivers/net/tun.c
index a36b56f..af372d0 100644
--- a/drivers/net/tun.c
+++ b/drivers/net/tun.c
@@ -428,8 +428,10 @@ static void __tun_detach(struct tun_file *tfile, bool clean)
/* Drop read queue */
skb_queue_purge(&tfile->sk.sk_receive_queue);
tun_set_real_num_queues(tun);
- } else if (tfile->detached && clean)
+ } else if (tfile->detached && clean) {
tun = tun_enable_queue(tfile);
+ sock_put(&tfile->sk);
+ }
if (clean) {
if (tun && tun->numqueues == 0 && tun->numdisabled == 0 &&
@@ -478,6 +480,9 @@ static void tun_detach_all(struct net_device *dev)
sock_put(&tfile->sk);
}
BUG_ON(tun->numdisabled != 0);
+
+ if (tun->flags & TUN_PERSIST)
+ module_put(THIS_MODULE);
}
static int tun_attach(struct tun_struct *tun, struct file *file)
@@ -1874,10 +1879,11 @@ static long __tun_chr_ioctl(struct file *file, unsigned int cmd,
/* Disable/Enable persist mode. Keep an extra reference to the
* module to prevent the module being unprobed.
*/
- if (arg) {
+ if (arg && !(tun->flags & TUN_PERSIST)) {
tun->flags |= TUN_PERSIST;
__module_get(THIS_MODULE);
- } else {
+ }
+ if (!arg && (tun->flags & TUN_PERSIST)) {
tun->flags &= ~TUN_PERSIST;
module_put(THIS_MODULE);
}
--
1.7.1
^ permalink raw reply related [flat|nested] 5+ messages in thread
* Re: [PATCH V2 0/3] some fixes of tuntap
2013-01-12 2:59 [PATCH V2 0/3] some fixes of tuntap Jason Wang
` (2 preceding siblings ...)
2013-01-12 2:59 ` [PATCH V2 3/3] tuntap: fix leaking reference count Jason Wang
@ 2013-01-12 3:42 ` David Miller
3 siblings, 0 replies; 5+ messages in thread
From: David Miller @ 2013-01-12 3:42 UTC (permalink / raw)
To: jasowang; +Cc: mst, netdev, linux-kernel, edumazet, stefanha
From: Jason Wang <jasowang@redhat.com>
Date: Sat, 12 Jan 2013 10:59:31 +0800
> There series fixes two issues:
> - Don't allow calling TUNSETIFF when a file is detached which may cause kernel
> data structure corrupt.
> - Fix the reference count leaking of sock and module.
>
> Plus a suggestion from Eric to use rtnl_dereference() instead of the open code.
>
> Changes from v1:
> - don't use rcu to dereference tfile->detached as it was already protected by
> rtnl lock.
> - add a patch of switching to use rtnl_dereference().
All applied, thanks Jason.
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2013-01-12 3:42 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-01-12 2:59 [PATCH V2 0/3] some fixes of tuntap Jason Wang
2013-01-12 2:59 ` [PATCH V2 1/3] tuntap: switch to use rtnl_dereference() Jason Wang
2013-01-12 2:59 ` [PATCH V2 2/3] tuntap: forbid calling TUNSETIFF when detached Jason Wang
2013-01-12 2:59 ` [PATCH V2 3/3] tuntap: fix leaking reference count Jason Wang
2013-01-12 3:42 ` [PATCH V2 0/3] some fixes of tuntap David Miller
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).