summaryrefslogtreecommitdiffstats
path: root/src/drivers/net
diff options
context:
space:
mode:
authorWissam Shoukair2015-08-12 11:28:58 +0200
committerMichael Brown2015-08-17 15:42:36 +0200
commiteb8df9a0466078f083822e5ef2fb16713c94d25c (patch)
treef42ae5a6ad32a2e1a04139894cece0c0dc3c3a67 /src/drivers/net
parent[peerdist] Add support for PeerDist (aka BranchCache) HTTP content encoding (diff)
downloadipxe-eb8df9a0466078f083822e5ef2fb16713c94d25c.tar.gz
ipxe-eb8df9a0466078f083822e5ef2fb16713c94d25c.tar.xz
ipxe-eb8df9a0466078f083822e5ef2fb16713c94d25c.zip
[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>
Diffstat (limited to 'src/drivers/net')
-rw-r--r--src/drivers/net/ipoib.c7
1 files changed, 5 insertions, 2 deletions
diff --git a/src/drivers/net/ipoib.c b/src/drivers/net/ipoib.c
index 7ecb2c5dd..6552d764e 100644
--- a/src/drivers/net/ipoib.c
+++ b/src/drivers/net/ipoib.c
@@ -791,7 +791,8 @@ static void ipoib_link_state_changed ( struct ib_device *ibdev ) {
int rc;
/* Leave existing broadcast group */
- ipoib_leave_broadcast_group ( ipoib );
+ if ( ipoib->qp )
+ ipoib_leave_broadcast_group ( ipoib );
/* Update MAC address based on potentially-new GID prefix */
memcpy ( &ipoib->mac.gid.s.prefix, &ibdev->gid.s.prefix,
@@ -806,7 +807,7 @@ static void ipoib_link_state_changed ( struct ib_device *ibdev ) {
netdev_link_err ( netdev, ( rc ? rc : -EINPROGRESS_JOINING ) );
/* Join new broadcast group */
- if ( ib_is_open ( ibdev ) && ib_link_ok ( ibdev ) &&
+ if ( ib_is_open ( ibdev ) && ib_link_ok ( ibdev ) && ipoib->qp &&
( ( rc = ipoib_join_broadcast_group ( ipoib ) ) != 0 ) ) {
DBGC ( ipoib, "IPoIB %p could not rejoin broadcast group: "
"%s\n", ipoib, strerror ( rc ) );
@@ -894,7 +895,9 @@ static void ipoib_close ( struct net_device *netdev ) {
/* Tear down the queues */
ib_destroy_qp ( ibdev, ipoib->qp );
+ ipoib->qp = NULL;
ib_destroy_cq ( ibdev, ipoib->cq );
+ ipoib->cq = NULL;
/* Close IB device */
ib_close ( ibdev );