<feed xmlns='http://www.w3.org/2005/Atom'>
<title>kernel/linux.git/drivers/net/ovpn, branch v7.1.6</title>
<subtitle>Linux kernel stable tree (mirror)</subtitle>
<id>https://git.radix-linux.su/kernel/linux.git/atom?h=v7.1.6</id>
<link rel='self' href='https://git.radix-linux.su/kernel/linux.git/atom?h=v7.1.6'/>
<link rel='alternate' type='text/html' href='https://git.radix-linux.su/kernel/linux.git/'/>
<updated>2026-08-03T09:26:00+00:00</updated>
<entry>
<title>ovpn: hold peer before scheduling keepalive work</title>
<updated>2026-08-03T09:26:00+00:00</updated>
<author>
<name>Shuvam Pandey</name>
<email>shuvampandey1@gmail.com</email>
</author>
<published>2026-05-23T14:53:27+00:00</published>
<link rel='alternate' type='text/html' href='https://git.radix-linux.su/kernel/linux.git/commit/?id=ee6c5b5194f16d719dd22839b01c9ee8ad9ab934'/>
<id>urn:sha1:ee6c5b5194f16d719dd22839b01c9ee8ad9ab934</id>
<content type='text'>
commit a4710ae2e7e322fdaefb4be8604228279cfaf48c upstream.

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 &lt;shuvampandey1@gmail.com&gt;
Reviewed-by: Sabrina Dubroca &lt;sd@queasysnail.net&gt;
Signed-off-by: Antonio Quartulli &lt;antonio@openvpn.net&gt;
Signed-off-by: Greg Kroah-Hartman &lt;gregkh@linuxfoundation.org&gt;
</content>
</entry>
<entry>
<title>ovpn: fix peer refcount leak in TCP error paths</title>
<updated>2026-08-03T09:26:00+00:00</updated>
<author>
<name>Pavitra Jha</name>
<email>jhapavitra98@gmail.com</email>
</author>
<published>2026-05-23T09:02:43+00:00</published>
<link rel='alternate' type='text/html' href='https://git.radix-linux.su/kernel/linux.git/commit/?id=f08f39c1f43f3980d46b06af8ed99ffe84ac294a'/>
<id>urn:sha1:f08f39c1f43f3980d46b06af8ed99ffe84ac294a</id>
<content type='text'>
commit 63bbe18fc03062f483c627838a566a707b62da79 upstream.

When either the TCP RX or TX error path calls ovpn_peer_hold() followed
by schedule_work(&amp;peer-&gt;tcp.defer_del_work), and the work item is already
pending from the other path, schedule_work() returns false and the work
runs only once. Since ovpn_tcp_peer_del_work() calls ovpn_peer_put()
exactly once, the extra reference taken by the losing path is never
dropped, leaking the peer object.

The race window:

  CPU0 (strparser/RX error):       CPU1 (tcp_tx_work/TX error):
  ovpn_peer_hold()   &lt;- refcnt+1   ovpn_peer_hold()   &lt;- refcnt+2
  schedule_work()    &lt;- queued      schedule_work()    &lt;- NO-OP
                                    (work already pending)
  ovpn_tcp_peer_del_work runs:
    ovpn_peer_del()
    ovpn_peer_put()  &lt;- refcnt+1
                                   &lt;- peer never freed

Fix by checking the return value of schedule_work() in both paths and
calling ovpn_peer_put() to drop the extra reference if the work was
already pending. ovpn_peer_hold() is kept unconditional in the TX path
as it cannot fail at that point.

Fixes: a6a5e87b3ee4 ("ovpn: avoid sleep in atomic context in TCP RX error path")
Cc: stable@vger.kernel.org
Signed-off-by: Pavitra Jha &lt;jhapavitra98@gmail.com&gt;
Reviewed-by: Sabrina Dubroca &lt;sd@queasysnail.net&gt;
Signed-off-by: Antonio Quartulli &lt;antonio@openvpn.net&gt;
Signed-off-by: Greg Kroah-Hartman &lt;gregkh@linuxfoundation.org&gt;
</content>
</entry>
<entry>
<title>ovpn: use monotonic clock for peer keepalive timeouts</title>
<updated>2026-08-03T09:25:30+00:00</updated>
<author>
<name>Marco Baffo</name>
<email>marco@mandelbit.com</email>
</author>
<published>2026-06-08T14:06:42+00:00</published>
<link rel='alternate' type='text/html' href='https://git.radix-linux.su/kernel/linux.git/commit/?id=6c85bc624b4cdd41e2864ec3f67da39ca13005c2'/>
<id>urn:sha1:6c85bc624b4cdd41e2864ec3f67da39ca13005c2</id>
<content type='text'>
[ Upstream commit f7e6287ccd3abeed9e638b581dc3fdf742106ba3 ]

