net/mlx4_core: Make sure that negative array index isn't used
authorDotan Barak <dotanb@dev.mellanox.co.il>
Wed, 16 Jul 2014 08:57:48 +0000 (11:57 +0300)
committerDavid S. Miller <davem@davemloft.net>
Thu, 17 Jul 2014 06:26:24 +0000 (23:26 -0700)
To make sure that the array index isn't used in the code with
negative value, we stop using the for loop integer iterator
outside of it.
>From now on use members count to swap the last QP with removed one.
Fix also the second occurrence of this flow in mlx4_qp_detach_common().
In mlx4_qp_detach_common() use members_count instead of
loop iterator outside of the for loop.

Signed-off-by: Dotan Barak <dotanb@dev.mellanox.co.il>
Reviewed-by: Yevgeny Petrilin <yevgenyp@mellanox.co.il>
Signed-off-by: Eugenia Emantayev <eugenia@mellanox.com>
Signed-off-by: Amir Vadai <amirv@mellanox.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/mellanox/mlx4/mcg.c

index 14a4071934782a74eef80b173fb3adeb5f8af123..04a8636a0b7e6d2cb8a4c8ba9d8ceb78a8b95a97 100644 (file)
@@ -513,7 +513,7 @@ static int remove_promisc_qp(struct mlx4_dev *dev, u8 port,
        u32 members_count;
        bool found;
        bool back_to_list = false;
-       int loc, i;
+       int i;
        int err;
 
        if (port < 1 || port > dev->caps.num_ports)
@@ -565,18 +565,30 @@ static int remove_promisc_qp(struct mlx4_dev *dev, u8 port,
                        list_del(&dqp->list);
                        kfree(dqp);
                } else {
+                       int loc = -1;
                        err = mlx4_READ_ENTRY(dev, entry->index, mailbox);
                                if (err)
                                        goto out_mailbox;
                        members_count = be32_to_cpu(mgm->members_count) & 0xffffff;
-                       for (loc = -1, i = 0; i < members_count; ++i)
-                               if ((be32_to_cpu(mgm->qp[i]) & MGM_QPN_MASK) == qpn)
+                       for (i = 0; i < members_count; ++i)
+                               if ((be32_to_cpu(mgm->qp[i]) &
+                                    MGM_QPN_MASK) == qpn) {
                                        loc = i;
+                                       break;
+                               }
+
+                       if (loc < 0) {
+                               mlx4_err(dev, "QP %06x wasn't found in entry %d\n",
+                                        qpn, entry->index);
+                               err = -EINVAL;
+                               goto out_mailbox;
+                       }
 
+                       /* copy the last QP in this MGM over removed QP */
+                       mgm->qp[loc] = mgm->qp[members_count - 1];
+                       mgm->qp[members_count - 1] = 0;
                        mgm->members_count = cpu_to_be32(--members_count |
                                                         (MLX4_PROT_ETH << 30));
-                       mgm->qp[loc] = mgm->qp[i - 1];
-                       mgm->qp[i - 1] = 0;
 
                        err = mlx4_WRITE_ENTRY(dev, entry->index, mailbox);
                                if (err)
@@ -1074,7 +1086,7 @@ int mlx4_qp_detach_common(struct mlx4_dev *dev, struct mlx4_qp *qp, u8 gid[16],
        struct mlx4_mgm *mgm;
        u32 members_count;
        int prev, index;
-       int i, loc;
+       int i, loc = -1;
        int err;
        u8 port = gid[5];
        bool removed_entry = false;
@@ -1103,9 +1115,11 @@ int mlx4_qp_detach_common(struct mlx4_dev *dev, struct mlx4_qp *qp, u8 gid[16],
                goto out;
 
        members_count = be32_to_cpu(mgm->members_count) & 0xffffff;
-       for (loc = -1, i = 0; i < members_count; ++i)
-               if ((be32_to_cpu(mgm->qp[i]) & MGM_QPN_MASK) == qp->qpn)
+       for (i = 0; i < members_count; ++i)
+               if ((be32_to_cpu(mgm->qp[i]) & MGM_QPN_MASK) == qp->qpn) {
                        loc = i;
+                       break;
+               }
 
        if (loc == -1) {
                mlx4_err(dev, "QP %06x not found in MGM\n", qp->qpn);
@@ -1113,15 +1127,15 @@ int mlx4_qp_detach_common(struct mlx4_dev *dev, struct mlx4_qp *qp, u8 gid[16],
                goto out;
        }
 
-
+       /* copy the last QP in this MGM over removed QP */
+       mgm->qp[loc] = mgm->qp[members_count - 1];
+       mgm->qp[members_count - 1] = 0;
        mgm->members_count = cpu_to_be32(--members_count | (u32) prot << 30);
-       mgm->qp[loc]       = mgm->qp[i - 1];
-       mgm->qp[i - 1]     = 0;
 
        if (prot == MLX4_PROT_ETH)
                removed_entry = can_remove_steering_entry(dev, port, steer,
                                                                index, qp->qpn);
-       if (i != 1 && (prot != MLX4_PROT_ETH || !removed_entry)) {
+       if (members_count && (prot != MLX4_PROT_ETH || !removed_entry)) {
                err = mlx4_WRITE_ENTRY(dev, index, mailbox);
                goto out;
        }
This page took 0.027729 seconds and 5 git commands to generate.