RDMA/nes: Fix error handling issues
authorFaisal Latif <faisal.latif@intel.com>
Wed, 8 Apr 2009 21:22:20 +0000 (14:22 -0700)
committerRoland Dreier <rolandd@cisco.com>
Wed, 8 Apr 2009 21:22:20 +0000 (14:22 -0700)
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>
drivers/infiniband/hw/nes/nes_cm.c
drivers/infiniband/hw/nes/nes_cm.h

index 7c942470b980fa6b4fe6fd95102ff441cef44e60..a09caf5b387d7b0b44e4216cc4e4227be2e3b7f8 100644 (file)
@@ -426,6 +426,7 @@ int schedule_nes_timer(struct nes_cm_node *cm_node, struct sk_buff *skb,
        if (type == NES_TIMER_TYPE_CLOSE) {
                new_send->timetosend += (HZ/10);
                if (cm_node->recv_entry) {
+                       kfree(new_send);
                        WARN_ON(1);
                        return -EINVAL;
                }
@@ -1262,7 +1263,6 @@ static int rem_ref_cm_node(struct nes_cm_core *cm_core,
                cm_node->nesqp = NULL;
        }
 
-       cm_node->freed = 1;
        kfree(cm_node);
        return 0;
 }
@@ -1999,13 +1999,17 @@ static struct nes_cm_node *mini_cm_connect(struct nes_cm_core *cm_core,
                if (loopbackremotelistener == NULL) {
                        create_event(cm_node, NES_CM_EVENT_ABORTED);
                } else {
-                       atomic_inc(&cm_loopbacks);
                        loopback_cm_info = *cm_info;
                        loopback_cm_info.loc_port = cm_info->rem_port;
                        loopback_cm_info.rem_port = cm_info->loc_port;
                        loopback_cm_info.cm_id = loopbackremotelistener->cm_id;
                        loopbackremotenode = make_cm_node(cm_core, nesvnic,
                                &loopback_cm_info, loopbackremotelistener);
+                       if (!loopbackremotenode) {
+                               rem_ref_cm_node(cm_node->cm_core, cm_node);
+                               return NULL;
+                       }
+                       atomic_inc(&cm_loopbacks);
                        loopbackremotenode->loopbackpartner = cm_node;
                        loopbackremotenode->tcp_cntxt.rcv_wscale =
                                NES_CM_DEFAULT_RCV_WND_SCALE;
index d5f778202eb7072f6b2edf13d2c0445e20396169..80bba189257176b2814564018ad0db5c664e2108 100644 (file)
@@ -298,7 +298,6 @@ struct nes_cm_node {
        struct nes_vnic           *nesvnic;
        int                       apbvt_set;
        int                       accept_pend;
-       int                     freed;
        struct list_head        timer_entry;
        struct list_head        reset_entry;
        struct nes_qp           *nesqp;