summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorShuvam Pandey <shuvampandey1@gmail.com>2026-05-23 20:38:27 +0545
committerAntonio Quartulli <antonio@openvpn.net>2026-07-20 15:49:55 +0200
commita4710ae2e7e322fdaefb4be8604228279cfaf48c (patch)
treee5d0bd90e7794d670deae0af94a74b4907310f14
parent63bbe18fc03062f483c627838a566a707b62da79 (diff)
ovpn: hold peer before scheduling keepalive work
ovpn_peer_keepalive_send() passes its peer reference to ovpn_xmit_special(), which ultimately drops it. The keepalive scheduler currently queues the work first and takes the reference only after schedule_work() reports that the work was queued. Once schedule_work() queues the item, another CPU may run the worker before the caller gets to ovpn_peer_hold(). In that case the worker can consume a reference that was not acquired for it, corrupting the peer lifetime accounting. Take the peer reference before queueing the work and drop it again when the work was already pending. Fixes: 3ecfd9349f40 ("ovpn: implement keepalive mechanism") Cc: stable@vger.kernel.org Signed-off-by: Shuvam Pandey <shuvampandey1@gmail.com> Reviewed-by: Sabrina Dubroca <sd@queasysnail.net> Signed-off-by: Antonio Quartulli <antonio@openvpn.net>
-rw-r--r--drivers/net/ovpn/peer.c6
1 files changed, 4 insertions, 2 deletions
diff --git a/drivers/net/ovpn/peer.c b/drivers/net/ovpn/peer.c
index 1844d97154ce..2b6096d8b1cc 100644
--- a/drivers/net/ovpn/peer.c
+++ b/drivers/net/ovpn/peer.c
@@ -1284,8 +1284,10 @@ static time64_t ovpn_peer_keepalive_work_single(struct ovpn_peer *peer,
netdev_dbg(peer->ovpn->dev,
"sending keepalive to peer %u\n",
peer->id);
- if (schedule_work(&peer->keepalive_work))
- ovpn_peer_hold(peer);
+ if (WARN_ON(!ovpn_peer_hold(peer)))
+ return 0;
+ if (!schedule_work(&peer->keepalive_work))
+ ovpn_peer_put(peer);
}
if (next_run1 < next_run2)