RE: [PATCH net] net: qualcomm: rmnet: bound TX aggregates on byte-limit update

From: subash.a.kasiviswanathan

Date: Sun Nov 08 2026 - 02:36:44 EST


> -----Original Message-----
> From: Jérémy Jean <Jeremy.Jean@xxxxxxxxxxxxxxxxx>
> Sent: Saturday, October 31, 2026 4:11 PM
> To: Subash Abhinov Kasiviswanathan
> <subash.a.kasiviswanathan@xxxxxxxxxxxxxxxx>; Sean Tranchetti
> <sean.tranchetti@xxxxxxxxxxxxxxxx>
> Cc: netdev@xxxxxxxxxxxxxxx; linux-kernel@xxxxxxxxxxxxxxx; Jérémy Jean
> <Jeremy.Jean@xxxxxxxxxxxxxxxxx>; stable@xxxxxxxxxxxxxxx
> Subject: [PATCH net] net: qualcomm: rmnet: bound TX aggregates on byte-
> limit update
>
> 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

Reviewed-by: Subash Abhinov Kasiviswanathan <subash.a.kasiviswanathan@xxxxxxxxxxxxxxxx>