diff options
| author | Nicolin Chen <nicolinc@nvidia.com> | 2026-06-01 13:42:33 -0700 |
|---|---|---|
| committer | Jason Gunthorpe <jgg@nvidia.com> | 2026-06-05 11:07:11 -0300 |
| commit | 00203ca8323f9714630408c19a209b52397975e6 (patch) | |
| tree | 1c2fa7b15d36adc84571e19a004d8609f9884b93 | |
| parent | 01e41ad76c12ae5c49ab4ef4fc7dd54e9b8784d6 (diff) | |
iommufd: Reject invalid read count in iommufd_veventq_fops_read()
The read count must be large enough to hold a vEVENT header. For a normal
vEVENT, it must also hold the trailing data following the header.
iommufd_veventq_fops_read() does not validate the count, but returns 0 as
if the read had succeeded while leaving the pending event in the queue.
Return -EINVAL in both undersize cases.
Fixes: e36ba5ab808e ("iommufd: Add IOMMUFD_OBJ_VEVENTQ and IOMMUFD_CMD_VEVENTQ_ALLOC")
Link: https://patch.msgid.link/r/e1111adcc8a8882fbfd84accd6674dc846dc5689.1780343944.git.nicolinc@nvidia.com
Cc: stable@vger.kernel.org
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>
| -rw-r--r-- | drivers/iommu/iommufd/eventq.c | 6 |
1 files changed, 6 insertions, 0 deletions
diff --git a/drivers/iommu/iommufd/eventq.c b/drivers/iommu/iommufd/eventq.c index 896f45be0d2e..ac485d010a43 100644 --- a/drivers/iommu/iommufd/eventq.c +++ b/drivers/iommu/iommufd/eventq.c @@ -310,6 +310,9 @@ static ssize_t iommufd_veventq_fops_read(struct file *filep, char __user *buf, if (*ppos) return -ESPIPE; + /* Minimum read count is a vEVENT header */ + if (count < sizeof(*hdr)) + return -EINVAL; while ((cur = iommufd_veventq_deliver_fetch(veventq))) { /* Validate the remaining bytes against the header size */ @@ -323,6 +326,9 @@ static ssize_t iommufd_veventq_fops_read(struct file *filep, char __user *buf, if (!vevent_for_lost_events_header(cur) && sizeof(*hdr) + cur->data_len > count - done) { iommufd_veventq_deliver_restore(veventq, cur); + /* Read count doesn't fit a single normal vEVENT */ + if (done == 0) + rc = -EINVAL; break; } |
