diff options
author | John Levon <john.levon@nutanix.com> | 2021-05-24 11:41:30 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-05-24 11:41:30 +0100 |
commit | 7443fbedd1f94288fbe0d3563b72c4938aa9ff2f (patch) | |
tree | afaad7d00e33409c3104d25ca18790960157f72d /lib/irq.c | |
parent | bf3938dec68e1c820063db4f63aa2355c5703e4b (diff) | |
download | libvfio-user-7443fbedd1f94288fbe0d3563b72c4938aa9ff2f.zip libvfio-user-7443fbedd1f94288fbe0d3563b72c4938aa9ff2f.tar.gz libvfio-user-7443fbedd1f94288fbe0d3563b72c4938aa9ff2f.tar.bz2 |
python tests: add VFIO_USER_DEVICE_SET_IRQS (#473)
Signed-off-by: John Levon <john.levon@nutanix.com>
Reviewed-by: Thanos Makatos <thanos.makatos@nutanix.com>
Diffstat (limited to 'lib/irq.c')
-rw-r--r-- | lib/irq.c | 32 |
1 files changed, 18 insertions, 14 deletions
@@ -190,9 +190,6 @@ irqs_set_data_bool(vfu_ctx_t *vfu_ctx, struct vfio_irq_set *irq_set, void *data) assert(data != NULL); - // FIXME: we don't check that data is actually within ->argsz, could - // dereference junk - for (i = irq_set->start, d8 = data; i < (irq_set->start + irq_set->count); i++, d8++) { efd = vfu_ctx->irqs->efds[i]; @@ -242,19 +239,31 @@ irqs_set_data_eventfd(vfu_ctx_t *vfu_ctx, struct vfio_irq_set *irq_set, } static int -device_set_irqs_validate(vfu_ctx_t *vfu_ctx, struct vfio_irq_set *irq_set, - size_t nr_fds) +device_set_irqs_validate(vfu_ctx_t *vfu_ctx, vfu_msg_t *msg) { + struct vfio_irq_set *irq_set = msg->in_data; uint32_t a_type, d_type; int line; assert(vfu_ctx != NULL); assert(irq_set != NULL); + if (msg->in_size < sizeof(*irq_set) || msg->in_size != irq_set->argsz) { + vfu_log(vfu_ctx, LOG_ERR, "bad size %zu", msg->in_size); + return ERROR_INT(EINVAL); + } + // Separate action and data types from flags. a_type = (irq_set->flags & VFIO_IRQ_SET_ACTION_TYPE_MASK); d_type = (irq_set->flags & VFIO_IRQ_SET_DATA_TYPE_MASK); + // bools provided must match count + if (d_type == VFIO_IRQ_SET_DATA_BOOL && + (msg->in_size - sizeof(*irq_set) != sizeof(uint8_t) * irq_set->count)) { + line = __LINE__; + goto invalid; + } + // Ensure index is within bounds. if (irq_set->index >= VFU_DEV_NUM_IRQS) { line = __LINE__; @@ -300,12 +309,12 @@ device_set_irqs_validate(vfu_ctx_t *vfu_ctx, struct vfio_irq_set *irq_set, goto invalid; } // If fd's are provided, ensure it's only for VFIO_IRQ_SET_DATA_EVENTFD - if (nr_fds != 0 && d_type != VFIO_IRQ_SET_DATA_EVENTFD) { + if (msg->nr_in_fds != 0 && d_type != VFIO_IRQ_SET_DATA_EVENTFD) { line = __LINE__; goto invalid; } // If fd's are provided, ensure they match ->count - if (nr_fds != 0 && nr_fds != irq_set->count) { + if (msg->nr_in_fds != 0 && msg->nr_in_fds != irq_set->count) { line = __LINE__; goto invalid; } @@ -315,7 +324,7 @@ device_set_irqs_validate(vfu_ctx_t *vfu_ctx, struct vfio_irq_set *irq_set, invalid: vfu_log(vfu_ctx, LOG_DEBUG, "invalid SET_IRQS (%d): action=%u data_type=%u " "index=%u start=%u count=%u nr_fds=%zu", line, a_type, d_type, - irq_set->index, irq_set->start, irq_set->count, nr_fds); + irq_set->index, irq_set->start, irq_set->count, msg->nr_in_fds); return ERROR_INT(EINVAL); } @@ -329,12 +338,7 @@ handle_device_set_irqs(vfu_ctx_t *vfu_ctx, vfu_msg_t *msg) assert(vfu_ctx != NULL); assert(msg != NULL); - if (msg->in_size < sizeof(*irq_set) || msg->in_size != irq_set->argsz) { - vfu_log(vfu_ctx, LOG_ERR, "bad size %zu", msg->in_size); - return ERROR_INT(EINVAL); - } - - ret = device_set_irqs_validate(vfu_ctx, irq_set, msg->nr_in_fds); + ret = device_set_irqs_validate(vfu_ctx, msg); if (ret != 0) { return ret; } |