A struct rmnet_port stores a pointer to the most recently created
RMNET VND in port->rmnet_dev, but userspace can delete that VND while
the port still has another attached VND. When RMNET later sends a
buffered TX skb, a failure in __skb_linearize() makes rmnet_send_skb()
update the drop counter through that stale pointer, which causes a UAF.
Account TX drops on the lower device instead of port->rmnet_dev.
Fixes: 64b5d1f8f2d1 ("net: qualcomm: rmnet: add tx packets aggregation")
Cc: <redacted>
Signed-off-by: Jérémy Jean <redacted>
---
drivers/net/ethernet/qualcomm/rmnet/rmnet_map_data.c | 5 +----
1 file changed, 1 insertion(+), 4 deletions(-)
diff --git a/drivers/net/ethernet/qualcomm/rmnet/rmnet_map_data.c b/drivers/net/ethernet/qualcomm/rmnet/rmnet_map_data.c
index e6f48dc9fe64..4df75f4215fa 100644
--- a/drivers/net/ethernet/qualcomm/rmnet/rmnet_map_data.c
+++ b/drivers/net/ethernet/qualcomm/rmnet/rmnet_map_data.c
@@ -543,10 +543,7 @@ static void rmnet_send_skb(struct rmnet_port *port, struct sk_buff *skb)
{
if (skb_needs_linearize(skb, port->dev->features)) {
if (unlikely(__skb_linearize(skb))) {
- struct rmnet_priv *priv;
-
- priv = netdev_priv(port->rmnet_dev);
- this_cpu_inc(priv->pcpu_stats->stats.tx_drops);
+ dev_core_stats_tx_dropped_inc(port->dev);
dev_kfree_skb_any(skb);
return;
}--
2.47.3