Skip to content

Commit 8afa10c

Browse files
Nogah Frankeldavem330
authored andcommitted
net_sched: red: Avoid illegal values
Check the qmin & qmax values doesn't overflow for the given Wlog value. Check that qmin <= qmax. Fixes: a783474 ("[PKT_SCHED]: Generic RED layer") Signed-off-by: Nogah Frankel <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 5c47220 commit 8afa10c

File tree

5 files changed

+22
-0
lines changed

5 files changed

+22
-0
lines changed

include/net/red.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,17 @@ static inline void red_set_vars(struct red_vars *v)
168168
v->qcount = -1;
169169
}
170170

171+
static inline bool red_check_params(u32 qth_min, u32 qth_max, u8 Wlog)
172+
{
173+
if (fls(qth_min) + Wlog > 32)
174+
return false;
175+
if (fls(qth_max) + Wlog > 32)
176+
return false;
177+
if (qth_max < qth_min)
178+
return false;
179+
return true;
180+
}
181+
171182
static inline void red_set_parms(struct red_parms *p,
172183
u32 qth_min, u32 qth_max, u8 Wlog, u8 Plog,
173184
u8 Scell_log, u8 *stab, u32 max_P)

net/sched/sch_choke.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -369,6 +369,9 @@ static int choke_change(struct Qdisc *sch, struct nlattr *opt)
369369

370370
ctl = nla_data(tb[TCA_CHOKE_PARMS]);
371371

372+
if (!red_check_params(ctl->qth_min, ctl->qth_max, ctl->Wlog))
373+
return -EINVAL;
374+
372375
if (ctl->limit > CHOKE_MAX_QUEUE)
373376
return -EINVAL;
374377

net/sched/sch_gred.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -356,6 +356,9 @@ static inline int gred_change_vq(struct Qdisc *sch, int dp,
356356
struct gred_sched *table = qdisc_priv(sch);
357357
struct gred_sched_data *q = table->tab[dp];
358358

359+
if (!red_check_params(ctl->qth_min, ctl->qth_max, ctl->Wlog))
360+
return -EINVAL;
361+
359362
if (!q) {
360363
table->tab[dp] = q = *prealloc;
361364
*prealloc = NULL;

net/sched/sch_red.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -212,6 +212,8 @@ static int red_change(struct Qdisc *sch, struct nlattr *opt)
212212
max_P = tb[TCA_RED_MAX_P] ? nla_get_u32(tb[TCA_RED_MAX_P]) : 0;
213213

214214
ctl = nla_data(tb[TCA_RED_PARMS]);
215+
if (!red_check_params(ctl->qth_min, ctl->qth_max, ctl->Wlog))
216+
return -EINVAL;
215217

216218
if (ctl->limit > 0) {
217219
child = fifo_create_dflt(sch, &bfifo_qdisc_ops, ctl->limit);

net/sched/sch_sfq.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -639,6 +639,9 @@ static int sfq_change(struct Qdisc *sch, struct nlattr *opt)
639639
if (ctl->divisor &&
640640
(!is_power_of_2(ctl->divisor) || ctl->divisor > 65536))
641641
return -EINVAL;
642+
if (ctl_v1 && !red_check_params(ctl_v1->qth_min, ctl_v1->qth_max,
643+
ctl_v1->Wlog))
644+
return -EINVAL;
642645
if (ctl_v1 && ctl_v1->qth_min) {
643646
p = kmalloc(sizeof(*p), GFP_KERNEL);
644647
if (!p)

0 commit comments

Comments
 (0)