From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-co1nam03on0111.outbound.protection.outlook.com ([104.47.40.111]:36928 "EHLO NAM03-CO1-obe.outbound.protection.outlook.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1753361AbeA1W1F (ORCPT ); Sun, 28 Jan 2018 17:27:05 -0500 From: Sasha Levin To: "linux-kernel@vger.kernel.org" , "stable@vger.kernel.org" CC: Nogah Frankel , "David S . Miller" , Sasha Levin Subject: [PATCH AUTOSEL for 4.14 055/100] net_sched: red: Avoid illegal values Date: Sun, 28 Jan 2018 22:26:34 +0000 Message-ID: <20180128222547.7398-55-alexander.levin@microsoft.com> References: <20180128222547.7398-1-alexander.levin@microsoft.com> In-Reply-To: <20180128222547.7398-1-alexander.levin@microsoft.com> Content-Language: en-US Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Sender: stable-owner@vger.kernel.org List-ID: From: Nogah Frankel [ Upstream commit 8afa10cbe281b10371fee5a87ab266e48d71a7f9 ] Check the qmin & qmax values doesn't overflow for the given Wlog value. Check that qmin <=3D qmax. Fixes: a783474591f2 ("[PKT_SCHED]: Generic RED layer") Signed-off-by: Nogah Frankel Signed-off-by: David S. Miller Signed-off-by: Sasha Levin --- include/net/red.h | 11 +++++++++++ net/sched/sch_choke.c | 3 +++ net/sched/sch_gred.c | 3 +++ net/sched/sch_red.c | 2 ++ net/sched/sch_sfq.c | 3 +++ 5 files changed, 22 insertions(+) diff --git a/include/net/red.h b/include/net/red.h index 5918f78d36a0..9665582c4687 100644 --- a/include/net/red.h +++ b/include/net/red.h @@ -168,6 +168,17 @@ static inline void red_set_vars(struct red_vars *v) v->qcount =3D -1; } =20 +static inline bool red_check_params(u32 qth_min, u32 qth_max, u8 Wlog) +{ + if (fls(qth_min) + Wlog > 32) + return false; + if (fls(qth_max) + Wlog > 32) + return false; + if (qth_max < qth_min) + return false; + return true; +} + static inline void red_set_parms(struct red_parms *p, u32 qth_min, u32 qth_max, u8 Wlog, u8 Plog, u8 Scell_log, u8 *stab, u32 max_P) diff --git a/net/sched/sch_choke.c b/net/sched/sch_choke.c index b30a2c70bd48..531250fceb9e 100644 --- a/net/sched/sch_choke.c +++ b/net/sched/sch_choke.c @@ -369,6 +369,9 @@ static int choke_change(struct Qdisc *sch, struct nlatt= r *opt) =20 ctl =3D nla_data(tb[TCA_CHOKE_PARMS]); =20 + if (!red_check_params(ctl->qth_min, ctl->qth_max, ctl->Wlog)) + return -EINVAL; + if (ctl->limit > CHOKE_MAX_QUEUE) return -EINVAL; =20 diff --git a/net/sched/sch_gred.c b/net/sched/sch_gred.c index 17c7130454bd..bc30f9186ac6 100644 --- a/net/sched/sch_gred.c +++ b/net/sched/sch_gred.c @@ -356,6 +356,9 @@ static inline int gred_change_vq(struct Qdisc *sch, int= dp, struct gred_sched *table =3D qdisc_priv(sch); struct gred_sched_data *q =3D table->tab[dp]; =20 + if (!red_check_params(ctl->qth_min, ctl->qth_max, ctl->Wlog)) + return -EINVAL; + if (!q) { table->tab[dp] =3D q =3D *prealloc; *prealloc =3D NULL; diff --git a/net/sched/sch_red.c b/net/sched/sch_red.c index 93b9d70a9b28..d87c41e82917 100644 --- a/net/sched/sch_red.c +++ b/net/sched/sch_red.c @@ -184,6 +184,8 @@ static int red_change(struct Qdisc *sch, struct nlattr = *opt) max_P =3D tb[TCA_RED_MAX_P] ? nla_get_u32(tb[TCA_RED_MAX_P]) : 0; =20 ctl =3D nla_data(tb[TCA_RED_PARMS]); + if (!red_check_params(ctl->qth_min, ctl->qth_max, ctl->Wlog)) + return -EINVAL; =20 if (ctl->limit > 0) { child =3D fifo_create_dflt(sch, &bfifo_qdisc_ops, ctl->limit); diff --git a/net/sched/sch_sfq.c b/net/sched/sch_sfq.c index 74ea863b8240..3fbf20126045 100644 --- a/net/sched/sch_sfq.c +++ b/net/sched/sch_sfq.c @@ -637,6 +637,9 @@ static int sfq_change(struct Qdisc *sch, struct nlattr = *opt) if (ctl->divisor && (!is_power_of_2(ctl->divisor) || ctl->divisor > 65536)) return -EINVAL; + if (ctl_v1 && !red_check_params(ctl_v1->qth_min, ctl_v1->qth_max, + ctl_v1->Wlog)) + return -EINVAL; if (ctl_v1 && ctl_v1->qth_min) { p =3D kmalloc(sizeof(*p), GFP_KERNEL); if (!p) --=20 2.11.0