Skip to content

Commit 59cbf56

Browse files
Eric Dumazetdavem330
Eric Dumazet
authored andcommitted
vxlan: test dev->flags & IFF_UP before calling gro_cells_receive()
Same reasons than the ones explained in commit 4179cb5 ("vxlan: test dev->flags & IFF_UP before calling netif_rx()") netif_rx() or gro_cells_receive() must be called under a strict contract. At device dismantle phase, core networking clears IFF_UP and flush_all_backlogs() is called after rcu grace period to make sure no incoming packet might be in a cpu backlog and still referencing the device. A similar protocol is used for gro_cells infrastructure, as gro_cells_destroy() will be called only after a full rcu grace period is observed after IFF_UP has been cleared. Most drivers call netif_rx() from their interrupt handler, and since the interrupts are disabled at device dismantle, netif_rx() does not have to check dev->flags & IFF_UP Virtual drivers do not have this guarantee, and must therefore make the check themselves. Otherwise we risk use-after-free and/or crashes. Fixes: d342894 ("vxlan: virtual extensible lan") Signed-off-by: Eric Dumazet <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 95d6ebd commit 59cbf56

File tree

1 file changed

+11
-0
lines changed

1 file changed

+11
-0
lines changed

drivers/net/vxlan.c

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1731,13 +1731,24 @@ static int vxlan_rcv(struct sock *sk, struct sk_buff *skb)
17311731
goto drop;
17321732
}
17331733

1734+
rcu_read_lock();
1735+
1736+
if (unlikely(!(vxlan->dev->flags & IFF_UP))) {
1737+
rcu_read_unlock();
1738+
atomic_long_inc(&vxlan->dev->rx_dropped);
1739+
goto drop;
1740+
}
1741+
17341742
stats = this_cpu_ptr(vxlan->dev->tstats);
17351743
u64_stats_update_begin(&stats->syncp);
17361744
stats->rx_packets++;
17371745
stats->rx_bytes += skb->len;
17381746
u64_stats_update_end(&stats->syncp);
17391747

17401748
gro_cells_receive(&vxlan->gro_cells, skb);
1749+
1750+
rcu_read_unlock();
1751+
17411752
return 0;
17421753

17431754
drop:

0 commit comments

Comments
 (0)