diff options
author | Faisal Latif <faisal.latif@intel.com> | 2009-04-08 17:22:20 -0400 |
---|---|---|
committer | Roland Dreier <rolandd@cisco.com> | 2009-04-08 17:22:20 -0400 |
commit | 79fc3d7410c861c8ced5b81a5c3759f6bbf891dc (patch) | |
tree | 99c16570cd52c43d65bc9ca4e60f3c4e34d4ae7e /drivers/infiniband/hw/nes/nes_cm.c | |
parent | 7a5efb62f6ae366cefac6be475434906c5061e15 (diff) |
RDMA/nes: Fix error handling issues
Fix issues found by static code analysis:
(1) Check if cm_node was successfully created for loopback connection.
(2) schedule_nes_timer() does not free up allocated memory after
encountering an error. There is a WARN_ON() for this condition.
(3) there is a cm_node->freed flag which is set but not used.
Reported-by: Dan Carpenter <error27@gmail.com>
Signed-off-by: Faisal Latif <faisal.latif@intel.com>
Signed-off-by: Roland Dreier <rolandd@cisco.com>
Diffstat (limited to 'drivers/infiniband/hw/nes/nes_cm.c')
-rw-r--r-- | drivers/infiniband/hw/nes/nes_cm.c | 8 |
1 files changed, 6 insertions, 2 deletions
diff --git a/drivers/infiniband/hw/nes/nes_cm.c b/drivers/infiniband/hw/nes/nes_cm.c index 7c942470b980..a09caf5b387d 100644 --- a/drivers/infiniband/hw/nes/nes_cm.c +++ b/drivers/infiniband/hw/nes/nes_cm.c | |||
@@ -426,6 +426,7 @@ int schedule_nes_timer(struct nes_cm_node *cm_node, struct sk_buff *skb, | |||
426 | if (type == NES_TIMER_TYPE_CLOSE) { | 426 | if (type == NES_TIMER_TYPE_CLOSE) { |
427 | new_send->timetosend += (HZ/10); | 427 | new_send->timetosend += (HZ/10); |
428 | if (cm_node->recv_entry) { | 428 | if (cm_node->recv_entry) { |
429 | kfree(new_send); | ||
429 | WARN_ON(1); | 430 | WARN_ON(1); |
430 | return -EINVAL; | 431 | return -EINVAL; |
431 | } | 432 | } |
@@ -1262,7 +1263,6 @@ static int rem_ref_cm_node(struct nes_cm_core *cm_core, | |||
1262 | cm_node->nesqp = NULL; | 1263 | cm_node->nesqp = NULL; |
1263 | } | 1264 | } |
1264 | 1265 | ||
1265 | cm_node->freed = 1; | ||
1266 | kfree(cm_node); | 1266 | kfree(cm_node); |
1267 | return 0; | 1267 | return 0; |
1268 | } | 1268 | } |
@@ -1999,13 +1999,17 @@ static struct nes_cm_node *mini_cm_connect(struct nes_cm_core *cm_core, | |||
1999 | if (loopbackremotelistener == NULL) { | 1999 | if (loopbackremotelistener == NULL) { |
2000 | create_event(cm_node, NES_CM_EVENT_ABORTED); | 2000 | create_event(cm_node, NES_CM_EVENT_ABORTED); |
2001 | } else { | 2001 | } else { |
2002 | atomic_inc(&cm_loopbacks); | ||
2003 | loopback_cm_info = *cm_info; | 2002 | loopback_cm_info = *cm_info; |
2004 | loopback_cm_info.loc_port = cm_info->rem_port; | 2003 | loopback_cm_info.loc_port = cm_info->rem_port; |
2005 | loopback_cm_info.rem_port = cm_info->loc_port; | 2004 | loopback_cm_info.rem_port = cm_info->loc_port; |
2006 | loopback_cm_info.cm_id = loopbackremotelistener->cm_id; | 2005 | loopback_cm_info.cm_id = loopbackremotelistener->cm_id; |
2007 | loopbackremotenode = make_cm_node(cm_core, nesvnic, | 2006 | loopbackremotenode = make_cm_node(cm_core, nesvnic, |
2008 | &loopback_cm_info, loopbackremotelistener); | 2007 | &loopback_cm_info, loopbackremotelistener); |
2008 | if (!loopbackremotenode) { | ||
2009 | rem_ref_cm_node(cm_node->cm_core, cm_node); | ||
2010 | return NULL; | ||
2011 | } | ||
2012 | atomic_inc(&cm_loopbacks); | ||
2009 | loopbackremotenode->loopbackpartner = cm_node; | 2013 | loopbackremotenode->loopbackpartner = cm_node; |
2010 | loopbackremotenode->tcp_cntxt.rcv_wscale = | 2014 | loopbackremotenode->tcp_cntxt.rcv_wscale = |
2011 | NES_CM_DEFAULT_RCV_WND_SCALE; | 2015 | NES_CM_DEFAULT_RCV_WND_SCALE; |