aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Levon <john.levon@nutanix.com>2023-10-02 14:06:38 +0100
committerGitHub <noreply@github.com>2023-10-02 14:06:38 +0100
commit8d38e8c57923f736ffc8215b7b237c76d240e3b4 (patch)
treefda7ef5d3223c51c391bd6b14915476a90de4416
parent7da33b5aaef3e1bafe530138451e53cda541a504 (diff)
downloadlibvfio-user-8d38e8c57923f736ffc8215b7b237c76d240e3b4.zip
libvfio-user-8d38e8c57923f736ffc8215b7b237c76d240e3b4.tar.gz
libvfio-user-8d38e8c57923f736ffc8215b7b237c76d240e3b4.tar.bz2
fix VFIO_USER_DEVICE_GET_REGION_IO_FDS allocation (#785)
clang-tidy static analysis identified a zero-sized allocation in the case that no ioregionfds had been configured. Fix this issue and add a test for it. Signed-off-by: John Levon <john.levon@nutanix.com> Reviewed-by: Thanos Makatos <thanos.makatos@nutanix.com>
-rw-r--r--lib/libvfio-user.c13
-rw-r--r--test/py/test_shadow_ioeventfd.py28
2 files changed, 37 insertions, 4 deletions
diff --git a/lib/libvfio-user.c b/lib/libvfio-user.c
index 47ae522..7f4d4ec 100644
--- a/lib/libvfio-user.c
+++ b/lib/libvfio-user.c
@@ -622,7 +622,8 @@ handle_device_get_region_io_fds(vfu_ctx_t *vfu_ctx, vfu_msg_t *msg)
sizeof(vfio_user_sub_region_ioeventfd_t);
msg->out.nr_fds = 0;
- if (req->argsz >= reply->argsz) {
+
+ if (max_sent_sub_regions > 0 && req->argsz >= reply->argsz) {
msg->out.fds = calloc(sizeof(int),
max_sent_sub_regions + nr_shadow_reg);
if (msg->out.fds == NULL) {
@@ -630,18 +631,22 @@ handle_device_get_region_io_fds(vfu_ctx_t *vfu_ctx, vfu_msg_t *msg)
}
sub_reg = LIST_FIRST(&vfu_reg->subregions);
+
for (i = 0; i < max_sent_sub_regions; i++) {
+ int fdi;
ioefd = &reply->sub_regions[i].ioeventfd;
ioefd->gpa_offset = sub_reg->gpa_offset;
ioefd->size = sub_reg->size;
- ioefd->fd_index = add_fd_index(msg->out.fds, &msg->out.nr_fds,
- sub_reg->fd);
+ fdi = add_fd_index(msg->out.fds, &msg->out.nr_fds, sub_reg->fd);
+ ioefd->fd_index = fdi;
if (sub_reg->shadow_fd == -1) {
ioefd->type = VFIO_USER_IO_FD_TYPE_IOEVENTFD;
} else {
ioefd->type = VFIO_USER_IO_FD_TYPE_IOEVENTFD_SHADOW;
- ioefd->shadow_mem_fd_index = add_fd_index(msg->out.fds, &msg->out.nr_fds, sub_reg->shadow_fd);
+ fdi = add_fd_index(msg->out.fds, &msg->out.nr_fds,
+ sub_reg->shadow_fd);
+ ioefd->shadow_mem_fd_index = fdi;
}
ioefd->flags = sub_reg->flags;
ioefd->datamatch = sub_reg->datamatch;
diff --git a/test/py/test_shadow_ioeventfd.py b/test/py/test_shadow_ioeventfd.py
index 1375769..3830b88 100644
--- a/test/py/test_shadow_ioeventfd.py
+++ b/test/py/test_shadow_ioeventfd.py
@@ -33,6 +33,34 @@ import mmap
import errno
+def test_shadow_ioeventfd_none():
+ """Test VFIO_USER_DEVICE_GET_REGION_IO_FDS when none are set up."""
+
+ # server setup
+ ctx = vfu_create_ctx(flags=LIBVFIO_USER_FLAG_ATTACH_NB)
+ assert ctx is not None
+ ret = vfu_setup_region(ctx, index=VFU_PCI_DEV_BAR0_REGION_IDX, size=0x1000,
+ flags=VFU_REGION_FLAG_RW)
+ assert ret == 0
+
+ ret = vfu_realize_ctx(ctx)
+ assert ret == 0
+
+ # client
+ client = connect_client(ctx)
+ payload = vfio_user_region_io_fds_request(
+ argsz=len(vfio_user_region_io_fds_reply()) +
+ len(vfio_user_sub_region_ioeventfd()), flags=0,
+ index=VFU_PCI_DEV_BAR0_REGION_IDX, count=0)
+ newfds, ret = msg_fds(ctx, client.sock, VFIO_USER_DEVICE_GET_REGION_IO_FDS,
+ payload, expect=0)
+ assert len(newfds) == 0
+ reply, ret = vfio_user_region_io_fds_reply.pop_from_buffer(ret)
+ assert reply.count == 0
+
+ vfu_destroy_ctx(ctx)
+
+
def test_shadow_ioeventfd():
"""Configure a shadow ioeventfd, have the client trigger it, confirm that
the server receives the notification and can see the value."""