diff options
author | Eric W. Biederman <ebiederm@xmission.com> | 2009-01-20 11:07:17 +0000 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2009-01-21 16:00:46 -0800 |
commit | c70f182940f988448f3c12a209d18b1edc276e33 (patch) | |
tree | 6469d90befb657f4ef37cc40c03b97de992dba80 /net | |
parent | b2430de37ef0bc0799ffba7b5219d38ca417eb76 (diff) | |
download | linux-3.10-c70f182940f988448f3c12a209d18b1edc276e33.tar.gz linux-3.10-c70f182940f988448f3c12a209d18b1edc276e33.tar.bz2 linux-3.10-c70f182940f988448f3c12a209d18b1edc276e33.zip |
tun: Fix races between tun_net_close and free_netdev.
The tun code does not cope gracefully if the network device goes away before
the tun file descriptor is closed. It looks like we can trigger this with
rmmod, and moving tun devices between network namespaces will allow this
to be triggered when network namespaces exit.
To fix this I introduce an intermediate data structure tun_file which
holds a count of users and a pointer to the struct tun_struct. tun_get
increments that reference count if it is greater than 0. tun_put decrements
that reference count and detaches from the network device if the count is 0.
While we have a file attached to the network device I hold a reference
to the network device keeping it from going away completely.
When a network device is unregistered I decrement the count of the
attached tun_file and if that was the last user I detach the tun_file,
and all processes on read_wait are woken up to ensure they do not
sleep indefinitely. As some of those sleeps happen with the count on
the tun device elevated waking up the read waiters ensures that
tun_file will be detached in a timely manner.
Signed-off-by: Eric W. Biederman <ebiederm@aristanetworks.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net')
0 files changed, 0 insertions, 0 deletions