aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorThanos Makatos <thanos.makatos@nutanix.com>2020-12-14 05:39:50 -0500
committerThanos Makatos <tmakatos@gmail.com>2020-12-14 11:38:41 +0000
commit6299ba17273e9bc7b020395cb85ebf77dba296cd (patch)
tree4a370141151609c915d7ab5656e01cc18a8de1c6 /lib
parent36d99cfd369b047b3d31ec3e7f02aa8507d9f06d (diff)
downloadlibvfio-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.c46
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;