Denis Kirjanov ad0651
From 9209700b1f818bdbcfd9452fc944e6622b22e22e Mon Sep 17 00:00:00 2001
Denis Kirjanov ad0651
From: Manish Chopra <manishc@marvell.com>
Denis Kirjanov ad0651
Date: Wed, 2 Mar 2022 02:52:22 -0800
Denis Kirjanov ad0651
Subject: [PATCH 6/8] qed: validate and restrict untrusted VFs vlan promisc
Denis Kirjanov ad0651
 mode
Denis Kirjanov ad0651
Git-commit: cbcc44db2cf7b836896733acc0e5ea966136ed22
Denis Kirjanov ad0651
Patch-mainline: v5.18-rc1
Denis Kirjanov ad0651
References: git-fixes
Denis Kirjanov ad0651
Denis Kirjanov ad0651
Today when VFs are put in promiscuous mode, they can request PF
Denis Kirjanov ad0651
to configure device for them to receive all VLANs traffic regardless
Denis Kirjanov ad0651
of what vlan is configured by the PF (via ip link) and PF allows this
Denis Kirjanov ad0651
config request regardless of whether VF is trusted or not.
Denis Kirjanov ad0651
Denis Kirjanov ad0651
From security POV, when VLAN is configured for VF through PF (via ip link),
Denis Kirjanov ad0651
honour such config requests from VF only when they are configured to be
Denis Kirjanov ad0651
trusted, otherwise restrict such VFs vlan promisc mode config.
Denis Kirjanov ad0651
Denis Kirjanov ad0651
Cc: stable@vger.kernel.org
Denis Kirjanov ad0651
Fixes: f990c82c385b ("qed*: Add support for ndo_set_vf_trust")
Denis Kirjanov ad0651
Signed-off-by: Manish Chopra <manishc@marvell.com>
Denis Kirjanov ad0651
Signed-off-by: Ariel Elior <aelior@marvell.com>
Denis Kirjanov ad0651
Signed-off-by: David S. Miller <davem@davemloft.net>
Denis Kirjanov ad0651
Signed-off-by: Denis Kirjanov <denis.kirjanov@suse.com>
Denis Kirjanov ad0651
---
Denis Kirjanov ad0651
 drivers/net/ethernet/qlogic/qed/qed_sriov.c | 28 ++++++++++++++++++++++++++--
Denis Kirjanov ad0651
 drivers/net/ethernet/qlogic/qed/qed_sriov.h |  1 +
Denis Kirjanov ad0651
 2 files changed, 27 insertions(+), 2 deletions(-)
Denis Kirjanov ad0651
Denis Kirjanov ad0651
diff --git a/drivers/net/ethernet/qlogic/qed/qed_sriov.c b/drivers/net/ethernet/qlogic/qed/qed_sriov.c
Denis Kirjanov ad0651
index bbc8611c4067..40d9939f4997 100644
Denis Kirjanov ad0651
--- a/drivers/net/ethernet/qlogic/qed/qed_sriov.c
Denis Kirjanov ad0651
+++ b/drivers/net/ethernet/qlogic/qed/qed_sriov.c
Denis Kirjanov ad0651
@@ -3003,12 +3003,16 @@ static int qed_iov_pre_update_vport(struct qed_hwfn *hwfn,
Denis Kirjanov ad0651
 	u8 mask = QED_ACCEPT_UCAST_UNMATCHED | QED_ACCEPT_MCAST_UNMATCHED;
Denis Kirjanov ad0651
 	struct qed_filter_accept_flags *flags = &params->accept_flags;
Denis Kirjanov ad0651
 	struct qed_public_vf_info *vf_info;
Denis Kirjanov ad0651
+	u16 tlv_mask;
Denis Kirjanov ad0651
+
Denis Kirjanov ad0651
+	tlv_mask = BIT(QED_IOV_VP_UPDATE_ACCEPT_PARAM) |
Denis Kirjanov ad0651
+		   BIT(QED_IOV_VP_UPDATE_ACCEPT_ANY_VLAN);
Denis Kirjanov ad0651
 
Denis Kirjanov ad0651
 	/* Untrusted VFs can't even be trusted to know that fact.
Denis Kirjanov ad0651
 	 * Simply indicate everything is configured fine, and trace
Denis Kirjanov ad0651
 	 * configuration 'behind their back'.
Denis Kirjanov ad0651
 	 */
Denis Kirjanov ad0651
-	if (!(*tlvs & BIT(QED_IOV_VP_UPDATE_ACCEPT_PARAM)))
Denis Kirjanov ad0651
+	if (!(*tlvs & tlv_mask))
Denis Kirjanov ad0651
 		return 0;
Denis Kirjanov ad0651
 
Denis Kirjanov ad0651
 	vf_info = qed_iov_get_public_vf_info(hwfn, vfid, true);
Denis Kirjanov ad0651
@@ -3025,6 +3029,13 @@ static int qed_iov_pre_update_vport(struct qed_hwfn *hwfn,
Denis Kirjanov ad0651
 			flags->tx_accept_filter &= ~mask;
Denis Kirjanov ad0651
 	}
Denis Kirjanov ad0651
 
Denis Kirjanov ad0651
+	if (params->update_accept_any_vlan_flg) {
Denis Kirjanov ad0651
+		vf_info->accept_any_vlan = params->accept_any_vlan;
Denis Kirjanov ad0651
+
Denis Kirjanov ad0651
+		if (vf_info->forced_vlan && !vf_info->is_trusted_configured)
Denis Kirjanov ad0651
+			params->accept_any_vlan = false;
Denis Kirjanov ad0651
+	}
Denis Kirjanov ad0651
+
Denis Kirjanov ad0651
 	return 0;
Denis Kirjanov ad0651
 }
