From: Chenna Arnoori <[email protected]>

Two independent out-of-bounds issues in the driver:

- bnxt_mac_addr_add_op() indexed bp->vnic_info[pool] with a
  caller-supplied pool before validating it against bp->max_vnics, and
  before checking bp->vnic_info was even allocated yet (it is NULL
  until the port is started). The existing "if (!vnic)" check was
  always false, since vnic held the address of an array element and
  is never NULL. Reorder to check dev_started/vnic_info first, then
  bounds-check pool against max_vnics before indexing.

- bnxt_flow_non_void_item()/bnxt_flow_non_void_action() looped
  unconditionally until a non-VOID item/action was found, walking off
  the end of a pattern/actions array that lacked a terminating END
  item. Bound the skip loop and stop advancing once the limit is hit.

Fixes: 51fafb89a9a0 ("net/bnxt: get rid of ff pools and use VNIC info array")
Fixes: 5c1171c97216 ("net/bnxt: refactor filter/flow")
Cc: [email protected]

Signed-off-by: Chenna Arnoori <[email protected]>
Signed-off-by: Mohammad Shuab Siddique <[email protected]>
---
 drivers/net/bnxt/bnxt_ethdev.c | 16 ++++++++++------
 drivers/net/bnxt/bnxt_flow.c   | 28 ++++++++++++++++++++--------
 2 files changed, 30 insertions(+), 14 deletions(-)

diff --git a/drivers/net/bnxt/bnxt_ethdev.c b/drivers/net/bnxt/bnxt_ethdev.c
index 27cf67c04f..db9b49238a 100644
--- a/drivers/net/bnxt/bnxt_ethdev.c
+++ b/drivers/net/bnxt/bnxt_ethdev.c
@@ -2113,7 +2113,7 @@ static int bnxt_mac_addr_add_op(struct rte_eth_dev 
*eth_dev,
                                uint32_t index, uint32_t pool)
 {
        struct bnxt *bp = eth_dev->data->dev_private;
-       struct bnxt_vnic_info *vnic = &bp->vnic_info[pool];
+       struct bnxt_vnic_info *vnic;
        int rc = 0;
 
        rc = is_bnxt_in_error(bp);
@@ -2125,15 +2125,19 @@ static int bnxt_mac_addr_add_op(struct rte_eth_dev 
*eth_dev,
                return -ENOTSUP;
        }
 
-       if (!vnic) {
-               PMD_DRV_LOG_LINE(ERR, "VNIC not found for pool %d!", pool);
-               return -EINVAL;
-       }
-
        /* Filter settings will get applied when port is started */
        if (!eth_dev->data->dev_started)
                return 0;
 
+       if (bp->vnic_info == NULL)
+               return 0;
+
+       if (pool >= bp->max_vnics) {
+               PMD_DRV_LOG_LINE(ERR, "Pool %u exceeds VNIC count %u!", pool, 
bp->max_vnics);
+               return -EINVAL;
+       }
+       vnic = &bp->vnic_info[pool];
+
        rc = bnxt_add_mac_filter(bp, vnic, mac_addr, index, pool);
 
        return rc;
diff --git a/drivers/net/bnxt/bnxt_flow.c b/drivers/net/bnxt/bnxt_flow.c
index a2e590540b..14d52e1818 100644
--- a/drivers/net/bnxt/bnxt_flow.c
+++ b/drivers/net/bnxt/bnxt_flow.c
@@ -58,24 +58,36 @@ bnxt_flow_args_validate(const struct rte_flow_attr *attr,
        return 0;
 }
 
+#define BNXT_MAX_FLOW_ITEMS 256
+
 static const struct rte_flow_item *
 bnxt_flow_non_void_item(const struct rte_flow_item *cur)
 {
-       while (1) {
-               if (cur->type != RTE_FLOW_ITEM_TYPE_VOID)
-                       return cur;
+       int i = 0;
+
+       if (!cur)
+               return NULL;
+
+       while (cur->type == RTE_FLOW_ITEM_TYPE_VOID && i < BNXT_MAX_FLOW_ITEMS) 
{
                cur++;
+               i++;
        }
+       return cur;
 }
 
 static const struct rte_flow_action *
 bnxt_flow_non_void_action(const struct rte_flow_action *cur)
 {
-       while (1) {
-               if (cur->type != RTE_FLOW_ACTION_TYPE_VOID)
-                       return cur;
+       int i = 0;
+
+       if (!cur)
+               return NULL;
+
+       while (cur->type == RTE_FLOW_ACTION_TYPE_VOID && i < 
BNXT_MAX_FLOW_ITEMS) {
                cur++;
+               i++;
        }
+       return cur;
 }
 
 static int
@@ -109,7 +121,7 @@ bnxt_filter_type_check(const struct rte_flow_item pattern[],
                        PMD_DRV_LOG_LINE(DEBUG, "Unknown Flow type");
                        use_ntuple |= 0;
                }
-               item++;
+               item = bnxt_flow_non_void_item(item + 1);
        }
 
        if (has_vlan && use_ntuple) {
@@ -680,7 +692,7 @@ bnxt_validate_and_parse_flow_type(const struct 
rte_flow_attr *attr,
                default:
                        break;
                }
-               item++;
+               item = bnxt_flow_non_void_item(item + 1);
        }
        filter->enables = en;
        filter->valid_flags = valid_flags;
-- 
2.47.3

Reply via email to