summaryrefslogtreecommitdiffstats
path: root/net/sched
diff options
context:
space:
mode:
authorEric Dumazet <edumazet@google.com>2020-04-26 18:19:07 -0700
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2020-05-20 08:16:54 +0200
commit9945949908fe11b27fa1127d2fc9e3182c218312 (patch)
treedd97567adc006150ff70cd94df49c88237def7e7 /net/sched
parent4836eb6b59657a383fa97d3d301da77581ec8f0c (diff)
downloadlinux-stable-9945949908fe11b27fa1127d2fc9e3182c218312.tar.gz
linux-stable-9945949908fe11b27fa1127d2fc9e3182c218312.tar.bz2
linux-stable-9945949908fe11b27fa1127d2fc9e3182c218312.zip
sch_sfq: validate silly quantum values
[ Upstream commit df4953e4e997e273501339f607b77953772e3559 ] syzbot managed to set up sfq so that q->scaled_quantum was zero, triggering an infinite loop in sfq_dequeue() More generally, we must only accept quantum between 1 and 2^18 - 7, meaning scaled_quantum must be in [1, 0x7FFF] range. Otherwise, we also could have a loop in sfq_dequeue() if scaled_quantum happens to be 0x8000, since slot->allot could indefinitely switch between 0 and 0x8000. Fixes: eeaeb068f139 ("sch_sfq: allow big packets and be fair") Signed-off-by: Eric Dumazet <edumazet@google.com> Reported-by: syzbot+0251e883fe39e7a0cb0a@syzkaller.appspotmail.com Cc: Jason A. Donenfeld <Jason@zx2c4.com> Signed-off-by: David S. Miller <davem@davemloft.net> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'net/sched')
-rw-r--r--net/sched/sch_sfq.c9
1 files changed, 9 insertions, 0 deletions
diff --git a/net/sched/sch_sfq.c b/net/sched/sch_sfq.c
index cbc54ddfe076..1eae4de319b3 100644
--- a/net/sched/sch_sfq.c
+++ b/net/sched/sch_sfq.c
@@ -639,6 +639,15 @@ static int sfq_change(struct Qdisc *sch, struct nlattr *opt)
if (ctl->divisor &&
(!is_power_of_2(ctl->divisor) || ctl->divisor > 65536))
return -EINVAL;
+
+ /* slot->allot is a short, make sure quantum is not too big. */
+ if (ctl->quantum) {
+ unsigned int scaled = SFQ_ALLOT_SIZE(ctl->quantum);
+
+ if (scaled <= 0 || scaled > SHRT_MAX)
+ return -EINVAL;
+ }
+
if (ctl_v1 && !red_check_params(ctl_v1->qth_min, ctl_v1->qth_max,
ctl_v1->Wlog))
return -EINVAL;