diff options
author | Nicolas Schichan <nschichan@freebox.fr> | 2013-06-26 19:23:42 +0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2013-06-27 00:42:54 +0400 |
commit | 5dbe7c178d3f0a4634f088d9e729f1909b9ddcd1 (patch) | |
tree | 8945b6c5125b57cee5f36e903fc995e58664a639 /net/ipv6/ip6_output.c | |
parent | 6d446ec32f169c6a5d9bc90684a8082a6cbe90f6 (diff) | |
download | linux-5dbe7c178d3f0a4634f088d9e729f1909b9ddcd1.tar.xz |
net: fix kernel deadlock with interface rename and netdev name retrieval.
When the kernel (compiled with CONFIG_PREEMPT=n) is performing the
rename of a network interface, it can end up waiting for a workqueue
to complete. If userland is able to invoke a SIOCGIFNAME ioctl or a
SO_BINDTODEVICE getsockopt in between, the kernel will deadlock due to
the fact that read_secklock_begin() will spin forever waiting for the
writer process (the one doing the interface rename) to update the
devnet_rename_seq sequence.
This patch fixes the problem by adding a helper (netdev_get_name())
and using it in the code handling the SIOCGIFNAME ioctl and
SO_BINDTODEVICE setsockopt.
The netdev_get_name() helper uses raw_seqcount_begin() to avoid
spinning forever, waiting for devnet_rename_seq->sequence to become
even. cond_resched() is used in the contended case, before retrying
the access to give the writer process a chance to finish.
The use of raw_seqcount_begin() will incur some unneeded work in the
reader process in the contended case, but this is better than
deadlocking the system.
Signed-off-by: Nicolas Schichan <nschichan@freebox.fr>
Acked-by: Eric Dumazet <edumazet@google.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv6/ip6_output.c')
0 files changed, 0 insertions, 0 deletions