Skip to content

Commit ec6a328

Browse files
author
Paolo Abeni
committed
Merge tag 'ovpn-net-20250603' of https://github.com/OpenVPN/ovpn-net-next
Antonio Quartulli says: ==================== In this batch you can find the following bug fixes: Patch 1: when releasing a UDP socket we were wrongly invoking setup_udp_tunnel_sock() with an empty config. This was not properly shutting down the UDP encap state. With this patch we simply undo what was done during setup. Patch 2: ovpn was holding a reference to a 'struct socket' without increasing its reference counter. This was intended and worked as expected until we hit a race condition where user space tries to close the socket while kernel space is also releasing it. In this case the (struct socket *)->sk member would disappear under our feet leading to a null-ptr-deref. This patch fixes this issue by having struct ovpn_socket hold a reference directly to the sk member while also increasing its reference counter. Patch 3: in case of errors along the TCP RX path (softirq) we want to immediately delete the peer, but this operation may sleep. With this patch we move the peer deletion to a scheduled worker. Patch 4 and 5 are instead fixing minor issues in the ovpn kselftests. * tag 'ovpn-net-20250603' of https://github.com/OpenVPN/ovpn-net-next: selftest/net/ovpn: fix missing file selftest/net/ovpn: fix TCP socket creation ovpn: avoid sleep in atomic context in TCP RX error path ovpn: ensure sk is still valid during cleanup ovpn: properly deconfigure UDP-tunnel ==================== Link: https://patch.msgid.link/[email protected]/ Signed-off-by: Paolo Abeni <[email protected]>
2 parents 501fe52 + 9c7e8b3 commit ec6a328

File tree

11 files changed

+128
-108
lines changed

11 files changed

+128
-108
lines changed

drivers/net/ovpn/io.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,7 @@ void ovpn_decrypt_post(void *data, int ret)
134134

135135
rcu_read_lock();
136136
sock = rcu_dereference(peer->sock);
137-
if (sock && sock->sock->sk->sk_protocol == IPPROTO_UDP)
137+
if (sock && sock->sk->sk_protocol == IPPROTO_UDP)
138138
/* check if this peer changed local or remote endpoint */
139139
ovpn_peer_endpoints_update(peer, skb);
140140
rcu_read_unlock();
@@ -270,12 +270,12 @@ void ovpn_encrypt_post(void *data, int ret)
270270
if (unlikely(!sock))
271271
goto err_unlock;
272272