Replace ktime_get_real_seconds() with the monotonic
ktime_get_boottime_seconds() to ensure the keepalive mechanism is robust
against system clock modifications.

Right now, the driver uses ktime_get_real_seconds() to track peer
timeouts, relying on the system wall-clock.

An administrative time adjustment or an NTP sync that steps the clock
forward can cause `now' to instantly exceed `last_recv + timeout'.

When this occurs, the driver artificially expires healthy peers.
Depending on the OpenVPN user-space configuration, this triggers a
premature tunnel restart (if --keepalive or --ping-restart is used) or
a complete disconnection of the client (if --ping-exit is used).

Fixes: 3ecfd9349f40 ("ovpn: implement keepalive mechanism")
Signed-off-by: Marco Baffo &lt;marco@mandelbit.com&gt;
Signed-off-by: Antonio Quartulli &lt;antonio@openvpn.net&gt;
Signed-off-by: Sasha Levin &lt;sashal@kernel.org&gt;
</content>
</entry>
<entry>
<title>ovpn: fix use after free in unlock_ovpn()</title>
<updated>2026-08-03T09:25:29+00:00</updated>
<author>
<name>Marco Baffo</name>
<email>marco@mandelbit.com</email>
</author>
<published>2026-06-08T14:04:46+00:00</published>
<link rel='alternate' type='text/html' href='https://git.radix-linux.su/kernel/linux.git/commit/?id=4cdb209f12a89c5faf9be0c45edb90ccdf65db0c'/>
<id>urn:sha1:4cdb209f12a89c5faf9be0c45edb90ccdf65db0c</id>
<content type='text'>
[ Upstream commit e1ad6fe5db719874efa45b2caf9934552e09fc43 ]

unlock_ovpn() iterates over the release_list using llist_for_each_entry()
and drops the peer reference inside the loop body via ovpn_peer_put().

If this drops the last reference, the peer is eventually freed. However,
llist_for_each_entry() reads peer-&gt;release_entry.next in the loop advance
expression, which runs after the body. By that time the peer may have
already been freed, resulting in a use after free when advancing to the
next list entry.

Fix this by using llist_for_each_entry_safe(), which caches the next
pointer before executing the loop body.

Fixes: 80747caef33d ("ovpn: introduce the ovpn_peer object")
Signed-off-by: Marco Baffo &lt;marco@mandelbit.com&gt;
Signed-off-by: Antonio Quartulli &lt;antonio@openvpn.net&gt;
Signed-off-by: Sasha Levin &lt;sashal@kernel.org&gt;
</content>
</entry>
<entry>
<title>ovpn: avoid putting unrelated P2P peer on socket release</title>
<updated>2026-08-03T09:25:29+00:00</updated>
<author>
<name>Qing Ming</name>
<email>a0yami@mailbox.org</email>
</author>
<published>2026-05-23T08:15:43+00:00</published>
<link rel='alternate' type='text/html' href='https://git.radix-linux.su/kernel/linux.git/commit/?id=016a50379d17b886d12a4efa5211a418e035fe70'/>
<id>urn:sha1:016a50379d17b886d12a4efa5211a418e035fe70</id>
<content type='text'>
[ Upstream commit b52c5103f64ee825996ca1ab8df7283cde8c5f86 ]

ovpn_peer_release_p2p() is called when an OVPN UDP socket is being
destroyed. It checks the currently published P2P peer and releases it only
if that peer still uses the socket being destroyed.

A peer replacement can publish a new peer before the old UDP socket is
destroyed. When the old socket destruction path runs afterwards,
ovpn_peer_release_p2p() observes the new peer through ovpn-&gt;peer. Since the
new peer uses a different socket, the function takes the socket mismatch
branch.

