提交 6d0b908a 编写于 作者: V Victor Kaplansky 提交者: Michael S. Tsirkin

tests/vhost-user-bridge.c: fix fd leakage

This fixes file descriptor leakage in vhost-user-bridge
application. Whenever a new callfd or kickfd is set, the previous
one should be explicitly closed. File descriptors used to map
guest's memory are closed immediately after mmap call.
Signed-off-by: NVictor Kaplansky <victork@redhat.com>
Reviewed-by: NMichael S. Tsirkin <mst@redhat.com>
Signed-off-by: NMichael S. Tsirkin <mst@redhat.com>
上级 b0ae1536
...@@ -113,7 +113,6 @@ dispatcher_add(Dispatcher *dispr, int sock, void *ctx, CallbackFunc cb) ...@@ -113,7 +113,6 @@ dispatcher_add(Dispatcher *dispr, int sock, void *ctx, CallbackFunc cb)
return 0; return 0;
} }
#if 0
/* dispatcher_remove() is not currently in use but may be useful /* dispatcher_remove() is not currently in use but may be useful
* in the future. */ * in the future. */
static int static int
...@@ -127,9 +126,9 @@ dispatcher_remove(Dispatcher *dispr, int sock) ...@@ -127,9 +126,9 @@ dispatcher_remove(Dispatcher *dispr, int sock)
} }
FD_CLR(sock, &dispr->fdset); FD_CLR(sock, &dispr->fdset);
DPRINT("Sock %d removed from dispatcher watch.\n", sock);
return 0; return 0;
} }
#endif
/* timeout in us */ /* timeout in us */
static int static int
...@@ -156,11 +155,16 @@ dispatcher_wait(Dispatcher *dispr, uint32_t timeout) ...@@ -156,11 +155,16 @@ dispatcher_wait(Dispatcher *dispr, uint32_t timeout)
/* Now call callback for every ready socket. */ /* Now call callback for every ready socket. */
int sock; int sock;
for (sock = 0; sock < dispr->max_sock + 1; sock++) for (sock = 0; sock < dispr->max_sock + 1; sock++) {
if (FD_ISSET(sock, &fdset)) { /* The callback on a socket can remove other sockets from the
* dispatcher, thus we have to check that the socket is
* still not removed from dispatcher's list
*/
if (FD_ISSET(sock, &fdset) && FD_ISSET(sock, &dispr->fdset)) {
Event *e = &dispr->events[sock]; Event *e = &dispr->events[sock];
e->callback(sock, e->ctx); e->callback(sock, e->ctx);
} }
}
return 0; return 0;
} }
...@@ -837,9 +841,10 @@ vubr_set_mem_table_exec(VubrDev *dev, VhostUserMsg *vmsg) ...@@ -837,9 +841,10 @@ vubr_set_mem_table_exec(VubrDev *dev, VhostUserMsg *vmsg)
if (mmap_addr == MAP_FAILED) { if (mmap_addr == MAP_FAILED) {
vubr_die("mmap"); vubr_die("mmap");
} }
dev_region->mmap_addr = (uint64_t) mmap_addr; dev_region->mmap_addr = (uint64_t) mmap_addr;
DPRINT(" mmap_addr: 0x%016"PRIx64"\n", dev_region->mmap_addr); DPRINT(" mmap_addr: 0x%016"PRIx64"\n", dev_region->mmap_addr);
close(vmsg->fds[i]);
} }
return 0; return 0;
...@@ -950,6 +955,17 @@ vubr_get_vring_base_exec(VubrDev *dev, VhostUserMsg *vmsg) ...@@ -950,6 +955,17 @@ vubr_get_vring_base_exec(VubrDev *dev, VhostUserMsg *vmsg)
* we have to respect * VHOST_USER_SET_VRING_ENABLE request. */ * we have to respect * VHOST_USER_SET_VRING_ENABLE request. */
dev->ready = 0; dev->ready = 0;
if (dev->vq[index].call_fd != -1) {
close(dev->vq[index].call_fd);
dispatcher_remove(&dev->dispatcher, dev->vq[index].call_fd);
dev->vq[index].call_fd = -1;
}
if (dev->vq[index].kick_fd != -1) {
close(dev->vq[index].kick_fd);
dispatcher_remove(&dev->dispatcher, dev->vq[index].kick_fd);
dev->vq[index].kick_fd = -1;
}
/* Reply */ /* Reply */
return 1; return 1;
} }
...@@ -965,6 +981,10 @@ vubr_set_vring_kick_exec(VubrDev *dev, VhostUserMsg *vmsg) ...@@ -965,6 +981,10 @@ vubr_set_vring_kick_exec(VubrDev *dev, VhostUserMsg *vmsg)
assert((u64_arg & VHOST_USER_VRING_NOFD_MASK) == 0); assert((u64_arg & VHOST_USER_VRING_NOFD_MASK) == 0);
assert(vmsg->fd_num == 1); assert(vmsg->fd_num == 1);
if (dev->vq[index].kick_fd != -1) {
close(dev->vq[index].kick_fd);
dispatcher_remove(&dev->dispatcher, dev->vq[index].kick_fd);
}
dev->vq[index].kick_fd = vmsg->fds[0]; dev->vq[index].kick_fd = vmsg->fds[0];
DPRINT("Got kick_fd: %d for vq: %d\n", vmsg->fds[0], index); DPRINT("Got kick_fd: %d for vq: %d\n", vmsg->fds[0], index);
...@@ -999,6 +1019,10 @@ vubr_set_vring_call_exec(VubrDev *dev, VhostUserMsg *vmsg) ...@@ -999,6 +1019,10 @@ vubr_set_vring_call_exec(VubrDev *dev, VhostUserMsg *vmsg)
assert((u64_arg & VHOST_USER_VRING_NOFD_MASK) == 0); assert((u64_arg & VHOST_USER_VRING_NOFD_MASK) == 0);
assert(vmsg->fd_num == 1); assert(vmsg->fd_num == 1);
if (dev->vq[index].call_fd != -1) {
close(dev->vq[index].call_fd);
dispatcher_remove(&dev->dispatcher, dev->vq[index].call_fd);
}
dev->vq[index].call_fd = vmsg->fds[0]; dev->vq[index].call_fd = vmsg->fds[0];
DPRINT("Got call_fd: %d for vq: %d\n", vmsg->fds[0], index); DPRINT("Got call_fd: %d for vq: %d\n", vmsg->fds[0], index);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册