<feed xmlns='http://www.w3.org/2005/Atom'>
<title>kernel/git/stable/linux.git/drivers/net/ovpn, branch linux-7.2.y</title>
<subtitle>Linux kernel stable tree</subtitle>
<id>https://git.rulkc.org/pub/scm/linux/kernel/git/stable/linux.git/atom?h=linux-7.2.y</id>
<link rel='self' href='https://git.rulkc.org/pub/scm/linux/kernel/git/stable/linux.git/atom?h=linux-7.2.y'/>
<link rel='alternate' type='text/html' href='https://git.rulkc.org/pub/scm/linux/kernel/git/stable/linux.git/'/>
<updated>2026-08-09T20:47:57+00:00</updated>
<entry>
<title>ovpn: defer key slot crypto freeing to workqueue</title>
<updated>2026-08-09T20:47:57+00:00</updated>
<author>
<name>Ralf Lici</name>
<email>ralf@mandelbit.com</email>
</author>
<published>2026-07-29T10:21:46+00:00</published>
<link rel='alternate' type='text/html' href='https://git.rulkc.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=2da3dfa1ddfe55a065f484750c83660e3bd4ac00'/>
<id>urn:sha1:2da3dfa1ddfe55a065f484750c83660e3bd4ac00</id>
<content type='text'>
Key slots are released through a kref and the existing release path
frees the AEAD transforms from an RCU callback. That is not safe for all
crypto implementations: crypto_free_aead can sleep, for example when an
async or hardware implementation has teardown work to complete.

Use queue_rcu_work for key-slot release. This keeps the RCU grace period
needed by lockless key-slot readers, but runs the actual crypto teardown
from workqueue context where sleeping is allowed. Once the rcu_work
callback runs, pre-existing RCU readers are gone, and the final kref put
already proves that no transform user remains, so the worker can release
the AEAD transforms and free the slot directly.

The previous patch drains ovpn_wq during module exit, so queued key-slot
teardown work cannot outlive module text.

Fixes: 8534731dbf2d ("ovpn: implement packet processing")
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: run deferred work on a module-owned workqueue</title>
<updated>2026-08-09T20:47:57+00:00</updated>
<author>
<name>Ralf Lici</name>
<email>ralf@mandelbit.com</email>
</author>
<published>2026-08-07T07:55:43+00:00</published>
<link rel='alternate' type='text/html' href='https://git.rulkc.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=e9714db8041763f59dde152c812b96b3de05c6d9'/>
<id>urn:sha1:e9714db8041763f59dde152c812b96b3de05c6d9</id>
<content type='text'>
ovpn queues several work items whose callbacks execute module text.
These works currently run on the global system workqueues, so module
exit has no driver-owned drain point that guarantees the callbacks have
fully returned before the module text can be freed.

Object references protect the objects used by the callbacks, but they do
not prove that a workqueue function has returned. In particular, a
worker can drop the final reference that unblocks device teardown while
it is still executing ovpn code.

Add a module-owned workqueue and queue all ovpn work items on it. During
module exit, unregister rtnl and netlink first, flush the workqueue so
ordinary ovpn workers finish, run the final RCU barrier, and destroy the
workqueue last. This keeps the workqueue available for cleanup work
queued from RCU callbacks, while ensuring no ovpn work item can outlive
the module text.

The per-device delayed keepalive work remains explicitly disabled during
netdev teardown (disable_delayed_work_sync in ndo_uninit), since
flush_workqueue does not flush delayed work that is still only pending
on its timer.

Fixes: 3ecfd9349f40 ("ovpn: implement keepalive mechanism")
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: finish crypto callback cleanup before peer release</title>
<updated>2026-08-07T00:12:13+00:00</updated>
<author>
<name>Ralf Lici</name>
<email>ralf@mandelbit.com</email>
</author>
<published>2026-07-29T10:21:44+00:00</published>
<link rel='alternate' type='text/html' href='https://git.rulkc.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=9e163917a86c6adfbe150e13f4c73653a54616de'/>
<id>urn:sha1:9e163917a86c6adfbe150e13f4c73653a54616de</id>
<content type='text'>
Crypto completion callbacks hold both key-slot and peer references. The
peer reference pins the netdev, and dropping the last peer reference can
let netdev unregistration and module removal make progress.

Do not release that peer reference before the callback has finished its
own cleanup. If ovpn_crypto_key_slot_put runs after ovpn_peer_put, it can
schedule an RCU callback backed by module text after ovpn_cleanup
rcu_barrier has already run. The TX error path also freed the remaining
skb after ovpn_peer_put, leaving callback cleanup outside the peer/netdev
lifetime window.

Release the key slot and free any remaining skb first, then drop the peer
reference as the last callback action.

