Browse Source

[ipoib] Fix a race when chain-loading undionly.kpxe in IPoIB

The Infiniband link status change callback ipoib_link_state_changed()
may be called while the IPoIB device is closed, in which case there
will not be an IPoIB queue pair to be joined to the IPv4 broadcast
group.  This leads to NULL pointer dereferences in ib_mcast_attach()
and ib_mcast_detach().

Fix by not attempting to join (or leave) the broadcast group unless we
actually have an IPoIB queue pair.

Signed-off-by: Wissam Shoukair <wissams@mellanox.com>
Modified-by: Michael Brown <mcb30@ipxe.org>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
tags/v1.20.1
Wissam Shoukair 9 years ago
parent
commit
eb8df9a046
3 changed files with 17 additions and 2 deletions
  1. 5
    2
      src/drivers/net/ipoib.c
  2. 6
    0
      src/net/infiniband.c
  3. 6
    0
      src/net/infiniband/ib_mcast.c

+ 5
- 2
src/drivers/net/ipoib.c View File

791
 	int rc;
791
 	int rc;
792
 
792
 
793
 	/* Leave existing broadcast group */
793
 	/* Leave existing broadcast group */
794
-	ipoib_leave_broadcast_group ( ipoib );
794
+	if ( ipoib->qp )
795
+		ipoib_leave_broadcast_group ( ipoib );
795
 
796
 
796
 	/* Update MAC address based on potentially-new GID prefix */
797
 	/* Update MAC address based on potentially-new GID prefix */
797
 	memcpy ( &ipoib->mac.gid.s.prefix, &ibdev->gid.s.prefix,
798
 	memcpy ( &ipoib->mac.gid.s.prefix, &ibdev->gid.s.prefix,
806
 	netdev_link_err ( netdev, ( rc ? rc : -EINPROGRESS_JOINING ) );
807
 	netdev_link_err ( netdev, ( rc ? rc : -EINPROGRESS_JOINING ) );
807
 
808
 
808
 	/* Join new broadcast group */
809
 	/* Join new broadcast group */
809
-	if ( ib_is_open ( ibdev ) && ib_link_ok ( ibdev ) &&
810
+	if ( ib_is_open ( ibdev ) && ib_link_ok ( ibdev ) && ipoib->qp &&
810
 	     ( ( rc = ipoib_join_broadcast_group ( ipoib ) ) != 0 ) ) {
811
 	     ( ( rc = ipoib_join_broadcast_group ( ipoib ) ) != 0 ) ) {
811
 		DBGC ( ipoib, "IPoIB %p could not rejoin broadcast group: "
812
 		DBGC ( ipoib, "IPoIB %p could not rejoin broadcast group: "
812
 		       "%s\n", ipoib, strerror ( rc ) );
813
 		       "%s\n", ipoib, strerror ( rc ) );
894
 
895
 
895
 	/* Tear down the queues */
896
 	/* Tear down the queues */
896
 	ib_destroy_qp ( ibdev, ipoib->qp );
897
 	ib_destroy_qp ( ibdev, ipoib->qp );
898
+	ipoib->qp = NULL;
897
 	ib_destroy_cq ( ibdev, ipoib->cq );
899
 	ib_destroy_cq ( ibdev, ipoib->cq );
900
+	ipoib->cq = NULL;
898
 
901
 
899
 	/* Close IB device */
902
 	/* Close IB device */
900
 	ib_close ( ibdev );
903
 	ib_close ( ibdev );

+ 6
- 0
src/net/infiniband.c View File

718
 	struct ib_multicast_gid *mgid;
718
 	struct ib_multicast_gid *mgid;
719
 	int rc;
719
 	int rc;
720
 
720
 
721
+	/* Sanity check */
722
+	assert ( qp != NULL );
723
+
721
 	/* Add to software multicast GID list */
724
 	/* Add to software multicast GID list */
722
 	mgid = zalloc ( sizeof ( *mgid ) );
725
 	mgid = zalloc ( sizeof ( *mgid ) );
723
 	if ( ! mgid ) {
726
 	if ( ! mgid ) {
751
 		       union ib_gid *gid ) {
754
 		       union ib_gid *gid ) {
752
 	struct ib_multicast_gid *mgid;
755
 	struct ib_multicast_gid *mgid;
753
 
756
 
757
+	/* Sanity check */
758
+	assert ( qp != NULL );
759
+
754
 	/* Remove from hardware multicast GID list */
760
 	/* Remove from hardware multicast GID list */
755
 	ibdev->op->mcast_detach ( ibdev, qp, gid );
761
 	ibdev->op->mcast_detach ( ibdev, qp, gid );
756
 
762
 

+ 6
- 0
src/net/infiniband/ib_mcast.c View File

150
 	DBGC ( ibdev, "IBDEV %p QPN %lx joining " IB_GID_FMT "\n",
150
 	DBGC ( ibdev, "IBDEV %p QPN %lx joining " IB_GID_FMT "\n",
151
 	       ibdev, qp->qpn, IB_GID_ARGS ( gid ) );
151
 	       ibdev, qp->qpn, IB_GID_ARGS ( gid ) );
152
 
152
 
153
+	/* Sanity check */
154
+	assert ( qp != NULL );
155
+
153
 	/* Initialise structure */
156
 	/* Initialise structure */
154
 	membership->qp = qp;
157
 	membership->qp = qp;
155
 	memcpy ( &membership->gid, gid, sizeof ( membership->gid ) );
158
 	memcpy ( &membership->gid, gid, sizeof ( membership->gid ) );
199
 	DBGC ( ibdev, "IBDEV %p QPN %lx leaving " IB_GID_FMT "\n",
202
 	DBGC ( ibdev, "IBDEV %p QPN %lx leaving " IB_GID_FMT "\n",
200
 	       ibdev, qp->qpn, IB_GID_ARGS ( gid ) );
203
 	       ibdev, qp->qpn, IB_GID_ARGS ( gid ) );
201
 
204
 
205
+	/* Sanity check */
206
+	assert ( qp != NULL );
207
+
202
 	/* Detach from multicast GID */
208
 	/* Detach from multicast GID */
203
 	ib_mcast_detach ( ibdev, qp, &membership->gid );
209
 	ib_mcast_detach ( ibdev, qp, &membership->gid );
204
 
210
 

Loading…
Cancel
Save