[Openvpn-devel,ovpn,net,2/3] ovpn: fix VPN TX bytes counting

Message ID 20260119131400.424161-2-ralf@mandelbit.com
State New
Headers show
Series [Openvpn-devel,ovpn,net,1/3] ovpn: set sk_user_data before overriding callbacks | expand

Commit Message

Ralf Lici Jan. 19, 2026, 1:13 p.m. UTC
In ovpn_net_xmit, after GSO segmentation, skb points to the head of a
list of segments. The current code uses skb->len to increment VPN TX
statistics, but this only accounts for the first segment's length,
ignoring all subsequent segments.

More critically, if the first segment fails skb_share_check, the skb is
freed but the pointer remains. The subsequent skb->len access results in
a use-after-free.

Fix both issues by accumulating the length of each segment that
successfully passes skb_share_check and is queued for transmission.

Signed-off-by: Ralf Lici <ralf@mandelbit.com>
---
 drivers/net/ovpn/io.c | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

Patch

diff --git a/drivers/net/ovpn/io.c b/drivers/net/ovpn/io.c
index 3e9e7f8444b3..c59501344d97 100644
--- a/drivers/net/ovpn/io.c
+++ b/drivers/net/ovpn/io.c
@@ -355,6 +355,7 @@  netdev_tx_t ovpn_net_xmit(struct sk_buff *skb, struct net_device *dev)
 	struct ovpn_priv *ovpn = netdev_priv(dev);
 	struct sk_buff *segments, *curr, *next;
 	struct sk_buff_head skb_list;
+	unsigned int tx_bytes = 0;
 	struct ovpn_peer *peer;
 	__be16 proto;
 	int ret;
@@ -394,6 +395,8 @@  netdev_tx_t ovpn_net_xmit(struct sk_buff *skb, struct net_device *dev)
 			continue;
 		}
 
+		/* only count what we actually send */
+		tx_bytes += curr->len;
 		__skb_queue_tail(&skb_list, curr);
 	}
 	skb_list.prev->next = NULL;
@@ -418,7 +421,7 @@  netdev_tx_t ovpn_net_xmit(struct sk_buff *skb, struct net_device *dev)
 	/* dst was needed for peer selection - it can now be dropped */
 	skb_dst_drop(skb);
 
-	ovpn_peer_stats_increment_tx(&peer->vpn_stats, skb->len);
+	ovpn_peer_stats_increment_tx(&peer->vpn_stats, tx_bytes);
 	ovpn_send(ovpn, skb_list.next, peer);
 
 	return NETDEV_TX_OK;