273-
switch (sock->sock->sk->sk_protocol) {
273+
switch (sock->sk->sk_protocol) {
274274
case IPPROTO_UDP:
275-
ovpn_udp_send_skb(peer, sock->sock, skb);
275+
ovpn_udp_send_skb(peer, sock->sk, skb);
276276
break;
277277
case IPPROTO_TCP:
278-
ovpn_tcp_send_skb(peer, sock->sock, skb);
278+
ovpn_tcp_send_skb(peer, sock->sk, skb);
279279
break;
280280
default:
281281
/* no transport configured yet */

drivers/net/ovpn/netlink.c

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -501,7 +501,7 @@ int ovpn_nl_peer_set_doit(struct sk_buff *skb, struct genl_info *info)
501501
/* when using a TCP socket the remote IP is not expected */
502502
rcu_read_lock();
503503
sock = rcu_dereference(peer->sock);
504-
if (sock && sock->sock->sk->sk_protocol == IPPROTO_TCP &&
504+
if (sock && sock->sk->sk_protocol == IPPROTO_TCP &&
505505
(attrs[OVPN_A_PEER_REMOTE_IPV4] ||
506506
attrs[OVPN_A_PEER_REMOTE_IPV6])) {
507507
rcu_read_unlock();
@@ -559,14 +559,14 @@ static int ovpn_nl_send_peer(struct sk_buff *skb, const struct genl_info *info,
559559
goto err_unlock;
560560
}
561561

562-
if (!net_eq(genl_info_net(info), sock_net(sock->sock->sk))) {
562+
if (!net_eq(genl_info_net(info), sock_net(sock->sk))) {
563563
id = peernet2id_alloc(genl_info_net(info),
564-
sock_net(sock->sock->sk),
564+
sock_net(sock->sk),
565565
GFP_ATOMIC);
566566
if (nla_put_s32(skb, OVPN_A_PEER_SOCKET_NETNSID, id))
567567
goto err_unlock;
568568
}
569-
local_port = inet_sk(sock->sock->sk)->inet_sport;
569+
local_port = inet_sk(sock->sk)->inet_sport;
570570
rcu_read_unlock();
571571

572572
if (nla_put_u32(skb, OVPN_A_PEER_ID, peer->id))
@@ -1153,8 +1153,8 @@ int ovpn_nl_peer_del_notify(struct ovpn_peer *peer)
11531153
ret = -EINVAL;
11541154
goto err_unlock;
11551155
}
1156-
genlmsg_multicast_netns(&ovpn_nl_family, sock_net(sock->sock->sk),
1157-
msg, 0, OVPN_NLGRP_PEERS, GFP_ATOMIC);
1156+
genlmsg_multicast_netns(&ovpn_nl_family, sock_net(sock->sk), msg, 0,
1157+
OVPN_NLGRP_PEERS, GFP_ATOMIC);
11581158
rcu_read_unlock();
11591159

11601160
return 0;
@@ -1218,8 +1218,8 @@ int ovpn_nl_key_swap_notify(struct ovpn_peer *peer, u8 key_id)
12181218
ret = -EINVAL;
12191219
goto err_unlock;
12201220
}
1221-
genlmsg_multicast_netns(&ovpn_nl_family, sock_net(sock->sock->sk),
1222-
msg, 0, OVPN_NLGRP_PEERS, GFP_ATOMIC);
1221+
genlmsg_multicast_netns(&ovpn_nl_family, sock_net(sock->sk), msg, 0,
1222+
OVPN_NLGRP_PEERS, GFP_ATOMIC);
12231223
rcu_read_unlock();
12241224

12251225
return 0;

drivers/net/ovpn/peer.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1145,7 +1145,7 @@ static void ovpn_peer_release_p2p(struct ovpn_priv *ovpn, struct sock *sk,
11451145

11461146
if (sk) {
11471147
ovpn_sock = rcu_access_pointer(peer->sock);
1148-
if (!ovpn_sock || ovpn_sock->sock->sk != sk) {
1148+
if (!ovpn_sock || ovpn_sock->sk != sk) {
11491149
spin_unlock_bh(&ovpn->lock);
11501150
ovpn_peer_put(peer);
11511151
return;
@@ -1175,7 +1175,7 @@ static void ovpn_peers_release_mp(struct ovpn_priv *ovpn, struct sock *sk,
11751175
if (sk) {
11761176
rcu_read_lock();
11771177
ovpn_sock = rcu_dereference(peer->sock);
1178-
remove = ovpn_sock && ovpn_sock->sock->sk == sk;
1178+
remove = ovpn_sock && ovpn_sock->sk == sk;
11791179
rcu_read_unlock();
11801180
}
11811181

drivers/net/ovpn/socket.c

Lines changed: 38 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,9 @@ static void ovpn_socket_release_kref(struct kref *kref)
2424
struct ovpn_socket *sock = container_of(kref, struct ovpn_socket,
2525
refcount);
2626

27-
if (sock->sock->sk->sk_protocol == IPPROTO_UDP)
27+
if (sock->sk->sk_protocol == IPPROTO_UDP)
2828
ovpn_udp_socket_detach(sock);
29-
else if (sock->sock->sk->sk_protocol == IPPROTO_TCP)
29+
else if (sock->sk->sk_protocol == IPPROTO_TCP)
3030
ovpn_tcp_socket_detach(sock);
3131
}
3232

@@ -75,37 +75,31 @@ void ovpn_socket_release(struct ovpn_peer *peer)
7575
if (!sock)
7676
return;
7777

78-
/* sanity check: we should not end up here if the socket
79-
* was already closed
80-
*/
81-
if (!sock->sock->sk) {
82-
DEBUG_NET_WARN_ON_ONCE(1);
83-
return;
84-
}
85-
8678
/* Drop the reference while holding the sock lock to avoid
8779
* concurrent ovpn_socket_new call to mess up with a partially
8880
* detached socket.
8981
*
9082
* Holding the lock ensures that a socket with refcnt 0 is fully
9183
* detached before it can be picked by a concurrent reader.
9284
*/
93-
lock_sock(sock->sock->sk);
85+
lock_sock(sock->sk);
9486
released = ovpn_socket_put(peer, sock);
95-
release_sock(sock->sock->sk);
87+
release_sock(sock->sk);
9688

9789
/* align all readers with sk_user_data being NULL */
9890
synchronize_rcu();
9991

10092
/* following cleanup should happen with lock released */
10193
if (released) {
102-
if (sock->sock->sk->sk_protocol == IPPROTO_UDP) {
94+
if (sock->sk->sk_protocol == IPPROTO_UDP) {
10395
netdev_put(sock->ovpn->dev, &sock->dev_tracker);
104-
} else if (sock->sock->sk->sk_protocol == IPPROTO_TCP) {
96+
} else if (sock->sk->sk_protocol == IPPROTO_TCP) {
10597
/* wait for TCP jobs to terminate */
10698
ovpn_tcp_socket_wait_finish(sock);
10799
ovpn_peer_put(sock->peer);
108100
}
101+
/* drop reference acquired in ovpn_socket_new() */
102+
sock_put(sock->sk);
109103
/* we can call plain kfree() because we already waited one RCU
110104
* period due to synchronize_rcu()
111105
*/
@@ -118,12 +112,14 @@ static bool ovpn_socket_hold(struct ovpn_socket *sock)
118112
return kref_get_unless_zero(&sock->refcount);
119113
}
120114

121-
static int ovpn_socket_attach(struct ovpn_socket *sock, struct ovpn_peer *peer)
115+
static int ovpn_socket_attach(struct ovpn_socket *ovpn_sock,
116+
struct socket *sock,
117+
struct ovpn_peer *peer)
122118
{
123-
if (sock->sock->sk->sk_protocol == IPPROTO_UDP)
124-
return ovpn_udp_socket_attach(sock, peer->ovpn);
125-
else if (sock->sock->sk->sk_protocol == IPPROTO_TCP)
126-
return ovpn_tcp_socket_attach(sock, peer);
119+
if (sock->sk->sk_protocol == IPPROTO_UDP)
120+
return ovpn_udp_socket_attach(ovpn_sock, sock, peer->ovpn);
121+
else if (sock->sk->sk_protocol == IPPROTO_TCP)
122+
return ovpn_tcp_socket_attach(ovpn_sock, peer);
127123

128124
return -EOPNOTSUPP;
129125
}
@@ -138,23 +134,24 @@ static int ovpn_socket_attach(struct ovpn_socket *sock, struct ovpn_peer *peer)
138134
struct ovpn_socket *ovpn_socket_new(struct socket *sock, struct ovpn_peer *peer)
139135
{
140136
struct ovpn_socket *ovpn_sock;
137+
struct sock *sk = sock->sk;
141138
int ret;
142139

143-
lock_sock(sock->sk);
140+
lock_sock(sk);
144141

145142
/* a TCP socket can only be owned by a single peer, therefore there
146143
* can't be any other user
147144
*/
148-
if (sock->sk->sk_protocol == IPPROTO_TCP && sock->sk->sk_user_data) {
145+
if (sk->sk_protocol == IPPROTO_TCP && sk->sk_user_data) {
149146
ovpn_sock = ERR_PTR(-EBUSY);
150147
goto sock_release;
151148
}
152149

153150
/* a UDP socket can be shared across multiple peers, but we must make
154151
* sure it is not owned by something else
155152
*/
156-
if (sock->sk->sk_protocol == IPPROTO_UDP) {
157-
u8 type = READ_ONCE(udp_sk(sock->sk)->encap_type);
153+
if (sk->sk_protocol == IPPROTO_UDP) {
154+
u8 type = READ_ONCE(udp_sk(sk)->encap_type);
158155

159156
/* socket owned by other encapsulation module */
160157
if (type && type != UDP_ENCAP_OVPNINUDP) {
@@ -163,7 +160,7 @@ struct ovpn_socket *ovpn_socket_new(struct socket *sock, struct ovpn_peer *peer)
163160
}
164161

165162
rcu_read_lock();
166-
ovpn_sock = rcu_dereference_sk_user_data(sock->sk);
163+
ovpn_sock = rcu_dereference_sk_user_data(sk);
167164
if (ovpn_sock) {
168165
/* socket owned by another ovpn instance, we can't use it */
169166
if (ovpn_sock->ovpn != peer->ovpn) {
@@ -200,11 +197,22 @@ struct ovpn_socket *ovpn_socket_new(struct socket *sock, struct ovpn_peer *peer)
200197
goto sock_release;
201198
}
202199

203-
ovpn_sock->sock = sock;
200+
ovpn_sock->sk = sk;
204201
kref_init(&ovpn_sock->refcount);
205202

206-
ret = ovpn_socket_attach(ovpn_sock, peer);
203+
/* the newly created ovpn_socket is holding reference to sk,
204+
* therefore we increase its refcounter.
205+
*
206+
* This ovpn_socket instance is referenced by all peers
207+
* using the same socket.
208+
*
209+
* ovpn_socket_release() will take care of dropping the reference.
210+
*/
211+
sock_hold(sk);
212+
213+
ret = ovpn_socket_attach(ovpn_sock, sock, peer);
207214
if (ret < 0) {
215+
sock_put(sk);
208216
kfree(ovpn_sock);
209217
ovpn_sock = ERR_PTR(ret);
210218
goto sock_release;
@@ -213,11 +221,11 @@ struct ovpn_socket *ovpn_socket_new(struct socket *sock, struct ovpn_peer *peer)
213221
/* TCP sockets are per-peer, therefore they are linked to their unique
214222
* peer
215223
*/
216-
if (sock->sk->sk_protocol == IPPROTO_TCP) {
224+
if (sk->sk_protocol == IPPROTO_TCP) {
217225
INIT_WORK(&ovpn_sock->tcp_tx_work, ovpn_tcp_tx_work);
218226
ovpn_sock->peer = peer;
219227
ovpn_peer_hold(peer);
220-
} else if (sock->sk->sk_protocol == IPPROTO_UDP) {
228+
} else if (sk->sk_protocol == IPPROTO_UDP) {
221229
/* in UDP we only link the ovpn instance since the socket is
222230
* shared among multiple peers
223231
*/
@@ -226,8 +234,8 @@ struct ovpn_socket *ovpn_socket_new(struct socket *sock, struct ovpn_peer *peer)
226234
GFP_KERNEL);
227235
}
228236

229-
rcu_assign_sk_user_data(sock->sk, ovpn_sock);
237+
rcu_assign_sk_user_data(sk, ovpn_sock);
230238
sock_release:
231-
release_sock(sock->sk);
239+
release_sock(sk);
232240
return ovpn_sock;
233241
}

drivers/net/ovpn/socket.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ struct ovpn_peer;
2222
* @ovpn: ovpn instance owning this socket (UDP only)
2323
* @dev_tracker: reference tracker for associated dev (UDP only)
2424
* @peer: unique peer transmitting over this socket (TCP only)
25-
* @sock: the low level sock object
25+
* @sk: the low level sock object
2626
* @refcount: amount of contexts currently referencing this object
2727
* @work: member used to schedule release routine (it may block)
2828
* @tcp_tx_work: work for deferring outgoing packet processing (TCP only)
@@ -36,7 +36,7 @@ struct ovpn_socket {
3636
struct ovpn_peer *peer;
3737
};
3838

39-
struct socket *sock;
39+
struct sock *sk;
4040
struct kref refcount;
4141
struct work_struct work;
4242
struct work_struct tcp_tx_work;

0 commit comments

Comments
 (0)