Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Drivers: hv: Cleanup error handling in vmbus_open()

Fix a memory leak in the error handling path in the function vmbus_open().

Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
Reviewed-by: Haiyang Zhang <haiyangz@microsoft.com>
Reported-by: Jason Wang <jasowang@redhat.com>
Cc: Stable <stable@vger.kernel.org>
Acked-by: Jason Wang <jasowang@redhat.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

authored by

K. Y. Srinivasan and committed by
Greg Kroah-Hartman
13925502 1b207734

+13 -11
+13 -11
drivers/hv/channel.c
··· 146 146 147 147 if (ret != 0) { 148 148 err = ret; 149 - goto errorout; 149 + goto error0; 150 150 } 151 151 152 152 ret = hv_ringbuffer_init( 153 153 &newchannel->inbound, in, recv_ringbuffer_size); 154 154 if (ret != 0) { 155 155 err = ret; 156 - goto errorout; 156 + goto error0; 157 157 } 158 158 159 159 ··· 168 168 169 169 if (ret != 0) { 170 170 err = ret; 171 - goto errorout; 171 + goto error0; 172 172 } 173 173 174 174 /* Create and init the channel open message */ ··· 177 177 GFP_KERNEL); 178 178 if (!open_info) { 179 179 err = -ENOMEM; 180 - goto errorout; 180 + goto error0; 181 181 } 182 182 183 183 init_completion(&open_info->waitevent); ··· 193 193 194 194 if (userdatalen > MAX_USER_DEFINED_BYTES) { 195 195 err = -EINVAL; 196 - goto errorout; 196 + goto error0; 197 197 } 198 198 199 199 if (userdatalen) ··· 208 208 sizeof(struct vmbus_channel_open_channel)); 209 209 210 210 if (ret != 0) 211 - goto cleanup; 211 + goto error1; 212 212 213 213 t = wait_for_completion_timeout(&open_info->waitevent, 5*HZ); 214 214 if (t == 0) { 215 215 err = -ETIMEDOUT; 216 - goto errorout; 216 + goto error1; 217 217 } 218 218 219 219 220 220 if (open_info->response.open_result.status) 221 221 err = open_info->response.open_result.status; 222 222 223 - cleanup: 224 223 spin_lock_irqsave(&vmbus_connection.channelmsg_lock, flags); 225 224 list_del(&open_info->msglistentry); 226 225 spin_unlock_irqrestore(&vmbus_connection.channelmsg_lock, flags); ··· 227 228 kfree(open_info); 228 229 return err; 229 230 230 - errorout: 231 - hv_ringbuffer_cleanup(&newchannel->outbound); 232 - hv_ringbuffer_cleanup(&newchannel->inbound); 231 + error1: 232 + spin_lock_irqsave(&vmbus_connection.channelmsg_lock, flags); 233 + list_del(&open_info->msglistentry); 234 + spin_unlock_irqrestore(&vmbus_connection.channelmsg_lock, flags); 235 + 236 + error0: 233 237 free_pages((unsigned long)out, 234 238 get_order(send_ringbuffer_size + recv_ringbuffer_size)); 235 239 kfree(open_info);