2024-10-29, 11:47:19 +0100, Antonio Quartulli wrote:
+static void ovpn_peer_release(struct ovpn_peer *peer) +{
- ovpn_bind_reset(peer, NULL);
- dst_cache_destroy(&peer->dst_cache);
Is it safe to destroy the cache at this time? In the same function, we use rcu to free the peer, but AFAICT the dst_cache will be freed immediately:
void dst_cache_destroy(struct dst_cache *dst_cache) { [...] free_percpu(dst_cache->cache); }
(probably no real issue because ovpn_udp_send_skb gets called while we hold a reference to the peer?)
- netdev_put(peer->ovpn->dev, &peer->ovpn->dev_tracker);
- kfree_rcu(peer, rcu);
+}
[...]
+static int ovpn_peer_del_p2p(struct ovpn_peer *peer,
enum ovpn_del_peer_reason reason)
- __must_hold(&peer->ovpn->lock)
+{
- struct ovpn_peer *tmp;
- tmp = rcu_dereference_protected(peer->ovpn->peer,
lockdep_is_held(&peer->ovpn->lock));
- if (tmp != peer) {
DEBUG_NET_WARN_ON_ONCE(1);
if (tmp)
ovpn_peer_put(tmp);
Does peer->ovpn->peer need to be set to NULL here as well? Or is it going to survive this _put?
return -ENOENT;
- }
- tmp->delete_reason = reason;
- RCU_INIT_POINTER(peer->ovpn->peer, NULL);
- ovpn_peer_put(tmp);
- return 0;
+}