[PATCH net] net: qualcomm: rmnet: bound TX aggregates on byte-limit update
From: Jérémy Jean
Date: Sat Oct 31 2026 - 18:11:35 EST
If userspace reduces the TX aggregation byte limit while a buffered skb
is pending, subtracting the skb length from the new limit underflows.
The later comparison with unsigned skb->len then lets the buffered skb
grow past the limit.
Check lengths before subtracting. Flush a buffered skb if it is already
at or above the new byte limit.
Fixes: 64b5d1f8f2d1 ("net: qualcomm: rmnet: add tx packets aggregation")
Cc: stable@xxxxxxxxxxxxxxx
Signed-off-by: Jérémy Jean <Jeremy.Jean@xxxxxxxxxxxxxxxxx>
---
drivers/net/ethernet/qualcomm/rmnet/rmnet_map_data.c | 12 ++++++------
1 file changed, 6 insertions(+), 6 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..205ac81f2c82 100644
--- a/drivers/net/ethernet/qualcomm/rmnet/rmnet_map_data.c
+++ b/drivers/net/ethernet/qualcomm/rmnet/rmnet_map_data.c
@@ -594,7 +594,7 @@ unsigned int rmnet_map_tx_aggregate(struct sk_buff *skb, struct rmnet_port *port
struct timespec64 diff, last;
unsigned int len = skb->len;
struct sk_buff *agg_skb;
- int size;
+ unsigned int size;
spin_lock_bh(&port->agg_lock);
memcpy(&last, &port->agg_last, sizeof(struct timespec64));
@@ -606,13 +606,14 @@ unsigned int rmnet_map_tx_aggregate(struct sk_buff *skb, struct rmnet_port *port
*/
new_packet:
diff = timespec64_sub(port->agg_last, last);
- size = port->egress_agg_params.bytes - skb->len;
+ size = port->egress_agg_params.bytes;
- if (size < 0) {
+ if (skb->len > size) {
/* dropped */
spin_unlock_bh(&port->agg_lock);
return 0;
}
+ size -= skb->len;
if (diff.tv_sec > 0 || diff.tv_nsec > RMNET_AGG_BYPASS_TIME_NSEC ||
size == 0)
@@ -630,9 +631,8 @@ unsigned int rmnet_map_tx_aggregate(struct sk_buff *skb, struct rmnet_port *port
goto schedule;
}
diff = timespec64_sub(port->agg_last, port->agg_time);
- size = port->egress_agg_params.bytes - port->skbagg_head->len;
-
- if (skb->len > size) {
+ if (port->skbagg_head->len >= port->egress_agg_params.bytes ||
+ skb->len > port->egress_agg_params.bytes - port->skbagg_head->len) {
agg_skb = port->skbagg_head;
reset_aggr_params(port);
spin_unlock_bh(&port->agg_lock);
--
2.47.3