]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
iommufd/selftest: Cover invalid read counts on vEVENTQ FD
authorNicolin Chen <nicolinc@nvidia.com>
Mon, 1 Jun 2026 20:42:38 +0000 (13:42 -0700)
committerJason Gunthorpe <jgg@nvidia.com>
Fri, 5 Jun 2026 14:07:12 +0000 (11:07 -0300)
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.

Link: https://patch.msgid.link/r/7bcd153d306f2cf04c094c728c0ebe146855072a.1780343944.git.nicolinc@nvidia.com
Assisted-by: Claude:claude-opus-4-7
Signed-off-by: Nicolin Chen <nicolinc@nvidia.com>
Reviewed-by: Pranjal Shrivastava <praan@google.com>
Reviewed-by: Kevin Tian <kevin.tian@intel.com>
Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
tools/testing/selftests/iommu/iommufd.c

index 2e8a27dab0bb8d72a7463519c48e006c6827bd9a..8d32b2f70beaebf64d8d1a50cfc6159e735688de 100644 (file)
@@ -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);