That branch still calls ovpn_peer_put(peer). At this point, however, peer
is the currently published replacement peer, not the peer associated with
the socket being destroyed. Dropping its reference can free it while
ovpn-&gt;peer still points to it, leading to later use-after-free accesses
from the peer and socket cleanup paths.

KASAN reports this as a slab-use-after-free on the kmalloc-1k ovpn_peer
object. In the reproducer, the object is allocated from ovpn_peer_new() via
ovpn_nl_peer_new_doit(), and freed through ovpn_peer_release_rcu() from RCU
callback processing. Observed access sites include ovpn_peer_remove(),
ovpn_socket_release(), ovpn_nl_peer_del_notify(), and unlock_ovpn().

Fix this by returning from the socket mismatch branch without putting the
peer.

Fixes: f6226ae7a0cd ("ovpn: introduce the ovpn_socket object")
Signed-off-by: Qing Ming &lt;a0yami@mailbox.org&gt;
Reviewed-by: Simon Horman &lt;horms@kernel.org&gt;
Signed-off-by: Antonio Quartulli &lt;antonio@openvpn.net&gt;
Signed-off-by: Sasha Levin &lt;sashal@kernel.org&gt;
</content>
</entry>
<entry>
<title>udp_tunnel: Pass struct sock to setup_udp_tunnel_sock().</title>
<updated>2026-07-24T14:20:31+00:00</updated>
<author>
<name>Kuniyuki Iwashima</name>
<email>kuniyu@google.com</email>
</author>
<published>2026-05-02T03:12:55+00:00</published>
<link rel='alternate' type='text/html' href='https://git.radix-linux.su/kernel/linux.git/commit/?id=80e9adfed05d687a984b18d2f6ab2ee2bba370cf'/>
<id>urn:sha1:80e9adfed05d687a984b18d2f6ab2ee2bba370cf</id>
<content type='text'>
[ Upstream commit 2cba193628fe523cee6dd61938db2c4563ce15a9 ]

None of the udp_tunnel users need struct socket in their
fast paths; it is only used for tunnel setup / teardown.

Even setup_udp_tunnel_sock() does not need struct socket.

Let's change setup_udp_tunnel_sock() to take struct sock
instead of struct socket.

Signed-off-by: Kuniyuki Iwashima &lt;kuniyu@google.com&gt;
Link: https://patch.msgid.link/20260502031401.3557229-3-kuniyu@google.com
Signed-off-by: Jakub Kicinski &lt;kuba@kernel.org&gt;
Stable-dep-of: c1481c94e74c ("tipc: avoid busy looping in tipc_exit_net()")
Signed-off-by: Sasha Levin &lt;sashal@kernel.org&gt;
</content>
</entry>
<entry>
<title>ovpn: disable BHs when updating device stats</title>
<updated>2026-05-14T22:43:55+00:00</updated>
<author>
<name>Ralf Lici</name>
<email>ralf@mandelbit.com</email>
</author>
<published>2026-05-13T13:26:10+00:00</published>
<link rel='alternate' type='text/html' href='https://git.radix-linux.su/kernel/linux.git/commit/?id=0c0dddc07d272a8d25922e48041e8e4d2434df7e'/>
<id>urn:sha1:0c0dddc07d272a8d25922e48041e8e4d2434df7e</id>
<content type='text'>
ovpn updates dev-&gt;dstats from both process and softirq contexts. In
particular, TCP paths may run from socket callbacks, workqueues or
strparser work, while UDP receive and ovpn's ndo_start_xmit path may
update the same per-device dstats from BH context.

Add ovpn device drop-stat helpers that disable BHs around
dev_dstats_rx_dropped() and dev_dstats_tx_dropped(), and use them for
drop accounting.

The successful RX dev_dstats_rx_add() update is already covered by the
BH-disabled section around gro_cells_receive(). For the successful TCP
TX dev_dstats_tx_add() update, replace the existing preempt-disabled
section with a BH-disabled one.

