The PF dispatcher zxdh_config_process_callback() hands the<br />msghead->vport and msghead->pcieid of a request, both written by the<br />VF into its BAR0 mailbox window, straight to the handlers, and<br />nothing on the receive path compares them with the sender. One<br />message can therefore be aimed at any port: it rewrites or deletes<br />the port attribute entry of the PF itself or of another VF.<br /> <br />Add zxdh_msg_head_is_own_vf() before the dispatch: pcieid must be a<br />VF pcieid whose PF is this PF, and vport must carry vf_flag with this<br />PF's epid and pfid. The vport vfid is deliberately not compared with<br />the pcieid function number: vfid is allocated sequentially across all<br />PFs of an epid while the function number restarts at 0 for each PF.<br />Anything else is answered ZXDH_REPS_INVALID and no handler runs;<br />messages built by zxdh_msg_head_build() pass unchanged.<br /> <br />A VF that forges both pcieid and vport of a sibling VF of the same PF<br />still cannot be told apart by the driver; protection against that<br />case is planned on the device side. This patch closes the PF-port and<br />cross-PF cases.<br /> <br />Fixes: 2e22ff2528db ("net/zxdh: provide PF/VF message interrupt callback")<br />Cc: stable@dpdk.org<br /> <br />Signed-off-by: Junlong Wang <wang.junlong1@zte.com.cn> <br />---<br /> drivers/net/zxdh/zxdh_msg.c | 25 ++++++++++++++++++++++++-<br /> 1 file changed, 24 insertions(+), 1 deletion(-)<br /> <br />diff --git a/drivers/net/zxdh/zxdh_msg.c b/drivers/net/zxdh/zxdh_msg.c<br />index f0f0522817..6aafefe289 100644<br />--- a/drivers/net/zxdh/zxdh_msg.c<br />+++ b/drivers/net/zxdh/zxdh_msg.c<br />@@ -2397,6 +2397,24 @@ static const zxdh_msg_process_callback zxdh_proc_cb[] = {<br />     [ZXDH_FLOW_HW_FLUSH] = zxdh_vf_flow_hw_flush,<br /> };<br />  <br />+/*<br />+ * The msg head is written by the VF driver: the vport and pcieid it carries<br />+ * must name one VF of this PF, not the PF itself or a port of another PF.<br />+ */<br />+static bool<br />+zxdh_msg_head_is_own_vf(struct zxdh_hw *hw, struct zxdh_msg_head *msghead)<br />+{<br />+    union zxdh_virport_num vport = {.vport = msghead->vport};<br />+<br />+    if ((msghead->pcieid & ZXDH_PCIEID_IS_PF_MASK) ||<br />+            ZXDH_PF_PCIE_ID(msghead->pcieid) != hw->pcie_id)<br />+        return false;<br />+<br />+    return vport.vf_flag && <br />+        vport.epid == hw->vport.epid && <br />+        vport.pfid == hw->vport.pfid;<br />+}<br />+<br /> static inline int<br /> zxdh_config_process_callback(struct zxdh_hw *hw, struct zxdh_msg_info *msg_info,<br />     void *res, uint16_t *res_len)<br />@@ -2408,7 +2426,12 @@ zxdh_config_process_callback(struct zxdh_hw *hw, struct zxdh_msg_info *msg_info,<br />         PMD_DRV_LOG(ERR, " invalid param");<br />         return -1;<br />     }<br />-    if (zxdh_proc_cb[msghead->msg_type]) {<br />+<br />+    if (!zxdh_msg_head_is_own_vf(hw, msghead)) {<br />+        PMD_DRV_LOG(ERR, "msg_type %d vport 0x%x pcieid 0x%x is not a VF of PF pcieid 0x%x",<br />+            msghead->msg_type, msghead->vport, msghead->pcieid, hw->pcie_id);<br />+        ZXDH_SET(msg_reply_body, res, flag, ZXDH_REPS_INVALID);<br />+    } else if (zxdh_proc_cb[msghead->msg_type]) {<br />         ret = zxdh_proc_cb[msghead->msg_type](hw, msghead->vport, msghead->pcieid,<br />                     (void *)&msg_info->data, res, res_len);<br />         if (!ret)<br />--  <br />2.27.0<br />