diff options
author | Thanos Makatos <thanos.makatos@nutanix.com> | 2020-12-14 05:39:50 -0500 |
---|---|---|
committer | Thanos Makatos <tmakatos@gmail.com> | 2020-12-14 11:38:41 +0000 |
commit | 6299ba17273e9bc7b020395cb85ebf77dba296cd (patch) | |
tree | 4a370141151609c915d7ab5656e01cc18a8de1c6 /lib | |
parent | 36d99cfd369b047b3d31ec3e7f02aa8507d9f06d (diff) | |
download | libvfio-user-6299ba17273e9bc7b020395cb85ebf77dba296cd.zip libvfio-user-6299ba17273e9bc7b020395cb85ebf77dba296cd.tar.gz libvfio-user-6299ba17273e9bc7b020395cb85ebf77dba296cd.tar.bz2 |
don't return memory allocated on the stack
Signed-off-by: Thanos Makatos <thanos.makatos@nutanix.com>
Diffstat (limited to 'lib')
-rw-r--r-- | lib/libvfio-user.c | 46 |
1 files changed, 30 insertions, 16 deletions
diff --git a/lib/libvfio-user.c b/lib/libvfio-user.c index af7a7bf..75ad41c 100644 --- a/lib/libvfio-user.c +++ b/lib/libvfio-user.c @@ -690,7 +690,7 @@ handle_region_access(vfu_ctx_t *vfu_ctx, uint32_t size, uint16_t cmd, if (cmd == VFIO_USER_REGION_READ) { *len += region_access->count; } - *data = malloc(*len); + *data = calloc(1, *len); if (*data == NULL) { return -ENOMEM; } @@ -878,8 +878,8 @@ exec_command(vfu_ctx_t *vfu_ctx, struct vfio_user_header *hdr, size_t size, bool *free_iovec_data) { int ret; - struct vfio_irq_info irq_info; - struct vfio_device_info dev_info; + struct vfio_irq_info *irq_info; + struct vfio_device_info *dev_info; struct vfio_region_info *dev_reg_info = NULL; void *cmd_data = NULL; @@ -937,10 +937,15 @@ exec_command(vfu_ctx_t *vfu_ctx, struct vfio_user_header *hdr, size_t size, fds, nr_fds, cmd_data); break; case VFIO_USER_DEVICE_GET_INFO: - ret = handle_device_get_info(vfu_ctx, hdr->msg_size, &dev_info); + dev_info = calloc(1, sizeof *dev_info); + if (dev_info == NULL) { + ret = -ENOMEM; + goto reply; + } + ret = handle_device_get_info(vfu_ctx, hdr->msg_size, dev_info); if (ret >= 0) { - _iovecs[1].iov_base = &dev_info; - _iovecs[1].iov_len = dev_info.argsz; + _iovecs[1].iov_base = dev_info; + _iovecs[1].iov_len = dev_info->argsz; *iovecs = _iovecs; *nr_iovecs = 2; } @@ -956,11 +961,16 @@ exec_command(vfu_ctx_t *vfu_ctx, struct vfio_user_header *hdr, size_t size, } break; case VFIO_USER_DEVICE_GET_IRQ_INFO: + irq_info = calloc(1, sizeof *irq_info); + if (irq_info == NULL) { + ret = -ENOMEM; + goto reply; + } ret = handle_device_get_irq_info(vfu_ctx, hdr->msg_size, cmd_data, - &irq_info); + irq_info); if (ret == 0) { - _iovecs[1].iov_base = &irq_info; - _iovecs[1].iov_len = sizeof irq_info; + _iovecs[1].iov_base = irq_info; + _iovecs[1].iov_len = sizeof *irq_info; *iovecs = _iovecs; *nr_iovecs = 2; } @@ -971,12 +981,14 @@ exec_command(vfu_ctx_t *vfu_ctx, struct vfio_user_header *hdr, size_t size, break; case VFIO_USER_REGION_READ: case VFIO_USER_REGION_WRITE: - *iovecs = _iovecs; ret = handle_region_access(vfu_ctx, hdr->msg_size, hdr->cmd, - &(*iovecs)[1].iov_base, - &(*iovecs)[1].iov_len, + &(_iovecs[1].iov_base), + &(_iovecs[1].iov_len), cmd_data); - *nr_iovecs = 2; + if (ret == 0) { + *iovecs = _iovecs; + *nr_iovecs = 2; + } break; case VFIO_USER_DEVICE_RESET: ret = handle_device_reset(vfu_ctx); @@ -1075,14 +1087,16 @@ process_request(vfu_ctx_t *vfu_ctx) ret = 0; } - if (iovecs != NULL && iovecs != _iovecs) { + if (iovecs != NULL) { if (free_iovec_data) { size_t i; - for (i = 0; i < nr_iovecs; i++) { + for (i = 1; i < nr_iovecs; i++) { free(iovecs[i].iov_base); } } - free(iovecs); + if (iovecs != _iovecs) { + free(iovecs); + } } return ret; |