Denis Kirjanov ad0651
 
Denis Kirjanov ad0651
@@ -5148,6 +5159,12 @@ static void qed_iov_handle_trust_change(struct qed_hwfn *hwfn)
Denis Kirjanov ad0651
 
Denis Kirjanov ad0651
 		params.update_ctl_frame_check = 1;
Denis Kirjanov ad0651
 		params.mac_chk_en = !vf_info->is_trusted_configured;
Denis Kirjanov ad0651
+		params.update_accept_any_vlan_flg = 0;
Denis Kirjanov ad0651
+
Denis Kirjanov ad0651
+		if (vf_info->accept_any_vlan && vf_info->forced_vlan) {
Denis Kirjanov ad0651
+			params.update_accept_any_vlan_flg = 1;
Denis Kirjanov ad0651
+			params.accept_any_vlan = vf_info->accept_any_vlan;
Denis Kirjanov ad0651
+		}
Denis Kirjanov ad0651
 
Denis Kirjanov ad0651
 		if (vf_info->rx_accept_mode & mask) {
Denis Kirjanov ad0651
 			flags->update_rx_mode_config = 1;
Denis Kirjanov ad0651
@@ -5163,13 +5180,20 @@ static void qed_iov_handle_trust_change(struct qed_hwfn *hwfn)
Denis Kirjanov ad0651
 		if (!vf_info->is_trusted_configured) {
Denis Kirjanov ad0651
 			flags->rx_accept_filter &= ~mask;
Denis Kirjanov ad0651
 			flags->tx_accept_filter &= ~mask;
Denis Kirjanov ad0651
+			params.accept_any_vlan = false;
Denis Kirjanov ad0651
 		}
Denis Kirjanov ad0651
 
Denis Kirjanov ad0651
 		if (flags->update_rx_mode_config ||
Denis Kirjanov ad0651
 		    flags->update_tx_mode_config ||
Denis Kirjanov ad0651
-		    params.update_ctl_frame_check)
Denis Kirjanov ad0651
+		    params.update_ctl_frame_check ||
Denis Kirjanov ad0651
+		    params.update_accept_any_vlan_flg) {
Denis Kirjanov ad0651
+			DP_VERBOSE(hwfn, QED_MSG_IOV,
Denis Kirjanov ad0651
+				   "vport update config for %s VF[abs 0x%x rel 0x%x]\n",
Denis Kirjanov ad0651
+				   vf_info->is_trusted_configured ? "trusted" : "untrusted",
Denis Kirjanov ad0651
+				   vf->abs_vf_id, vf->relative_vf_id);
Denis Kirjanov ad0651
 			qed_sp_vport_update(hwfn, &params,
Denis Kirjanov ad0651
 					    QED_SPQ_MODE_EBLOCK, NULL);
Denis Kirjanov ad0651
+		}
Denis Kirjanov ad0651
 	}
Denis Kirjanov ad0651
 }
Denis Kirjanov ad0651
 
Denis Kirjanov ad0651
diff --git a/drivers/net/ethernet/qlogic/qed/qed_sriov.h b/drivers/net/ethernet/qlogic/qed/qed_sriov.h
Denis Kirjanov ad0651
index 9a8fd79611f2..853be06bccdf 100644
Denis Kirjanov ad0651
--- a/drivers/net/ethernet/qlogic/qed/qed_sriov.h
Denis Kirjanov ad0651
+++ b/drivers/net/ethernet/qlogic/qed/qed_sriov.h
Denis Kirjanov ad0651
@@ -88,6 +88,7 @@ struct qed_public_vf_info {
Denis Kirjanov ad0651
 	bool is_trusted_request;
Denis Kirjanov ad0651
 	u8 rx_accept_mode;
Denis Kirjanov ad0651
 	u8 tx_accept_mode;
Denis Kirjanov ad0651
+	bool accept_any_vlan;
Denis Kirjanov ad0651
 };
Denis Kirjanov ad0651
 
Denis Kirjanov ad0651
 struct qed_iov_vf_init_params {
Denis Kirjanov ad0651
-- 
Denis Kirjanov ad0651
2.16.4
Denis Kirjanov ad0651