From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-cys01nam02on0101.outbound.protection.outlook.com ([104.47.37.101]:53605 "EHLO NAM02-CY1-obe.outbound.protection.outlook.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S966898AbeCSQOF (ORCPT ); Mon, 19 Mar 2018 12:14:05 -0400 From: Sasha Levin To: "linux-kernel@vger.kernel.org" , "stable@vger.kernel.org" CC: Talat Batheesh , Tariq Toukan , "David S . Miller" , Sasha Levin Subject: [PATCH AUTOSEL for 3.18 070/102] net/mlx4: Fix the check in attaching steering rules Date: Mon, 19 Mar 2018 16:12:57 +0000 Message-ID: <20180319161117.17833-70-alexander.levin@microsoft.com> References: <20180319161117.17833-1-alexander.levin@microsoft.com> In-Reply-To: <20180319161117.17833-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: Talat Batheesh [ Upstream commit 6dc06c08bef1c746ff8da33dab677cfbacdcad32 ] Our previous patch (cited below) introduced a regression for RAW Eth QPs. Fix it by checking if the QP number provided by user-space exists, hence allowing steering rules to be added for valid QPs only. Fixes: 89c557687a32 ("net/mlx4_en: Avoid adding steering rules with invalid= ring") Reported-by: Or Gerlitz Signed-off-by: Talat Batheesh Signed-off-by: Tariq Toukan Acked-by: Or Gerlitz Reviewed-by: Leon Romanovsky Signed-off-by: David S. Miller Signed-off-by: Sasha Levin --- drivers/net/ethernet/mellanox/mlx4/en_ethtool.c | 5 ----- drivers/net/ethernet/mellanox/mlx4/mcg.c | 15 +++++++++++---- drivers/net/ethernet/mellanox/mlx4/qp.c | 13 +++++++++++++ include/linux/mlx4/qp.h | 1 + 4 files changed, 25 insertions(+), 9 deletions(-) diff --git a/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c b/drivers/net/= ethernet/mellanox/mlx4/en_ethtool.c index 17b3950e04a7..ae83da9cd18a 100644 --- a/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c +++ b/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c @@ -946,11 +946,6 @@ static int mlx4_en_flow_replace(struct net_device *dev= , qpn =3D priv->drop_qp.qpn; else if (cmd->fs.ring_cookie & EN_ETHTOOL_QP_ATTACH) { qpn =3D cmd->fs.ring_cookie & (EN_ETHTOOL_QP_ATTACH - 1); - if (qpn < priv->rss_map.base_qpn || - qpn >=3D priv->rss_map.base_qpn + priv->rx_ring_num) { - en_warn(priv, "rxnfc: QP (0x%x) doesn't exist\n", qpn); - return -EINVAL; - } } else { if (cmd->fs.ring_cookie >=3D priv->rx_ring_num) { en_warn(priv, "rxnfc: RX ring (%llu) doesn't exist\n", diff --git a/drivers/net/ethernet/mellanox/mlx4/mcg.c b/drivers/net/etherne= t/mellanox/mlx4/mcg.c index 872843179f44..c704e7bcda9d 100644 --- a/drivers/net/ethernet/mellanox/mlx4/mcg.c +++ b/drivers/net/ethernet/mellanox/mlx4/mcg.c @@ -35,6 +35,7 @@ #include =20 #include +#include #include =20 #include "mlx4.h" @@ -985,16 +986,21 @@ int mlx4_flow_attach(struct mlx4_dev *dev, if (IS_ERR(mailbox)) return PTR_ERR(mailbox); =20 + if (!mlx4_qp_lookup(dev, rule->qpn)) { + mlx4_err_rule(dev, "QP doesn't exist\n", rule); + ret =3D -EINVAL; + goto out; + } + trans_rule_ctrl_to_hw(rule, mailbox->buf); =20 size +=3D sizeof(struct mlx4_net_trans_rule_hw_ctrl); =20 list_for_each_entry(cur, &rule->list, list) { ret =3D parse_trans_rule(dev, cur, mailbox->buf + size); - if (ret < 0) { - mlx4_free_cmd_mailbox(dev, mailbox); - return ret; - } + if (ret < 0) + goto out; + size +=3D ret; } =20 @@ -1006,6 +1012,7 @@ int mlx4_flow_attach(struct mlx4_dev *dev, else if (ret) mlx4_err_rule(dev, "Fail to register network rule\n", rule); =20 +out: mlx4_free_cmd_mailbox(dev, mailbox); =20 return ret; diff --git a/drivers/net/ethernet/mellanox/mlx4/qp.c b/drivers/net/ethernet= /mellanox/mlx4/qp.c index b295eeb2af69..87e00742d401 100644 --- a/drivers/net/ethernet/mellanox/mlx4/qp.c +++ b/drivers/net/ethernet/mellanox/mlx4/qp.c @@ -358,6 +358,19 @@ static void mlx4_qp_free_icm(struct mlx4_dev *dev, int= qpn) __mlx4_qp_free_icm(dev, qpn); } =20 +struct mlx4_qp *mlx4_qp_lookup(struct mlx4_dev *dev, u32 qpn) +{ + struct mlx4_qp_table *qp_table =3D &mlx4_priv(dev)->qp_table; + struct mlx4_qp *qp; + + spin_lock(&qp_table->lock); + + qp =3D __mlx4_qp_lookup(dev, qpn); + + spin_unlock(&qp_table->lock); + return qp; +} + int mlx4_qp_alloc(struct mlx4_dev *dev, int qpn, struct mlx4_qp *qp, gfp_t= gfp) { struct mlx4_priv *priv =3D mlx4_priv(dev); diff --git a/include/linux/mlx4/qp.h b/include/linux/mlx4/qp.h index 5f4e36cf0091..30a73892a8d6 100644 --- a/include/linux/mlx4/qp.h +++ b/include/linux/mlx4/qp.h @@ -437,6 +437,7 @@ struct mlx4_update_qp_params { u32 flags; }; =20 +struct mlx4_qp *mlx4_qp_lookup(struct mlx4_dev *dev, u32 qpn); int mlx4_update_qp(struct mlx4_dev *dev, u32 qpn, enum mlx4_update_qp_attr attr, struct mlx4_update_qp_params *params); --=20 2.14.1