packet_time_ns() calculates transmission time for netem rate shaping. It adds q->packet_overhead (signed 32-bit int) to len (unsigned 64-bit int). When userspace configures a negative packet overhead (via TCA_NETEM_RATE packet_overhead attribute) and an enqueued packet's length is smaller than the absolute overhead, (s64)len + q->packet_overhead is negative. Because len is u64, the addition wraps into an astronomical value (~2^64 - 1). When multiplied by NSEC_PER_SEC and divided by q->rate, the calculated delay spans hours or days, causing enqueued packets to be frozen in the qdisc indefinitely and stalling transmission. A similar underflow can occur in cell length calculation when (q->cell_size + q->cell_overhead) is non-positive. Clamp the effective packet length to 0 if the overhead adjustment would underflow, and return 0 delay if effective cell length is non-positive, matching the behavior in sch_cake and sch_tbf. Fixes: 7bc0f28c7a0c ("netem: rate extension") Cc: stable@vger.kernel.org Signed-off-by: Bui Viet Dung --- net/sched/sch_netem.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/net/sched/sch_netem.c b/net/sched/sch_netem.c index 8a1b89a289d..a3dcd33bec4 100644 --- a/net/sched/sch_netem.c +++ b/net/sched/sch_netem.c @@ -366,14 +366,20 @@ static s64 tabledist(s64 mu, s32 sigma, static u64 packet_time_ns(u64 len, const struct netem_sched_data *q) { + if ((s64)len + q->packet_overhead <= 0) + return 0; + len += q->packet_overhead; if (q->cell_size) { u32 cells = reciprocal_divide(len, q->cell_size_reciprocal); + s32 cell_len = (s32)q->cell_size + q->cell_overhead; if (len > cells * q->cell_size) /* extra cell needed for remainder */ cells++; - len = cells * (q->cell_size + q->cell_overhead); + if (cell_len <= 0) + return 0; + len = (u64)cells * cell_len; } return div64_u64(len * NSEC_PER_SEC, q->rate); -- 2.43.0