DM: virtio_rnd: fix rnd->fd and vbs_k->fd leak

Previously, either rnd->fd or vbs_k->fd isn't be closed in some cases.
this patch will close them in time.

V2: fix vbs_k->fd leak as well

Signed-off-by: Li Zhijian <lizhijian@cn.fujitsu.com>
This commit is contained in:
Li Zhijian 2018-06-26 16:21:16 +08:00 committed by Xie, nanlin
parent 789899d05f
commit fcbc56439c

View File

@ -333,7 +333,7 @@ virtio_rnd_notify(void *base, struct virtio_vq_info *vq)
static int static int
virtio_rnd_init(struct vmctx *ctx, struct pci_vdev *dev, char *opts) virtio_rnd_init(struct vmctx *ctx, struct pci_vdev *dev, char *opts)
{ {
struct virtio_rnd *rnd; struct virtio_rnd *rnd = NULL;
int fd; int fd;
int len; int len;
uint8_t v; uint8_t v;
@ -367,13 +367,13 @@ virtio_rnd_init(struct vmctx *ctx, struct pci_vdev *dev, char *opts)
len = read(fd, &v, sizeof(v)); len = read(fd, &v, sizeof(v));
if (len <= 0) { if (len <= 0) {
WPRINTF(("virtio_rnd: /dev/random not ready, read(): %d", len)); WPRINTF(("virtio_rnd: /dev/random not ready, read(): %d", len));
return -1; goto fail;
} }
rnd = calloc(1, sizeof(struct virtio_rnd)); rnd = calloc(1, sizeof(struct virtio_rnd));
if (!rnd) { if (!rnd) {
WPRINTF(("virtio_rnd: calloc returns NULL\n")); WPRINTF(("virtio_rnd: calloc returns NULL\n"));
return -1; goto fail;
} }
rnd->vbs_k.status = kstat; rnd->vbs_k.status = kstat;
@ -431,14 +431,23 @@ virtio_rnd_init(struct vmctx *ctx, struct pci_vdev *dev, char *opts)
pci_set_cfgdata16(dev, PCIR_SUBVEND_0, VIRTIO_VENDOR); pci_set_cfgdata16(dev, PCIR_SUBVEND_0, VIRTIO_VENDOR);
if (virtio_interrupt_init(&rnd->base, virtio_uses_msix())) { if (virtio_interrupt_init(&rnd->base, virtio_uses_msix())) {
if (rnd) goto fail;
free(rnd);
return -1;
} }
virtio_set_io_bar(&rnd->base, 0); virtio_set_io_bar(&rnd->base, 0);
return 0; return 0;
fail:
close(fd);
if (rnd) {
if (rnd->vbs_k.status == VIRTIO_DEV_INIT_SUCCESS) {
/* VBS-K is in use */
close(rnd->vbs_k.fd);
}
free(rnd);
}
return -1;
} }
static void static void
@ -462,6 +471,8 @@ virtio_rnd_deinit(struct vmctx *ctx, struct pci_vdev *dev, char *opts)
rnd->vbs_k.fd = -1; rnd->vbs_k.fd = -1;
} }
assert(rnd->fd >= 0);
close(rnd->fd);
DPRINTF(("%s: free struct virtio_rnd!\n", __func__)); DPRINTF(("%s: free struct virtio_rnd!\n", __func__));
free(rnd); free(rnd);
} }