Fixes: 8534731dbf2d ("ovpn: implement packet processing")
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 NULL dereference when killing missing key</title>
<updated>2026-08-07T00:12:13+00:00</updated>
<author>
<name>Ralf Lici</name>
<email>ralf@mandelbit.com</email>
</author>
<published>2026-07-29T10:21:41+00:00</published>
<link rel='alternate' type='text/html' href='https://git.rulkc.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=41d44ac7a61e2f74453af40d4fe1b82af9ea0ada'/>
<id>urn:sha1:41d44ac7a61e2f74453af40d4fe1b82af9ea0ada</id>
<content type='text'>
ovpn_crypto_kill_key assumes both crypto slots are populated and
dereferences each slot before checking it. That is not guaranteed: a
peer can have only one installed key, and the kill path may be asked to
remove a key that is not present.

Read each slot once while holding the crypto state lock, check for NULL
before looking at key_id, and only replace the slot that actually
matches.

Fixes: 89d3c0e4612a ("ovpn: kill key and notify userspace in case of IV exhaustion")
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 incorrect use of rcu_access_pointer()</title>
<updated>2026-07-30T09:28:30+00:00</updated>
<author>
<name>Qingfang Deng</name>
<email>qingfang.deng@linux.dev</email>
</author>
<published>2026-07-24T01:49:26+00:00</published>
<link rel='alternate' type='text/html' href='https://git.rulkc.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=26ba17d845193dac4921ae1ab280d28d1938052e'/>
<id>urn:sha1:26ba17d845193dac4921ae1ab280d28d1938052e</id>
<content type='text'>
rcu_access_pointer() should only be used to test the value of a pointer,
not to dereference it. As it's in a spin_lock_bh() critical section, use
rcu_dereference_bh() instead, avoiding an extra rcu_read_lock().

Fixes: f6226ae7a0cd ("ovpn: introduce the ovpn_socket object")
Signed-off-by: Qingfang Deng &lt;qingfang.deng@linux.dev&gt;
Signed-off-by: Antonio Quartulli &lt;antonio@openvpn.net&gt;
</content>
</entry>
<entry>
<title>ovpn: ensure TCP vars are initialized first</title>
<updated>2026-07-30T09:28:30+00:00</updated>
<author>
<name>Antonio Quartulli</name>
<email>antonio@openvpn.net</email>
</author>
<published>2026-07-28T11:48:54+00:00</published>
<link rel='alternate' type='text/html' href='https://git.rulkc.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=4680c0ebd958fc18e53c8b91d80436b236a8fc09'/>
<id>urn:sha1:4680c0ebd958fc18e53c8b91d80436b236a8fc09</id>
<content type='text'>
Netlink calls may access TCP global vars (i.e. when attaching
a TCP socket), therefore we need to make sure the
latters are initialized beforehand.

For this reason move the global TCP initialization at the top
of the module init function.

Fixes: 11851cbd60ea ("ovpn: implement TCP transport")
Signed-off-by: Antonio Quartulli &lt;antonio@openvpn.net&gt;
</content>
</entry>
<entry>
<title>ovpn: disable IPv4 redirects on MP interfaces</title>
<updated>2026-07-30T09:28:30+00:00</updated>
<author>
<name>Antonio Quartulli</name>
<email>antonio@openvpn.net</email>
</author>
<published>2026-07-28T11:48:53+00:00</published>
<link rel='alternate' type='text/html' href='https://git.rulkc.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=0301aa324941698bec3dd455df1c5abc7afb10db'/>
<id>urn:sha1:0301aa324941698bec3dd455df1c5abc7afb10db</id>
<content type='text'>
ovpn_mp_alloc() tried to disable SEND_REDIRECTS on a multipeer
interface, but it runs from ovpn_net_init() (-&gt;ndo_init), which
register_netdevice() invokes before the NETDEV_REGISTER notifier
chain. The IPv4 in_device is only created when that notifier reaches
inetdev_event() -&gt; inetdev_init(), so __in_dev_get_rtnl() always
returned NULL at ndo_init time and the whole redirect-disabling block
(both the per-device and the per-netns IPV4_DEVCONF_ALL write) was
dead. MP interfaces therefore kept emitting ICMP redirects.

Disabling redirects only once is not enough either: the IPv4
in_device is destroyed and recreated when the interface is moved to a
different network namespace (NETDEV_UNREGISTER/NETDEV_REGISTER), and
the newly created in_device inherits the destination namespace
defaults, silently re-enabling SEND_REDIRECTS.

Disable redirects from ovpn_net_open() (-&gt;ndo_open) instead: it runs
every time the interface is brought up, including after the in_device
has been recreated, so the setting is always re-applied. This mirrors
what wireguard does in wg_open(). RTNL is held on the ndo_open() path,
so __in_dev_get_rtnl() is safe.

