2025-01-13, 10:31:31 +0100, Antonio Quartulli wrote:
+static void ovpn_tcp_rcv(struct strparser *strp, struct sk_buff *skb)[...]
+{
+ /* we need the first byte of data to be accessible
+ * to extract the opcode and the key ID later on
+ */
+ if (!pskb_may_pull(skb, 1)) {
make sure we have 1B...
+ net_warn_ratelimited("%s: packet too small to fetch opcode for peer %u\n",
+ netdev_name(peer->ovpn->dev), peer->id);
+ goto err;
+ }
+
+ /* DATA_V2 packets are handled in kernel, the rest goes to user space */
+ opcode = ovpn_opcode_from_skb(skb, 0);
but this reads a u32 (4B) from skb->data
[...]
+void ovpn_tcp_socket_detach(struct ovpn_socket *ovpn_sock)
+{
+ struct ovpn_peer *peer = ovpn_sock->peer;
+ struct socket *sock = ovpn_sock->sock;
+
+ strp_stop(&peer->tcp.strp);
+
+ skb_queue_purge(&peer->tcp.user_queue);
+ /* restore CBs that were saved in ovpn_sock_set_tcp_cb() */
+ sock->sk->sk_data_ready = peer->tcp.sk_cb.sk_data_ready;
+ sock->sk->sk_write_space = peer->tcp.sk_cb.sk_write_space;
+ sock->sk->sk_prot = peer->tcp.sk_cb.prot;
+ sock->sk->sk_socket->ops = peer->tcp.sk_cb.ops;
+
+ /* drop reference to peer */
nit: not really :)
+ rcu_assign_sk_user_data(sock->sk, NULL);
+
+ /* before canceling any ongoing work we must ensure that CBs
+ * have been reset to prevent workers from being re-armed
+ */
+ barrier();
+
+ cancel_work_sync(&peer->tcp.tx_work);
+ strp_done(&peer->tcp.strp);
+ skb_queue_purge(&peer->tcp.out_queue);
Also kfree_skb(peer->tcp.out_msg.skb)?
+ ovpn_peer_put(peer);
+}
[...]
+static int ovpn_tcp_sendmsg(struct sock *sk, struct msghdr *msg, size_t size)[...]
+{
+ ret = skb_copy_datagram_from_iter(skb, 0, &msg->msg_iter, size);
+ if (ret) {
+ kfree_skb(skb);
+ net_err_ratelimited("%s: skb copy from iter failed: %d\n",
+ netdev_name(sock->peer->ovpn->dev), ret);
+ goto peer_free;
+ }
+
+ ovpn_tcp_send_sock_skb(sock->peer, skb);
This isn't propagating MSG_DONTWAIT down to ovpn_tcp_send_sock?