Fixes: 11851cbd60ea ("ovpn: implement TCP transport")
Signed-off-by: Ralf Lici &lt;ralf@mandelbit.com&gt;
Signed-off-by: Antonio Quartulli &lt;antonio@openvpn.net&gt;
</content>
</entry>
<entry>
<title>ovpn: fix race between deleting interface and adding new peer</title>
<updated>2026-05-14T14:24:45+00:00</updated>
<author>
<name>Antonio Quartulli</name>
<email>antonio@openvpn.net</email>
</author>
<published>2026-03-17T13:47:56+00:00</published>
<link rel='alternate' type='text/html' href='https://git.radix-linux.su/kernel/linux.git/commit/?id=982422b11e6f95f766a8cd2c2b1cbdb77e234a61'/>
<id>urn:sha1:982422b11e6f95f766a8cd2c2b1cbdb77e234a61</id>
<content type='text'>
While deleting an existing ovpn interface, there is a very
narrow window where adding a new peer via netlink may cause
the netdevice to hang and prevent its unregistration.

It may happen during ovpn_dellink(), when all existing peers are
freed and the device is queued for deregistration, but a
CMD_PEER_NEW message comes in adding a new peer that takes again
a reference to the netdev.

At this point there is no way to release the device because we are
under the assumption that all peers were already released.

Fix the race condition by releasing all peers in ndo_uninit(),
when the netdevice has already been removed from the netdev
list.

Also ovpn_peer_add() has now an extra check that forces the
function to bail out if the device reg_state is not REGISTERED.
This way any incoming CMD_PEER_NEW racing with the interface
deletion routine will simply stop before adding the peer.

Note that the above check happens while holding the netdev_lock
to prevent racing netdev state changes.

ovpn_dellink() is now empty and can be removed.

Reported-by: Hyunwoo Kim &lt;imv4bel@gmail.com&gt;
Closes: https://lore.kernel.org/netdev/aaVgJ16edTfQkYbx@v4bel/
Suggested-by: Sabrina Dubroca &lt;sd@queasysnail.net&gt;
Fixes: 80747caef33d ("ovpn: introduce the ovpn_peer object")
Reviewed-by: Sabrina Dubroca &lt;sd@queasysnail.net&gt;
Signed-off-by: Antonio Quartulli &lt;antonio@openvpn.net&gt;
</content>
</entry>
<entry>
<title>ovpn: respect peer refcount in CMD_NEW_PEER error path</title>
<updated>2026-05-14T14:24:45+00:00</updated>
<author>
<name>David Carlier</name>
<email>devnexen@gmail.com</email>
</author>
<published>2026-05-13T10:55:21+00:00</published>
<link rel='alternate' type='text/html' href='https://git.radix-linux.su/kernel/linux.git/commit/?id=1fef6614673ff0846d30acdeeaf3cf98bb5f6116'/>
<id>urn:sha1:1fef6614673ff0846d30acdeeaf3cf98bb5f6116</id>
<content type='text'>
ovpn_nl_peer_new_doit()'s error path calls ovpn_peer_release() directly
rather than ovpn_peer_put(), bypassing the kref. The accompanying
comment ("peer was not yet hashed, thus it is not used in any context")
holds for UDP but not for TCP.

For UDP, the ovpn_socket union uses the .ovpn arm and never points back
at a peer; UDP encap_recv looks up peers via the not-yet-populated
hashtables, so the new peer is unreachable until ovpn_peer_add()
publishes it.

For TCP, ovpn_socket_new() sets ovpn_sock-&gt;peer and
ovpn_tcp_socket_attach() publishes ovpn_sock via rcu_assign_sk_user_data().
From that moment until ovpn_socket_release() detaches in the error path,
the TCP fd is fully wired: userspace recvmsg / sendmsg / close / poll
on the fd, as well as the strparser-driven ovpn_tcp_rcv() path, can
reach the peer through sk_user_data -&gt; ovpn_sock-&gt;peer and bump its
refcount via ovpn_peer_hold().

ovpn_tcp_socket_wait_finish() (called inside ovpn_socket_release())
drains strparser and the tx work, but does not synchronize with
userspace syscall callers that already hold a peer reference. If
ovpn_nl_peer_modify() or ovpn_peer_add() returns an error while such
a caller is in flight - notably an ovpn_tcp_recvmsg() blocked in
__skb_recv_datagram() on peer-&gt;tcp.user_queue - the direct
ovpn_peer_release() destroys the peer while the caller still holds
the reference, and the eventual ovpn_peer_put() from that caller
operates on freed memory.

