Subject: [PATCH net] ovpn: Fix race condition in ovpn_dellink()

From: Hyunwoo Kim <[email-masked]>
Date: Mon, 2 Mar 2026 19:02:15 +0900

When ovpn_dellink() is called, it invokes
cancel_delayed_work_sync() to stop keepalive_work before freeing
the device.
However, ovpn_nl_peer_new_doit() runs without any lock shared
with the RTNL path, so keepalive_work can be scheduled after
cancel_delayed_work_sync() returns.

The following is a simple race scenario:

          cpu0                            cpu1

ovpn_dellink(dev)
  cancel_delayed_work_sync(keepalive_work)
                                   ovpn_nl_peer_new_doit()
                                     ovpn_nl_peer_modify()
                                       ovpn_peer_keepalive_set()
                                         mod_delayed_work(keepalive_work)

To prevent this race condition, cancel_delayed_work_sync() is
replaced with disable_delayed_work_sync().

Fixes: 3ecfd9349f40 ("ovpn: implement keepalive mechanism")
Signed-off-by: Hyunwoo Kim <[email-masked]>
---
 drivers/net/ovpn/main.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/ovpn/main.c b/drivers/net/ovpn/main.c
index 2e0420febda0..ada73dd35ba4 100644
--- a/drivers/net/ovpn/main.c
+++ b/drivers/net/ovpn/main.c
@@ -212,7 +212,7 @@ static void ovpn_dellink(struct net_device *dev, struct list_head *head)
 {
 	struct ovpn_priv *ovpn = netdev_priv(dev);
 
-	cancel_delayed_work_sync(&ovpn->keepalive_work);
+	disable_delayed_work_sync(&ovpn->keepalive_work);
 	ovpn_peers_free(ovpn, NULL, OVPN_DEL_PEER_REASON_TEARDOWN);
 	unregister_netdevice_queue(dev, head);
 }
-- 
2.43.0