[PATCH v1 7/7] iommufd/selftest: Cover invalid read counts on vEVENTQ FD
From: Nicolin Chen
Date: Mon Jun 01 2026 - 16:45:24 EST
The vEVENTQ file descriptor must reject reads whose buffer cannot hold
even one event record. Add selftest coverage that exercises both the
empty-queue path (the upfront size check) and the non-empty path (the
in-loop check that fires only after an event is fetched).
For iommufd_veventq_fops_read():
- count == 0 and count < sizeof(header) on an empty vEVENTQ both
return -EINVAL.
- count == 0 and count == sizeof(header) on a non-empty vEVENTQ
(event has trailing payload) both return -EINVAL.
Assisted-by: Claude:claude-opus-4-7
Signed-off-by: Nicolin Chen <nicolinc@xxxxxxxxxx>
---
tools/testing/selftests/iommu/iommufd.c | 17 +++++++++++++++++
1 file changed, 17 insertions(+)
diff --git a/tools/testing/selftests/iommu/iommufd.c b/tools/testing/selftests/iommu/iommufd.c
index 2e8a27dab0bb8..8d32b2f70beae 100644
--- a/tools/testing/selftests/iommu/iommufd.c
+++ b/tools/testing/selftests/iommu/iommufd.c
@@ -2980,6 +2980,8 @@ TEST_F(iommufd_viommu, vdevice_alloc)
uint32_t veventq_id;
uint32_t veventq_fd;
int prev_seq = -1;
+ size_t hdr_size = sizeof(struct iommufd_vevent_header);
+ char vbuf[64];
if (dev_id) {
/* Must allocate vdevice before attaching to a nested hwpt */
@@ -3006,11 +3008,26 @@ TEST_F(iommufd_viommu, vdevice_alloc)
test_err_veventq_alloc(EEXIST, viommu_id,
IOMMU_VEVENTQ_TYPE_SELFTEST, 2, NULL,
NULL);
+
+ /* Invalid read counts on an empty vEVENTQ */
+ ASSERT_EQ(-1, read(veventq_fd, vbuf, 0));
+ ASSERT_EQ(EINVAL, errno);
+ ASSERT_EQ(-1, read(veventq_fd, vbuf, hdr_size - 1));
+ ASSERT_EQ(EINVAL, errno);
+
/* Set vdev_id to 0x99, unset it, and set to 0x88 */
test_cmd_vdevice_alloc(viommu_id, dev_id, 0x99, &vdev_id);
test_cmd_mock_domain_replace(self->stdev_id,
self->nested_hwpt_id);
test_cmd_trigger_vevents(dev_id, 1);
+
+ /* Invalid read counts on a non-empty vEVENTQ */
+ ASSERT_EQ(-1, read(veventq_fd, vbuf, 0));
+ ASSERT_EQ(EINVAL, errno);
+ /* header fits but the event's payload doesn't */
+ ASSERT_EQ(-1, read(veventq_fd, vbuf, hdr_size));
+ ASSERT_EQ(EINVAL, errno);
+
test_cmd_read_vevents(veventq_fd, 1, 0x99, &prev_seq);
test_err_vdevice_alloc(EEXIST, viommu_id, dev_id, 0x99,
&vdev_id);
--
2.43.0