diff options
author | Swapnil Ingle <swapnil.ingle@nutanix.com> | 2020-09-28 06:45:17 -0400 |
---|---|---|
committer | Swapnil Ingle <swapnil.ingle@nutanix.com> | 2020-09-28 06:45:17 -0400 |
commit | 217b60de1edac35460cab20cf812be8f2ec428f4 (patch) | |
tree | 108f543e8fccadc89ae47041eb6469fec19f538e | |
parent | 1d04b84719f443656badabdf672da592a4f85e59 (diff) | |
download | libvfio-user-217b60de1edac35460cab20cf812be8f2ec428f4.zip libvfio-user-217b60de1edac35460cab20cf812be8f2ec428f4.tar.gz libvfio-user-217b60de1edac35460cab20cf812be8f2ec428f4.tar.bz2 |
Fix handling of VFIO_USER_DEVICE_GET_INFO
vfio_device_info.argsz is set by the client and server is expected to
use/validate it.
Signed-off-by: Swapnil Ingle <swapnil.ingle@nutanix.com>
-rw-r--r-- | lib/libmuser.c | 34 | ||||
-rw-r--r-- | samples/client.c | 8 |
2 files changed, 27 insertions, 15 deletions
diff --git a/lib/libmuser.c b/lib/libmuser.c index 71d9ba2..b887afa 100644 --- a/lib/libmuser.c +++ b/lib/libmuser.c @@ -1643,23 +1643,27 @@ out: } static int handle_device_get_info(lm_ctx_t *lm_ctx, - struct vfio_user_header *hdr) + struct vfio_user_header *hdr, + struct vfio_device_info *dev_info) { - struct vfio_device_info dev_info; int ret; - dev_info.argsz = sizeof(struct vfio_device_info); + if ((hdr->msg_size - sizeof(*hdr)) != sizeof(*dev_info)) { + return -EINVAL; + } + + ret = recv(lm_ctx->conn_fd, dev_info, sizeof(*dev_info), 0); + if (ret < 0) { + return -errno; + } - ret = dev_get_info(&dev_info); + ret = dev_get_info(dev_info); if (ret < 0) { return ret; } - ret = send_vfio_user_msg(lm_ctx->conn_fd, hdr->msg_id, true, - VFIO_USER_DEVICE_GET_INFO, (void *)&dev_info, - dev_info.argsz, NULL, 0); lm_log(lm_ctx, LM_DBG, "sent devinfo flags %#x, num_regions %d, num_irqs" - " %d", dev_info.flags, dev_info.num_regions, dev_info.num_irqs); + " %d", dev_info->flags, dev_info->num_regions, dev_info->num_irqs); return ret; } @@ -1796,6 +1800,7 @@ process_request(lm_ctx_t *lm_ctx) int *fds = NULL; int nr_fds; struct vfio_irq_info irq_info; + struct vfio_device_info dev_info; void *data = NULL; int len; @@ -1844,8 +1849,11 @@ process_request(lm_ctx_t *lm_ctx) fds, nr_fds); break; case VFIO_USER_DEVICE_GET_INFO: - ret = handle_device_get_info(lm_ctx, &hdr); - goto out; + ret = handle_device_get_info(lm_ctx, &hdr, &dev_info); + if (ret == 0) { + data = &dev_info; + len = dev_info.argsz; + } break; case VFIO_USER_DEVICE_GET_IRQ_INFO: ret = handle_device_get_irq_info(lm_ctx, &hdr, &irq_info); @@ -1859,10 +1867,12 @@ process_request(lm_ctx_t *lm_ctx) return -EINVAL; } + /* + * TODO: In case of error during command handling set errno respectively + * in the reply message. + */ ret = send_vfio_user_msg(lm_ctx->conn_fd, hdr.msg_id, true, 0, data, len, NULL, 0); - -out: if (unlikely(ret < 0)) { lm_log(lm_ctx, LM_ERR, "failed to complete command: %s\n", strerror(-ret)); diff --git a/samples/client.c b/samples/client.c index e8afb11..9756141 100644 --- a/samples/client.c +++ b/samples/client.c @@ -94,7 +94,7 @@ set_version(int sock, int client_max_fds, int *server_max_fds) goto out; } - ret = send_version(sock, mj, mn, msg_id, true, client_caps); + ret = send_version(sock, mj, mn, msg_id, true, client_caps); if (ret < 0) { fprintf(stderr, "failed to send version to server: %s\n", strerror(-ret)); @@ -111,14 +111,16 @@ static int get_device_info(int sock) { struct vfio_user_header hdr; - struct vfio_device_info dev_info; + struct vfio_device_info dev_info = { + .argsz = sizeof(dev_info) + }; uint16_t msg_id; int ret; int size = sizeof dev_info; msg_id = 1; ret = send_vfio_user_msg(sock, msg_id, false, VFIO_USER_DEVICE_GET_INFO, - NULL, 0, NULL,0); + &dev_info, size, NULL,0); if (ret < 0) { fprintf(stderr, "%s: failed to send message: %s\n", __func__, strerror(-ret)); |