aboutsummaryrefslogtreecommitdiff
path: root/lib/libvfio-user.c
diff options
context:
space:
mode:
authorJohn Levon <john.levon@nutanix.com>2021-02-16 16:11:35 +0000
committerGitHub <noreply@github.com>2021-02-16 16:11:35 +0000
commitb4baf039588830dfd580a59e7d05efbc65cb6d03 (patch)
treee54da2a141a202362c3313200de16d4bef35ca9b /lib/libvfio-user.c
parent4b8d6d3898c28ff87f32b59e48e7e73158e786f8 (diff)
downloadlibvfio-user-b4baf039588830dfd580a59e7d05efbc65cb6d03.zip
libvfio-user-b4baf039588830dfd580a59e7d05efbc65cb6d03.tar.gz
libvfio-user-b4baf039588830dfd580a59e7d05efbc65cb6d03.tar.bz2
fix DEVICE_GET_INFO specification and handling (#344)
The specification for DEVICE_GET_INFO differed from the implementation. After some discussion, fix the spec such that the struct should be passed in with ->argsz set. As it happened, the implementation was also wrong: we weren't actually checking the incoming ->argsz for validation, but we should. Signed-off-by: John Levon <john.levon@nutanix.com> Reviewed-by: Thanos Makatos <thanos.makatos@nutanix.com>
Diffstat (limited to 'lib/libvfio-user.c')
-rw-r--r--lib/libvfio-user.c27
1 files changed, 16 insertions, 11 deletions
diff --git a/lib/libvfio-user.c b/lib/libvfio-user.c
index 2dccd62..0125cef 100644
--- a/lib/libvfio-user.c
+++ b/lib/libvfio-user.c
@@ -427,23 +427,27 @@ handle_device_get_region_info(vfu_ctx_t *vfu_ctx, uint32_t size,
}
int
-handle_device_get_info(vfu_ctx_t *vfu_ctx, uint32_t size,
- struct vfio_device_info *dev_info)
+handle_device_get_info(vfu_ctx_t *vfu_ctx, uint32_t in_size,
+ struct vfio_device_info *in_dev_info,
+ struct vfio_device_info *out_dev_info)
{
assert(vfu_ctx != NULL);
- assert(dev_info != NULL);
+ assert(in_dev_info != NULL);
+ assert(out_dev_info != NULL);
- if (size < sizeof *dev_info) {
+ if (in_size < sizeof (*in_dev_info) ||
+ in_dev_info->argsz < sizeof (*in_dev_info)) {
return -EINVAL;
}
- dev_info->argsz = sizeof *dev_info;
- dev_info->flags = VFIO_DEVICE_FLAGS_PCI | VFIO_DEVICE_FLAGS_RESET;
- dev_info->num_regions = vfu_ctx->nr_regions;
- dev_info->num_irqs = VFU_DEV_NUM_IRQS;
+ out_dev_info->argsz = sizeof (*in_dev_info);
+ out_dev_info->flags = VFIO_DEVICE_FLAGS_PCI | VFIO_DEVICE_FLAGS_RESET;
+ out_dev_info->num_regions = vfu_ctx->nr_regions;
+ out_dev_info->num_irqs = VFU_DEV_NUM_IRQS;
- vfu_log(vfu_ctx, LOG_DEBUG, "sent devinfo flags %#x, num_regions %d, num_irqs"
- " %d", dev_info->flags, dev_info->num_regions, dev_info->num_irqs);
+ vfu_log(vfu_ctx, LOG_DEBUG, "devinfo flags %#x, num_regions %d, "
+ "num_irqs %d", out_dev_info->flags, out_dev_info->num_regions,
+ out_dev_info->num_irqs);
return 0;
}
@@ -789,7 +793,8 @@ exec_command(vfu_ctx_t *vfu_ctx, struct vfio_user_header *hdr, size_t size,
ret = -ENOMEM;
break;
}
- ret = handle_device_get_info(vfu_ctx, cmd_data_size, dev_info);
+ ret = handle_device_get_info(vfu_ctx, cmd_data_size, cmd_data,
+ dev_info);
if (ret >= 0) {
_iovecs[1].iov_base = dev_info;
_iovecs[1].iov_len = dev_info->argsz;