net: fix dev_seq_next()
Commit c6d14c8456 (net: Introduce for_each_netdev_rcu() iterator)
added a race in dev_seq_next().
The rcu_dereference() call should be done _before_ testing the end of
list, or we might return a wrong net_device if a concurrent thread
changes net_device list under us.
Note : discovered thanks to a sparse warning :
net/core/dev.c:3919:9: error: incompatible types in comparison expression
(different address spaces)
Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
CC: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
committed by
David S. Miller
parent
065825402c
commit
ccf434380d
@@ -4051,12 +4051,15 @@ void *dev_seq_start(struct seq_file *seq, loff_t *pos)
|
||||
|
||||
void *dev_seq_next(struct seq_file *seq, void *v, loff_t *pos)
|
||||
{
|
||||
struct net_device *dev = (v == SEQ_START_TOKEN) ?
|
||||
first_net_device(seq_file_net(seq)) :
|
||||
next_net_device((struct net_device *)v);
|
||||
struct net_device *dev = v;
|
||||
|
||||
if (v == SEQ_START_TOKEN)
|
||||
dev = first_net_device_rcu(seq_file_net(seq));
|
||||
else
|
||||
dev = next_net_device_rcu(dev);
|
||||
|
||||
++*pos;
|
||||
return rcu_dereference(dev);
|
||||
return dev;
|
||||
}
|
||||
|
||||
void dev_seq_stop(struct seq_file *seq, void *v)
|
||||
|
||||
Reference in New Issue
Block a user