Drivers: hv: check vmbus_device_create() return value in vmbus_process_offer()
authorVitaly Kuznetsov <vkuznets@redhat.com>
Tue, 20 Jan 2015 15:45:04 +0000 (16:45 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sun, 25 Jan 2015 17:18:00 +0000 (09:18 -0800)
vmbus_device_create() result is not being checked in vmbus_process_offer() and
it can fail if kzalloc() fails. Add the check and do minor cleanup to avoid
additional duplication of "free_channel(); return;" block.

Reported-by: Jason Wang <jasowang@redhat.com>
Signed-off-by: Vitaly Kuznetsov <vkuznets@redhat.com>
Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
Acked-by: Jason Wang <jasowang@redhat.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/hv/channel_mgmt.c

index 1d7df2576b1c10cb3f4b1deaed889aa1238c086d..704c0e00f8d255304eae33f09c76a8cbf26b37bc 100644 (file)
@@ -341,11 +341,10 @@ static void vmbus_process_offer(struct work_struct *work)
                        if (channel->sc_creation_callback != NULL)
                                channel->sc_creation_callback(newchannel);
 
-                       return;
+                       goto out;
                }
 
-               free_channel(newchannel);
-               return;
+               goto err_free_chan;
        }
 
        /*
@@ -364,6 +363,8 @@ static void vmbus_process_offer(struct work_struct *work)
                &newchannel->offermsg.offer.if_type,
                &newchannel->offermsg.offer.if_instance,
                newchannel);
+       if (!newchannel->device_obj)
+               goto err_free_chan;
 
        /*
         * Add the new device to the bus. This will kick off device-driver
@@ -379,9 +380,12 @@ static void vmbus_process_offer(struct work_struct *work)
                list_del(&newchannel->listentry);
                spin_unlock_irqrestore(&vmbus_connection.channel_lock, flags);
                kfree(newchannel->device_obj);
-
-               free_channel(newchannel);
+               goto err_free_chan;
        }
+out:
+       return;
+err_free_chan:
+       free_channel(newchannel);
 }
 
 enum {