tap: fix memory leak on success to create a tap device
The memory leak on success to create a tap device. And the nfds and
nvhosts may not be the same and need to be processed separately.
Fixes: 07825977 ("tap: fix memory leak on failure to create a multiqueue tap device")
Fixes: 264986e2 ("tap: multiqueue support")
Cc: qemu-stable@nongnu.org
Signed-off-by: Yunjian Wang <wangyunjian@huawei.com>
Signed-off-by: Jason Wang <jasowang@redhat.com>
			
			
This commit is contained in:
		
							parent
							
								
									4712c158c5
								
							
						
					
					
						commit
						323e7c1177
					
				
							
								
								
									
										16
									
								
								net/tap.c
									
									
									
									
									
								
							
							
						
						
									
										16
									
								
								net/tap.c
									
									
									
									
									
								
							@ -805,7 +805,8 @@ int net_init_tap(const Netdev *netdev, const char *name,
 | 
				
			|||||||
    } else if (tap->has_fds) {
 | 
					    } else if (tap->has_fds) {
 | 
				
			||||||
        char **fds;
 | 
					        char **fds;
 | 
				
			||||||
        char **vhost_fds;
 | 
					        char **vhost_fds;
 | 
				
			||||||
        int nfds, nvhosts;
 | 
					        int nfds = 0, nvhosts = 0;
 | 
				
			||||||
 | 
					        int ret = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (tap->has_ifname || tap->has_script || tap->has_downscript ||
 | 
					        if (tap->has_ifname || tap->has_script || tap->has_downscript ||
 | 
				
			||||||
            tap->has_vnet_hdr || tap->has_helper || tap->has_queues ||
 | 
					            tap->has_vnet_hdr || tap->has_helper || tap->has_queues ||
 | 
				
			||||||
@ -825,6 +826,7 @@ int net_init_tap(const Netdev *netdev, const char *name,
 | 
				
			|||||||
            if (nfds != nvhosts) {
 | 
					            if (nfds != nvhosts) {
 | 
				
			||||||
                error_setg(errp, "The number of fds passed does not match "
 | 
					                error_setg(errp, "The number of fds passed does not match "
 | 
				
			||||||
                           "the number of vhostfds passed");
 | 
					                           "the number of vhostfds passed");
 | 
				
			||||||
 | 
					                ret = -1;
 | 
				
			||||||
                goto free_fail;
 | 
					                goto free_fail;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
@ -833,6 +835,7 @@ int net_init_tap(const Netdev *netdev, const char *name,
 | 
				
			|||||||
            fd = monitor_fd_param(cur_mon, fds[i], &err);
 | 
					            fd = monitor_fd_param(cur_mon, fds[i], &err);
 | 
				
			||||||
            if (fd == -1) {
 | 
					            if (fd == -1) {
 | 
				
			||||||
                error_propagate(errp, err);
 | 
					                error_propagate(errp, err);
 | 
				
			||||||
 | 
					                ret = -1;
 | 
				
			||||||
                goto free_fail;
 | 
					                goto free_fail;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -843,6 +846,7 @@ int net_init_tap(const Netdev *netdev, const char *name,
 | 
				
			|||||||
            } else if (vnet_hdr != tap_probe_vnet_hdr(fd)) {
 | 
					            } else if (vnet_hdr != tap_probe_vnet_hdr(fd)) {
 | 
				
			||||||
                error_setg(errp,
 | 
					                error_setg(errp,
 | 
				
			||||||
                           "vnet_hdr not consistent across given tap fds");
 | 
					                           "vnet_hdr not consistent across given tap fds");
 | 
				
			||||||
 | 
					                ret = -1;
 | 
				
			||||||
                goto free_fail;
 | 
					                goto free_fail;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -852,21 +856,21 @@ int net_init_tap(const Netdev *netdev, const char *name,
 | 
				
			|||||||
                             vnet_hdr, fd, &err);
 | 
					                             vnet_hdr, fd, &err);
 | 
				
			||||||
            if (err) {
 | 
					            if (err) {
 | 
				
			||||||
                error_propagate(errp, err);
 | 
					                error_propagate(errp, err);
 | 
				
			||||||
 | 
					                ret = -1;
 | 
				
			||||||
                goto free_fail;
 | 
					                goto free_fail;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        g_free(fds);
 | 
					 | 
				
			||||||
        g_free(vhost_fds);
 | 
					 | 
				
			||||||
        return 0;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
free_fail:
 | 
					free_fail:
 | 
				
			||||||
 | 
					        for (i = 0; i < nvhosts; i++) {
 | 
				
			||||||
 | 
					            g_free(vhost_fds[i]);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
        for (i = 0; i < nfds; i++) {
 | 
					        for (i = 0; i < nfds; i++) {
 | 
				
			||||||
            g_free(fds[i]);
 | 
					            g_free(fds[i]);
 | 
				
			||||||
            g_free(vhost_fds[i]);
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        g_free(fds);
 | 
					        g_free(fds);
 | 
				
			||||||
        g_free(vhost_fds);
 | 
					        g_free(vhost_fds);
 | 
				
			||||||
        return -1;
 | 
					        return ret;
 | 
				
			||||||
    } else if (tap->has_helper) {
 | 
					    } else if (tap->has_helper) {
 | 
				
			||||||
        if (tap->has_ifname || tap->has_script || tap->has_downscript ||
 | 
					        if (tap->has_ifname || tap->has_script || tap->has_downscript ||
 | 
				
			||||||
            tap->has_vnet_hdr || tap->has_queues || tap->has_vhostfds) {
 | 
					            tap->has_vnet_hdr || tap->has_queues || tap->has_vhostfds) {
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user