Re: [PATCH net] net: sched: gred: fix 32-bit backlog wrap in gred_enqueue

Jamal Hadi Salim <[email protected]>
Newsgroups gmane.linux.kernel.stable,gmane.linux.network
Message-ID <CAM0EoM=6zZVucSOUDi7pJiGhkoeTJ-PN9M18DnPWSpfH4GP6=A@mail.gmail.com>
On Sun, Aug 9, 2026 at 5:43 AM Zhan Xusheng <[email protected]> wrote:
>
> On Sun,  9 Aug 2026 05:16:57 -0400, Jamal Hadi Salim wrote:
> > -     if (likely(sch->qstats.backlog + qdisc_pkt_len(skb) <=
> > +     if (likely((u64)sch->qstats.backlog + qdisc_pkt_len(skb) <=
> >                   sch->limit))
>
> bfifo_enqueue() in net/sched/sch_fifo.c has the same expression, and this
> patch does not touch it:
>
>         if (likely(sch->qstats.backlog + qdisc_pkt_len(skb) <=
>                    READ_ONCE(sch->limit)))
>
> Same u32 backlog, same unsigned int length.  sch->limit comes from
> tc_fifo_qopt.limit, a __u32 documented as "bytes for bfifo", and nothing
> caps it on the way in -- both .init and .change are fifo_init(), which
> stores ctl->limit directly.
>

Looking at the code, I can confirm you are correct. I notice also plug
and sfq have a similar issue.

> The gred check is the newer of the two: it came in with a3eb95f891d6,
> the commit in your Fixes tag, while the bfifo one goes back to the
> initial git import, so there is no useful Fixes: tag for it.
>
> bfifo also has more ways in than gred.  sch_red.c and sch_tbf.c install a
> bfifo child through fifo_create_dflt() -> fifo_set_limit(), passing
> ctl->limit and qopt->limit straight from userspace; tc_red_qopt.limit is
> likewise documented as bytes.  Since this is heading to stable, fixing
> gred alone leaves those paths unchanged.
>

I should have paid closer attention instead of focussing on the bug report.
Since i already submitted, we can wait to see sashiko says - if
requires an update i can include the others; otherwise it will have to
be a followup patch.

cheers,
jamal

> Minor, and in the other direction: __fifo_init() does
>
>         u32 limit = qdisc_dev(sch)->tx_queue_len;
>
>         if (is_bfifo)
>                 limit *= psched_mtu(qdisc_dev(sch));
>
> which also wraps in 32 bits, but fails safe -- the result stays below
> 2^32, so the limit ends up smaller than intended rather than unbounded.
>
> Thanks,
> Zhan Xusheng
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.