Fixes: 05003b408c20 ("ovpn: implement multi-peer support")
Signed-off-by: Antonio Quartulli &lt;antonio@openvpn.net&gt;
</content>
</entry>
<entry>
<title>ovpn: hash floated peer by transport identity only</title>
<updated>2026-07-30T09:28:30+00:00</updated>
<author>
<name>Antonio Quartulli</name>
<email>antonio@openvpn.net</email>
</author>
<published>2026-07-28T11:48:52+00:00</published>
<link rel='alternate' type='text/html' href='https://git.rulkc.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=b47a52dcd598a50207a33df304acdf45348a690f'/>
<id>urn:sha1:b47a52dcd598a50207a33df304acdf45348a690f</id>
<content type='text'>
The by_transp_addr table is keyed on the peer's remote transport
address, but the float rehash hashed bind-&gt;remote directly, while the
two other sites that touch the table build a clean key first:
ovpn_peer_add_mp() and the lookup in ovpn_peer_get_by_transp_addr()
both hash a sockaddr holding only family/address/port.

For a link-local IPv6 peer, bind-&gt;remote carries sin6_scope_id (set
from ipv6_iface_scope_id() when the endpoint is learned), and that
field is folded into the jhash() over sizeof(struct sockaddr_in6).
The lookup never sets sin6_scope_id, so after such a peer floats it is
rehashed into a scope_id-dependent bucket that lookups (scope_id 0)
never visit, making the peer unreachable through the by_transp_addr
fallback. ovpn_peer_transp_match() only compares address and port, so
the hash was keying on a field the match ignores.

sin6_scope_id must stay in bind-&gt;remote because the TX path uses it as
flowi6_oif, so it cannot just be cleared there. Instead build the hash
key from family/address/port only, exactly like ovpn_peer_add_mp() and
the lookup, so all three sites agree on the bucket.

Fixes: f0281c1d3732 ("ovpn: add support for updating local or remote UDP endpoint")
Signed-off-by: Antonio Quartulli &lt;antonio@openvpn.net&gt;
</content>
</entry>
<entry>
<title>ovpn: zero-initialize sockaddr before learning a floated endpoint</title>
<updated>2026-07-30T09:28:30+00:00</updated>
<author>
<name>Antonio Quartulli</name>
<email>antonio@openvpn.net</email>
</author>
<published>2026-07-28T11:48:51+00:00</published>
<link rel='alternate' type='text/html' href='https://git.rulkc.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=3f012bdbabe211ccbc0c50ea5a1dbc60f8af1532'/>
<id>urn:sha1:3f012bdbabe211ccbc0c50ea5a1dbc60f8af1532</id>
<content type='text'>
ovpn_peer_endpoints_update() builds the new remote endpoint in an
on-stack struct sockaddr_storage that is left uninitialized. For IPv4
only sin_family/sin_addr/sin_port are written, leaving the 8-byte
sin_zero padding as stack garbage (for IPv6, sin6_flowinfo is left
uninitialized likewise).

ovpn_peer_reset_sockaddr() -&gt; ovpn_bind_from_sockaddr() then memcpy()s
sizeof(struct sockaddr_in)/sizeof(struct sockaddr_in6) bytes - padding
included - into bind-&gt;remote. That buffer is later hashed with jhash()
over the same length to place the peer in the by_transp_addr table, so
the garbage padding lands the floated peer in an essentially random
bucket. Lockless lookups in ovpn_peer_get_by_transp_addr() build their
key from a zero-initialized sockaddr_storage, compute a different bucket
and fail to find the peer.

This is also a plain use of uninitialized stack memory in jhash().

Build the floated endpoint with a designated initializer so the
padding (sin_zero for IPv4, sin6_flowinfo for IPv6) is zeroed as part
of the assignment. This keeps the padding out of the by_transp_addr
hash key without memset-ing the whole sockaddr_storage on every
received packet.

Fixes: f0281c1d3732 ("ovpn: add support for updating local or remote UDP endpoint")
Signed-off-by: Antonio Quartulli &lt;antonio@openvpn.net&gt;
</content>
</entry>
<entry>
<title>ovpn: ensure socket is owned by ovpn before deref sk_user_data</title>
<updated>2026-07-30T09:28:30+00:00</updated>
<author>
<name>Antonio Quartulli</name>
<email>antonio@openvpn.net</email>
</author>
<published>2026-07-28T11:48:50+00:00</published>
<link rel='alternate' type='text/html' href='https://git.rulkc.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=59aed1eb60d70678a53acccb0cb337a26ce6680e'/>
<id>urn:sha1:59aed1eb60d70678a53acccb0cb337a26ce6680e</id>
<content type='text'>
Some subsystems, like BPF SOCKMAP, set sk_user_data without
actually setting the encap_type.

For this reason, we must make sure that the type is the
one ovpn expects before dereferencing sk_user_data.

Failing to do so may lead to out-of-bounds reads.

Fixes: f6226ae7a0cd ("ovpn: introduce the ovpn_socket object")
Signed-off-by: Antonio Quartulli &lt;antonio@openvpn.net&gt;
</content>
</entry>
</feed>
