diff mbox

IB/mlx4: check iboe netdev pointer before dereferencing it

Message ID 1344623134-22600-1-git-send-email-klebers@linux.vnet.ibm.com (mailing list archive)
State Accepted, archived
Delegated to: Roland Dreier
Headers show

Commit Message

Kleber Sacilotto de Souza Aug. 10, 2012, 6:25 p.m. UTC
Unlike other parts of the mlx4_ib code, the function build_mlx_header()
doesn't check if the iboe netdev of the given port is valid before
derefering it, which can cause a crash if the ethernet interface has
already been taken down.

This patch fixes the problem by checking for a valid netdev pointer
before using it to get the port MAC address.

Signed-off-by: Kleber Sacilotto de Souza <klebers@linux.vnet.ibm.com>
---
 drivers/infiniband/hw/mlx4/qp.c |    6 +++++-
 1 files changed, 5 insertions(+), 1 deletions(-)

Comments

Or Gerlitz Aug. 12, 2012, 5:49 a.m. UTC | #1
On 10/08/2012 21:25, Kleber Sacilotto de Souza wrote:
> This patch fixes the problem by checking for a valid netdev pointer
> before using it to get the port MAC address.

just curious, how did you actually stepped on this, code inspection or 
any actual race?

Or.
--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Kleber Sacilotto de Souza Aug. 13, 2012, 1:17 p.m. UTC | #2
On 08/12/2012 02:49 AM, Or Gerlitz wrote:

> On 10/08/2012 21:25, Kleber Sacilotto de Souza wrote:
>> This patch fixes the problem by checking for a valid netdev pointer
>> before using it to get the port MAC address.
> 
> just curious, how did you actually stepped on this, code inspection or
> any actual race?
> 
> Or.
> 


I hit the problem during error recovery after injecting an EEH error on
a distro kernel based on linux 3.0. I was not able to reproduce the
problem on the mainline kernel, but it seems to be just a matter of
having the right timing.
diff mbox

Patch

diff --git a/drivers/infiniband/hw/mlx4/qp.c b/drivers/infiniband/hw/mlx4/qp.c
index a6d8ea0..f585edd 100644
--- a/drivers/infiniband/hw/mlx4/qp.c
+++ b/drivers/infiniband/hw/mlx4/qp.c
@@ -1407,6 +1407,7 @@  static int build_mlx_header(struct mlx4_ib_sqp *sqp, struct ib_send_wr *wr,
 	struct mlx4_wqe_mlx_seg *mlx = wqe;
 	struct mlx4_wqe_inline_seg *inl = wqe + sizeof *mlx;
 	struct mlx4_ib_ah *ah = to_mah(wr->wr.ud.ah);
+	struct net_device *ndev;
 	union ib_gid sgid;
 	u16 pkey;
 	int send_size;
@@ -1483,7 +1484,10 @@  static int build_mlx_header(struct mlx4_ib_sqp *sqp, struct ib_send_wr *wr,
 
 		memcpy(sqp->ud_header.eth.dmac_h, ah->av.eth.mac, 6);
 		/* FIXME: cache smac value? */
-		smac = to_mdev(sqp->qp.ibqp.device)->iboe.netdevs[sqp->qp.port - 1]->dev_addr;
+		ndev = to_mdev(sqp->qp.ibqp.device)->iboe.netdevs[sqp->qp.port - 1];
+		if (!ndev)
+			return -ENODEV;
+		smac = ndev->dev_addr;
 		memcpy(sqp->ud_header.eth.smac_h, smac, 6);
 		if (!memcmp(sqp->ud_header.eth.smac_h, sqp->ud_header.eth.dmac_h, 6))
 			mlx->flags |= cpu_to_be32(MLX4_WQE_CTRL_FORCE_LOOPBACK);