aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/infiniband
diff options
context:
space:
mode:
authorMichael S. Tsirkin <mst@dev.mellanox.co.il>2007-03-22 17:40:16 -0400
committerRoland Dreier <rolandd@cisco.com>2007-03-22 17:40:16 -0400
commitd04d01b113be5b88418eb30087753c3de0a39fd8 (patch)
tree3c7dc849f1dfc7293e8337cb66f6b24e90a3fc36 /drivers/infiniband
parent73b9e9870f5780cb554b68bbcfa47782b27a3e04 (diff)
IPoIB: Fix use-after-free in path_rec_completion()
The connected mode code added the possibility that an neigh struct gets freed in the list_for_each_entry() loop in path_rec_completion(), which causes a use-after-free. Fix this by changing to the _safe variant of the list walking macro. This was spotted by the Coverity checker (CID 1567). Signed-off-by: Michael S. Tsirkin <mst@dev.mellanox.co.il> Signed-off-by: Roland Dreier <rolandd@cisco.com>
Diffstat (limited to 'drivers/infiniband')
-rw-r--r--drivers/infiniband/ulp/ipoib/ipoib_main.c4
1 files changed, 2 insertions, 2 deletions
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_main.c b/drivers/infiniband/ulp/ipoib/ipoib_main.c
index f9dbc6f68145..0741c6d1337c 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_main.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_main.c
@@ -380,7 +380,7 @@ static void path_rec_completion(int status,
380 struct net_device *dev = path->dev; 380 struct net_device *dev = path->dev;
381 struct ipoib_dev_priv *priv = netdev_priv(dev); 381 struct ipoib_dev_priv *priv = netdev_priv(dev);
382 struct ipoib_ah *ah = NULL; 382 struct ipoib_ah *ah = NULL;
383 struct ipoib_neigh *neigh; 383 struct ipoib_neigh *neigh, *tn;
384 struct sk_buff_head skqueue; 384 struct sk_buff_head skqueue;
385 struct sk_buff *skb; 385 struct sk_buff *skb;
386 unsigned long flags; 386 unsigned long flags;
@@ -418,7 +418,7 @@ static void path_rec_completion(int status,
418 while ((skb = __skb_dequeue(&path->queue))) 418 while ((skb = __skb_dequeue(&path->queue)))
419 __skb_queue_tail(&skqueue, skb); 419 __skb_queue_tail(&skqueue, skb);
420 420
421 list_for_each_entry(neigh, &path->neigh_list, list) { 421 list_for_each_entry_safe(neigh, tn, &path->neigh_list, list) {
422 kref_get(&path->ah->ref); 422 kref_get(&path->ah->ref);
423 neigh->ah = path->ah; 423 neigh->ah = path->ah;
424 memcpy(&neigh->dgid.raw, &path->pathrec.dgid.raw, 424 memcpy(&neigh->dgid.raw, &path->pathrec.dgid.raw,