Replace the direct destructor call with ovpn_peer_put() so the kref
correctly defers destruction until the last reference is dropped.
In the common case where no concurrent user is present, behaviour is
unchanged: the kref hits zero immediately and ovpn_peer_release_kref()
runs the same destructor.

With this conversion ovpn_peer_release() has no callers outside peer.c
- ovpn_peer_release_kref() in the same translation unit is the only
remaining user - so make it static and drop its declaration from
peer.h.

Fixes: 11851cbd60ea ("ovpn: implement TCP transport")
Reviewed-by: Sabrina Dubroca &lt;sd@queasysnail.net&gt;
Assisted-by: Claude:claude-opus-4-7
Signed-off-by: David Carlier &lt;devnexen@gmail.com&gt;
Signed-off-by: Antonio Quartulli &lt;antonio@openvpn.net&gt;
</content>
</entry>
<entry>
<title>ovpn: tcp - use cached peer pointer in ovpn_tcp_close()</title>
<updated>2026-05-14T14:24:45+00:00</updated>
<author>
<name>David Carlier</name>
<email>devnexen@gmail.com</email>
</author>
<published>2026-05-13T10:55:20+00:00</published>
<link rel='alternate' type='text/html' href='https://git.radix-linux.su/kernel/linux.git/commit/?id=775d8d7ad02aa345e1588424a6a8b9ae49fb9012'/>
<id>urn:sha1:775d8d7ad02aa345e1588424a6a8b9ae49fb9012</id>
<content type='text'>
ovpn_tcp_close() loads the ovpn_socket via rcu_dereference_sk_user_data()
under rcu_read_lock(), takes a reference on sock-&gt;peer, caches the peer
pointer in a local, and drops the read lock. It then passes sock-&gt;peer
(rather than the cached local) to ovpn_peer_del(), re-dereferencing the
ovpn_socket after the RCU read section has ended.

Unlike ovpn_tcp_sendmsg(), which uses the same "load under RCU, use
after unlock" pattern but is protected by lock_sock() held across the
function, ovpn_tcp_close() runs without the socket lock: inet_release()
invokes sk_prot-&gt;close() without taking lock_sock first.

ovpn_socket_release() can therefore complete its kref_put -&gt; detach -&gt;
synchronize_rcu -&gt; kfree(sock) sequence concurrently, in the window
after ovpn_tcp_close() drops rcu_read_lock() but before it dereferences
sock-&gt;peer. The synchronize_rcu() in ovpn_socket_release() protects
readers that use the dereferenced pointer inside the RCU read section,
not those that escape the pointer to a local and use it afterwards.

A reproducer follows the pattern of commit 94560267d6c4 ("ovpn: tcp -
don't deref NULL sk_socket member after tcp_close()"): trigger a peer
removal (keepalive expiration or netlink OVPN_CMD_DEL_PEER) at the same
moment userspace closes the TCP fd. That commit fixed the detach-side
of the same race window; this one fixes the close-side at a different
victim.

Tighten the entry block to read sock-&gt;peer exactly once into the cached
peer local, and route all subsequent uses (the hold check, the
ovpn_peer_del() call, and the prot-&gt;close() invocation) through that
local. sock-&gt;peer is only ever written once in ovpn_socket_new() under
lock_sock(), before rcu_assign_sk_user_data() publishes the ovpn_socket,
and is never reassigned afterwards - but the previous multi-read pattern
made that invariant implicit rather than explicit. The same multi-read
shape exists in ovpn_tcp_recvmsg(), ovpn_tcp_sendmsg(),
ovpn_tcp_data_ready() and ovpn_tcp_write_space(); those will be cleaned
up via a dedicated helper in a follow-up net-next series.

Fixes: 11851cbd60ea ("ovpn: implement TCP transport")
Reviewed-by: Sabrina Dubroca &lt;sd@queasysnail.net&gt;
Assisted-by: Claude:claude-opus-4-7
Signed-off-by: David Carlier &lt;devnexen@gmail.com&gt;
Signed-off-by: Antonio Quartulli &lt;antonio@openvpn.net&gt;
</content>
</entry>
</feed>
