* [PATCH v1 0/7] iommufd: Fix bugs in eventq fops_read paths
@ 2026-06-01 20:42 Nicolin Chen
2026-06-01 20:42 ` [PATCH v1 1/7] iommufd: Rewind header length in done if iommufd_veventq_fops_read() fails Nicolin Chen
` (9 more replies)
0 siblings, 10 replies; 18+ messages in thread
From: Nicolin Chen @ 2026-06-01 20:42 UTC (permalink / raw)
To: jgg, kevin.tian; +Cc: joro, baolu.lu, iommu, linux-kernel, linux-kselftest
Bugs were found in iommufd_veventq/fault_fops_read(), where userspace may:
- Receive a corrupted byte stream after a partial copy_to_user
- Spin in a poll/read loop when reading with an undersized buffer
- Miss notifications when the kernel cannot allocate a lost-events copy
- Receive duplicate faults with stale cookies after a mid-group failure
- Cause the kernel to retry the same failed copy_to_user indefinitely
Fix them, then add selftest coverage for the vEVENTQ count validation.
This is on github:
https://github.com/nicolinc/iommufd/commits/fix_eventq_read_bugs-v1
Rebased on Jason's for-next tree with the veventq_depth series applied.
Nicolin Chen (7):
iommufd: Rewind header length in done if iommufd_veventq_fops_read()
fails
iommufd: Reject invalid read count in iommufd_veventq_fops_read()
iommufd: Propagate allocation failure in
iommufd_veventq_deliver_fetch()
iommufd: Reject invalid read count in iommufd_fault_fops_read()
iommufd: Break the loop on failure in iommufd_fault_fops_read()
iommufd: Avoid partial fault group delivery in
iommufd_fault_fops_read()
iommufd/selftest: Cover invalid read counts on vEVENTQ FD
drivers/iommu/iommufd/eventq.c | 29 ++++++++++++++++++++++---
tools/testing/selftests/iommu/iommufd.c | 17 +++++++++++++++
2 files changed, 43 insertions(+), 3 deletions(-)
base-commit: f25989c19028e8bf81e26e1133a99e3436c3afc2
--
2.43.0
^ permalink raw reply [flat|nested] 18+ messages in thread
* [PATCH v1 1/7] iommufd: Rewind header length in done if iommufd_veventq_fops_read() fails
2026-06-01 20:42 [PATCH v1 0/7] iommufd: Fix bugs in eventq fops_read paths Nicolin Chen
@ 2026-06-01 20:42 ` Nicolin Chen
2026-06-03 14:01 ` Pranjal Shrivastava
2026-06-01 20:42 ` [PATCH v1 2/7] iommufd: Reject invalid read count in iommufd_veventq_fops_read() Nicolin Chen
` (8 subsequent siblings)
9 siblings, 1 reply; 18+ messages in thread
From: Nicolin Chen @ 2026-06-01 20:42 UTC (permalink / raw)
To: jgg, kevin.tian; +Cc: joro, baolu.lu, iommu, linux-kernel, linux-kselftest
When the first event copy fails, rc = -EFAULT will not be reported as done
is set to the length of the copied header.
Rewind it to report rc correctly.
Fixes: e36ba5ab808e ("iommufd: Add IOMMUFD_OBJ_VEVENTQ and IOMMUFD_CMD_VEVENTQ_ALLOC")
Cc: stable@vger.kernel.org
Signed-off-by: Nicolin Chen <nicolinc@nvidia.com>
---
drivers/iommu/iommufd/eventq.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/iommu/iommufd/eventq.c b/drivers/iommu/iommufd/eventq.c
index 1f1e415285b1a..896f45be0d2ee 100644
--- a/drivers/iommu/iommufd/eventq.c
+++ b/drivers/iommu/iommufd/eventq.c
@@ -336,6 +336,7 @@ static ssize_t iommufd_veventq_fops_read(struct file *filep, char __user *buf,
if (cur->data_len &&
copy_to_user(buf + done, cur->event_data, cur->data_len)) {
iommufd_veventq_deliver_restore(veventq, cur);
+ done -= sizeof(*hdr);
rc = -EFAULT;
break;
}
--
2.43.0
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [PATCH v1 2/7] iommufd: Reject invalid read count in iommufd_veventq_fops_read()
2026-06-01 20:42 [PATCH v1 0/7] iommufd: Fix bugs in eventq fops_read paths Nicolin Chen
2026-06-01 20:42 ` [PATCH v1 1/7] iommufd: Rewind header length in done if iommufd_veventq_fops_read() fails Nicolin Chen
@ 2026-06-01 20:42 ` Nicolin Chen
2026-06-03 14:08 ` Pranjal Shrivastava
2026-06-01 20:42 ` [PATCH v1 3/7] iommufd: Propagate allocation failure in iommufd_veventq_deliver_fetch() Nicolin Chen
` (7 subsequent siblings)
9 siblings, 1 reply; 18+ messages in thread
From: Nicolin Chen @ 2026-06-01 20:42 UTC (permalink / raw)
To: jgg, kevin.tian; +Cc: joro, baolu.lu, iommu, linux-kernel, linux-kselftest
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")
Cc: stable@vger.kernel.org
Signed-off-by: Nicolin Chen <nicolinc@nvidia.com>
---
drivers/iommu/iommufd/eventq.c | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/drivers/iommu/iommufd/eventq.c b/drivers/iommu/iommufd/eventq.c
index 896f45be0d2ee..ac485d010a439 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;
}
--
2.43.0
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [PATCH v1 3/7] iommufd: Propagate allocation failure in iommufd_veventq_deliver_fetch()
2026-06-01 20:42 [PATCH v1 0/7] iommufd: Fix bugs in eventq fops_read paths Nicolin Chen
2026-06-01 20:42 ` [PATCH v1 1/7] iommufd: Rewind header length in done if iommufd_veventq_fops_read() fails Nicolin Chen
2026-06-01 20:42 ` [PATCH v1 2/7] iommufd: Reject invalid read count in iommufd_veventq_fops_read() Nicolin Chen
@ 2026-06-01 20:42 ` Nicolin Chen
2026-06-03 14:13 ` Pranjal Shrivastava
2026-06-01 20:42 ` [PATCH v1 4/7] iommufd: Reject invalid read count in iommufd_fault_fops_read() Nicolin Chen
` (6 subsequent siblings)
9 siblings, 1 reply; 18+ messages in thread
From: Nicolin Chen @ 2026-06-01 20:42 UTC (permalink / raw)
To: jgg, kevin.tian; +Cc: joro, baolu.lu, iommu, linux-kernel, linux-kselftest
When the kzalloc_obj() fails in iommufd_veventq_deliver_fetch(), it returns
NULL, falsely advertising to userspace that the queue is empty.
Propagate the -ENOMEM properly to the caller.
Fixes: e36ba5ab808e ("iommufd: Add IOMMUFD_OBJ_VEVENTQ and IOMMUFD_CMD_VEVENTQ_ALLOC")
Cc: stable@vger.kernel.org
Signed-off-by: Nicolin Chen <nicolinc@nvidia.com>
---
drivers/iommu/iommufd/eventq.c | 10 +++++++++-
1 file changed, 9 insertions(+), 1 deletion(-)
diff --git a/drivers/iommu/iommufd/eventq.c b/drivers/iommu/iommufd/eventq.c
index ac485d010a439..f55d173c59f61 100644
--- a/drivers/iommu/iommufd/eventq.c
+++ b/drivers/iommu/iommufd/eventq.c
@@ -264,8 +264,10 @@ iommufd_veventq_deliver_fetch(struct iommufd_veventq *veventq)
/* Make a copy of the lost_events_header for copy_to_user */
if (next == &veventq->lost_events_header) {
vevent = kzalloc_obj(*vevent, GFP_ATOMIC);
- if (!vevent)
+ if (!vevent) {
+ vevent = ERR_PTR(-ENOMEM);
goto out_unlock;
+ }
}
list_del(&next->node);
if (vevent)
@@ -315,6 +317,12 @@ static ssize_t iommufd_veventq_fops_read(struct file *filep, char __user *buf,
return -EINVAL;
while ((cur = iommufd_veventq_deliver_fetch(veventq))) {
+ if (IS_ERR(cur)) {
+ if (done == 0)
+ rc = PTR_ERR(cur);
+ break;
+ }
+
/* Validate the remaining bytes against the header size */
if (done >= count || sizeof(*hdr) > count - done) {
iommufd_veventq_deliver_restore(veventq, cur);
--
2.43.0
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [PATCH v1 4/7] iommufd: Reject invalid read count in iommufd_fault_fops_read()
2026-06-01 20:42 [PATCH v1 0/7] iommufd: Fix bugs in eventq fops_read paths Nicolin Chen
` (2 preceding siblings ...)
2026-06-01 20:42 ` [PATCH v1 3/7] iommufd: Propagate allocation failure in iommufd_veventq_deliver_fetch() Nicolin Chen
@ 2026-06-01 20:42 ` Nicolin Chen
2026-06-03 14:15 ` Pranjal Shrivastava
2026-06-01 20:42 ` [PATCH v1 5/7] iommufd: Break the loop on failure " Nicolin Chen
` (5 subsequent siblings)
9 siblings, 1 reply; 18+ messages in thread
From: Nicolin Chen @ 2026-06-01 20:42 UTC (permalink / raw)
To: jgg, kevin.tian; +Cc: joro, baolu.lu, iommu, linux-kernel, linux-kselftest
The read count must be large enough to hold one fault or a group's faults.
iommufd_fault_fops_read() does not validate the count, but returns 0 as if
the read had succeeded while leaving the pending fault in the queue.
Return -EINVAL in the undersize cases.
Fixes: 07838f7fd529 ("iommufd: Add iommufd fault object")
Cc: stable@vger.kernel.org
Signed-off-by: Nicolin Chen <nicolinc@nvidia.com>
---
drivers/iommu/iommufd/eventq.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/drivers/iommu/iommufd/eventq.c b/drivers/iommu/iommufd/eventq.c
index f55d173c59f61..613024ca8f1ff 100644
--- a/drivers/iommu/iommufd/eventq.c
+++ b/drivers/iommu/iommufd/eventq.c
@@ -142,6 +142,9 @@ static ssize_t iommufd_fault_fops_read(struct file *filep, char __user *buf,
if (done >= count ||
group->fault_count * fault_size > count - done) {
iommufd_fault_deliver_restore(fault, group);
+ /* Read count doesn't fit the first fault group */
+ if (done == 0)
+ rc = -EINVAL;
break;
}
--
2.43.0
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [PATCH v1 5/7] iommufd: Break the loop on failure in iommufd_fault_fops_read()
2026-06-01 20:42 [PATCH v1 0/7] iommufd: Fix bugs in eventq fops_read paths Nicolin Chen
` (3 preceding siblings ...)
2026-06-01 20:42 ` [PATCH v1 4/7] iommufd: Reject invalid read count in iommufd_fault_fops_read() Nicolin Chen
@ 2026-06-01 20:42 ` Nicolin Chen
2026-06-03 14:18 ` Pranjal Shrivastava
2026-06-01 20:42 ` [PATCH v1 6/7] iommufd: Avoid partial fault group delivery " Nicolin Chen
` (4 subsequent siblings)
9 siblings, 1 reply; 18+ messages in thread
From: Nicolin Chen @ 2026-06-01 20:42 UTC (permalink / raw)
To: jgg, kevin.tian; +Cc: joro, baolu.lu, iommu, linux-kernel, linux-kselftest
On a copy_to_user() failure inside the inner list_for_each_entry, only the
inner loop breaks; the outer while re-fetches the just-restored fault group
and retries the failing copy_to_user() forever, spinning the reader at 100%
CPU with fault->mutex held.
Check rc after the inner loop and break the outer while as well.
Fixes: 07838f7fd529 ("iommufd: Add iommufd fault object")
Cc: stable@vger.kernel.org
Signed-off-by: Nicolin Chen <nicolinc@nvidia.com>
---
drivers/iommu/iommufd/eventq.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/drivers/iommu/iommufd/eventq.c b/drivers/iommu/iommufd/eventq.c
index 613024ca8f1ff..1c010e691f972 100644
--- a/drivers/iommu/iommufd/eventq.c
+++ b/drivers/iommu/iommufd/eventq.c
@@ -168,6 +168,8 @@ static ssize_t iommufd_fault_fops_read(struct file *filep, char __user *buf,
}
done += fault_size;
}
+ if (rc)
+ break;
}
mutex_unlock(&fault->mutex);
--
2.43.0
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [PATCH v1 6/7] iommufd: Avoid partial fault group delivery in iommufd_fault_fops_read()
2026-06-01 20:42 [PATCH v1 0/7] iommufd: Fix bugs in eventq fops_read paths Nicolin Chen
` (4 preceding siblings ...)
2026-06-01 20:42 ` [PATCH v1 5/7] iommufd: Break the loop on failure " Nicolin Chen
@ 2026-06-01 20:42 ` Nicolin Chen
2026-06-03 14:26 ` Pranjal Shrivastava
2026-06-01 20:42 ` [PATCH v1 7/7] iommufd/selftest: Cover invalid read counts on vEVENTQ FD Nicolin Chen
` (3 subsequent siblings)
9 siblings, 1 reply; 18+ messages in thread
From: Nicolin Chen @ 2026-06-01 20:42 UTC (permalink / raw)
To: jgg, kevin.tian; +Cc: joro, baolu.lu, iommu, linux-kernel, linux-kselftest
The cookie returned by xa_alloc() in iommufd_fault_fops_read() is per fault
group, but the inner copy_to_user() runs per fault inside the group. If a
copy fails mid-group, xa_erase clears the cookie and the group is restored
to the deliver list, yet done is not rolled back. The function returns the
partial byte count, with the successfully copied faults sitting at offsets
below done carrying the now-erased cookie. The next read() then re-fetches
the group, allocates a fresh cookie, and re-delivers every fault including
the ones already copied; userspace sees duplicates carrying the new cookie,
and a stale cookie that can never be responded to.
Use a local group_done variable that tracks the per-group progress inside
the inner loop, and only commit done = group_done after the inner loop has
finished successfully. On a copy_to_user failure the outer break skips the
commit, so done remains at its prior start-of-group baseline; the partial
bytes already written past done are undefined to userspace per the read(2)
contract, and the next read re-delivers the whole group atomically.
Fixes: 07838f7fd529 ("iommufd: Add iommufd fault object")
Cc: stable@vger.kernel.org
Assisted-by: Claude:claude-opus-4-7
Signed-off-by: Nicolin Chen <nicolinc@nvidia.com>
---
drivers/iommu/iommufd/eventq.c | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/drivers/iommu/iommufd/eventq.c b/drivers/iommu/iommufd/eventq.c
index 1c010e691f972..5129e3bf5461c 100644
--- a/drivers/iommu/iommufd/eventq.c
+++ b/drivers/iommu/iommufd/eventq.c
@@ -139,6 +139,8 @@ static ssize_t iommufd_fault_fops_read(struct file *filep, char __user *buf,
mutex_lock(&fault->mutex);
while ((group = iommufd_fault_deliver_fetch(fault))) {
+ size_t group_done = done;
+
if (done >= count ||
group->fault_count * fault_size > count - done) {
iommufd_fault_deliver_restore(fault, group);
@@ -160,16 +162,17 @@ static ssize_t iommufd_fault_fops_read(struct file *filep, char __user *buf,
iommufd_compose_fault_message(&iopf->fault,
&data, idev,
group->cookie);
- if (copy_to_user(buf + done, &data, fault_size)) {
+ if (copy_to_user(buf + group_done, &data, fault_size)) {
xa_erase(&fault->response, group->cookie);
iommufd_fault_deliver_restore(fault, group);
rc = -EFAULT;
break;
}
- done += fault_size;
+ group_done += fault_size;
}
if (rc)
break;
+ done = group_done;
}
mutex_unlock(&fault->mutex);
--
2.43.0
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [PATCH v1 7/7] iommufd/selftest: Cover invalid read counts on vEVENTQ FD
2026-06-01 20:42 [PATCH v1 0/7] iommufd: Fix bugs in eventq fops_read paths Nicolin Chen
` (5 preceding siblings ...)
2026-06-01 20:42 ` [PATCH v1 6/7] iommufd: Avoid partial fault group delivery " Nicolin Chen
@ 2026-06-01 20:42 ` Nicolin Chen
2026-06-03 14:46 ` Pranjal Shrivastava
2026-06-02 6:27 ` [PATCH v1 0/7] iommufd: Fix bugs in eventq fops_read paths Nicolin Chen
` (2 subsequent siblings)
9 siblings, 1 reply; 18+ messages in thread
From: Nicolin Chen @ 2026-06-01 20:42 UTC (permalink / raw)
To: jgg, kevin.tian; +Cc: joro, baolu.lu, iommu, linux-kernel, linux-kselftest
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@nvidia.com>
---
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
^ permalink raw reply related [flat|nested] 18+ messages in thread
* Re: [PATCH v1 0/7] iommufd: Fix bugs in eventq fops_read paths
2026-06-01 20:42 [PATCH v1 0/7] iommufd: Fix bugs in eventq fops_read paths Nicolin Chen
` (6 preceding siblings ...)
2026-06-01 20:42 ` [PATCH v1 7/7] iommufd/selftest: Cover invalid read counts on vEVENTQ FD Nicolin Chen
@ 2026-06-02 6:27 ` Nicolin Chen
2026-06-03 6:59 ` Tian, Kevin
2026-06-05 14:30 ` Jason Gunthorpe
9 siblings, 0 replies; 18+ messages in thread
From: Nicolin Chen @ 2026-06-02 6:27 UTC (permalink / raw)
To: jgg, kevin.tian; +Cc: joro, baolu.lu, iommu, linux-kernel, linux-kselftest
On Mon, Jun 01, 2026 at 01:42:31PM -0700, Nicolin Chen wrote:
> Bugs were found in iommufd_veventq/fault_fops_read(), where userspace may:
> - Receive a corrupted byte stream after a partial copy_to_user
> - Spin in a poll/read loop when reading with an undersized buffer
> - Miss notifications when the kernel cannot allocate a lost-events copy
> - Receive duplicate faults with stale cookies after a mid-group failure
> - Cause the kernel to retry the same failed copy_to_user indefinitely
>
> Fix them, then add selftest coverage for the vEVENTQ count validation.
>
> This is on github:
> https://github.com/nicolinc/iommufd/commits/fix_eventq_read_bugs-v1
>
> Rebased on Jason's for-next tree with the veventq_depth series applied.
[...]
> base-commit: f25989c19028e8bf81e26e1133a99e3436c3afc2
I realized that I sent this too fast, before Jason's for-next tree
is available in linux-next. So maybe this is why Sashiko failed to
review.
FWIW, I've done a local Sashiko review, which came out clean. But,
maybe we can respin a v2 once it collects some comments and tags.
Thanks
Nicolin
^ permalink raw reply [flat|nested] 18+ messages in thread
* RE: [PATCH v1 0/7] iommufd: Fix bugs in eventq fops_read paths
2026-06-01 20:42 [PATCH v1 0/7] iommufd: Fix bugs in eventq fops_read paths Nicolin Chen
` (7 preceding siblings ...)
2026-06-02 6:27 ` [PATCH v1 0/7] iommufd: Fix bugs in eventq fops_read paths Nicolin Chen
@ 2026-06-03 6:59 ` Tian, Kevin
2026-06-05 14:30 ` Jason Gunthorpe
9 siblings, 0 replies; 18+ messages in thread
From: Tian, Kevin @ 2026-06-03 6:59 UTC (permalink / raw)
To: Nicolin Chen, jgg@nvidia.com
Cc: joro@8bytes.org, baolu.lu@linux.intel.com, iommu@lists.linux.dev,
linux-kernel@vger.kernel.org, linux-kselftest@vger.kernel.org
> From: Nicolin Chen <nicolinc@nvidia.com>
> Sent: Tuesday, June 2, 2026 4:43 AM
>
> Bugs were found in iommufd_veventq/fault_fops_read(), where userspace
> may:
> - Receive a corrupted byte stream after a partial copy_to_user
> - Spin in a poll/read loop when reading with an undersized buffer
> - Miss notifications when the kernel cannot allocate a lost-events copy
> - Receive duplicate faults with stale cookies after a mid-group failure
> - Cause the kernel to retry the same failed copy_to_user indefinitely
>
> Fix them, then add selftest coverage for the vEVENTQ count validation.
>
for the whole series:
Reviewed-by: Kevin Tian <kevin.tian@intel.com>
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH v1 1/7] iommufd: Rewind header length in done if iommufd_veventq_fops_read() fails
2026-06-01 20:42 ` [PATCH v1 1/7] iommufd: Rewind header length in done if iommufd_veventq_fops_read() fails Nicolin Chen
@ 2026-06-03 14:01 ` Pranjal Shrivastava
0 siblings, 0 replies; 18+ messages in thread
From: Pranjal Shrivastava @ 2026-06-03 14:01 UTC (permalink / raw)
To: Nicolin Chen
Cc: jgg, kevin.tian, joro, baolu.lu, iommu, linux-kernel,
linux-kselftest
On Mon, Jun 01, 2026 at 01:42:32PM -0700, Nicolin Chen wrote:
> When the first event copy fails, rc = -EFAULT will not be reported as done
> is set to the length of the copied header.
>
> Rewind it to report rc correctly.
>
> Fixes: e36ba5ab808e ("iommufd: Add IOMMUFD_OBJ_VEVENTQ and IOMMUFD_CMD_VEVENTQ_ALLOC")
> Cc: stable@vger.kernel.org
> Signed-off-by: Nicolin Chen <nicolinc@nvidia.com>
> ---
> drivers/iommu/iommufd/eventq.c | 1 +
> 1 file changed, 1 insertion(+)
>
> diff --git a/drivers/iommu/iommufd/eventq.c b/drivers/iommu/iommufd/eventq.c
> index 1f1e415285b1a..896f45be0d2ee 100644
> --- a/drivers/iommu/iommufd/eventq.c
> +++ b/drivers/iommu/iommufd/eventq.c
> @@ -336,6 +336,7 @@ static ssize_t iommufd_veventq_fops_read(struct file *filep, char __user *buf,
> if (cur->data_len &&
> copy_to_user(buf + done, cur->event_data, cur->data_len)) {
> iommufd_veventq_deliver_restore(veventq, cur);
> + done -= sizeof(*hdr);
> rc = -EFAULT;
> break;
> }
Reviewed-by: Pranjal Shrivastava <praan@google.com>
Thanks,
Praan
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH v1 2/7] iommufd: Reject invalid read count in iommufd_veventq_fops_read()
2026-06-01 20:42 ` [PATCH v1 2/7] iommufd: Reject invalid read count in iommufd_veventq_fops_read() Nicolin Chen
@ 2026-06-03 14:08 ` Pranjal Shrivastava
0 siblings, 0 replies; 18+ messages in thread
From: Pranjal Shrivastava @ 2026-06-03 14:08 UTC (permalink / raw)
To: Nicolin Chen
Cc: jgg, kevin.tian, joro, baolu.lu, iommu, linux-kernel,
linux-kselftest
On Mon, Jun 01, 2026 at 01:42:33PM -0700, Nicolin Chen wrote:
> 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")
> Cc: stable@vger.kernel.org
> Signed-off-by: Nicolin Chen <nicolinc@nvidia.com>
Reviewed-by: Pranjal Shrivastava <praan@google.com>
Thanks,
Praan
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH v1 3/7] iommufd: Propagate allocation failure in iommufd_veventq_deliver_fetch()
2026-06-01 20:42 ` [PATCH v1 3/7] iommufd: Propagate allocation failure in iommufd_veventq_deliver_fetch() Nicolin Chen
@ 2026-06-03 14:13 ` Pranjal Shrivastava
0 siblings, 0 replies; 18+ messages in thread
From: Pranjal Shrivastava @ 2026-06-03 14:13 UTC (permalink / raw)
To: Nicolin Chen
Cc: jgg, kevin.tian, joro, baolu.lu, iommu, linux-kernel,
linux-kselftest
On Mon, Jun 01, 2026 at 01:42:34PM -0700, Nicolin Chen wrote:
> When the kzalloc_obj() fails in iommufd_veventq_deliver_fetch(), it returns
> NULL, falsely advertising to userspace that the queue is empty.
>
> Propagate the -ENOMEM properly to the caller.
>
> Fixes: e36ba5ab808e ("iommufd: Add IOMMUFD_OBJ_VEVENTQ and IOMMUFD_CMD_VEVENTQ_ALLOC")
> Cc: stable@vger.kernel.org
> Signed-off-by: Nicolin Chen <nicolinc@nvidia.com>
Reviewed-by: Pranjal Shrivastava <praan@google.com>
Thanks,
Praan
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH v1 4/7] iommufd: Reject invalid read count in iommufd_fault_fops_read()
2026-06-01 20:42 ` [PATCH v1 4/7] iommufd: Reject invalid read count in iommufd_fault_fops_read() Nicolin Chen
@ 2026-06-03 14:15 ` Pranjal Shrivastava
0 siblings, 0 replies; 18+ messages in thread
From: Pranjal Shrivastava @ 2026-06-03 14:15 UTC (permalink / raw)
To: Nicolin Chen
Cc: jgg, kevin.tian, joro, baolu.lu, iommu, linux-kernel,
linux-kselftest
On Mon, Jun 01, 2026 at 01:42:35PM -0700, Nicolin Chen wrote:
> The read count must be large enough to hold one fault or a group's faults.
>
> iommufd_fault_fops_read() does not validate the count, but returns 0 as if
> the read had succeeded while leaving the pending fault in the queue.
>
> Return -EINVAL in the undersize cases.
>
> Fixes: 07838f7fd529 ("iommufd: Add iommufd fault object")
> Cc: stable@vger.kernel.org
> Signed-off-by: Nicolin Chen <nicolinc@nvidia.com>
Reviewed-by: Pranjal Shrivastava <praan@google.com>
Thanks,
Praan
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH v1 5/7] iommufd: Break the loop on failure in iommufd_fault_fops_read()
2026-06-01 20:42 ` [PATCH v1 5/7] iommufd: Break the loop on failure " Nicolin Chen
@ 2026-06-03 14:18 ` Pranjal Shrivastava
0 siblings, 0 replies; 18+ messages in thread
From: Pranjal Shrivastava @ 2026-06-03 14:18 UTC (permalink / raw)
To: Nicolin Chen
Cc: jgg, kevin.tian, joro, baolu.lu, iommu, linux-kernel,
linux-kselftest
On Mon, Jun 01, 2026 at 01:42:36PM -0700, Nicolin Chen wrote:
> On a copy_to_user() failure inside the inner list_for_each_entry, only the
> inner loop breaks; the outer while re-fetches the just-restored fault group
> and retries the failing copy_to_user() forever, spinning the reader at 100%
> CPU with fault->mutex held.
>
> Check rc after the inner loop and break the outer while as well.
>
> Fixes: 07838f7fd529 ("iommufd: Add iommufd fault object")
> Cc: stable@vger.kernel.org
> Signed-off-by: Nicolin Chen <nicolinc@nvidia.com>
> ---
> drivers/iommu/iommufd/eventq.c | 2 ++
> 1 file changed, 2 insertions(+)
>
> diff --git a/drivers/iommu/iommufd/eventq.c b/drivers/iommu/iommufd/eventq.c
> index 613024ca8f1ff..1c010e691f972 100644
> --- a/drivers/iommu/iommufd/eventq.c
> +++ b/drivers/iommu/iommufd/eventq.c
> @@ -168,6 +168,8 @@ static ssize_t iommufd_fault_fops_read(struct file *filep, char __user *buf,
> }
> done += fault_size;
> }
> + if (rc)
> + break;
> }
> mutex_unlock(&fault->mutex);
>
Reviewed-by: Pranjal Shrivastava <praan@google.com>
Thanks,
Praan
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH v1 6/7] iommufd: Avoid partial fault group delivery in iommufd_fault_fops_read()
2026-06-01 20:42 ` [PATCH v1 6/7] iommufd: Avoid partial fault group delivery " Nicolin Chen
@ 2026-06-03 14:26 ` Pranjal Shrivastava
0 siblings, 0 replies; 18+ messages in thread
From: Pranjal Shrivastava @ 2026-06-03 14:26 UTC (permalink / raw)
To: Nicolin Chen
Cc: jgg, kevin.tian, joro, baolu.lu, iommu, linux-kernel,
linux-kselftest
On Mon, Jun 01, 2026 at 01:42:37PM -0700, Nicolin Chen wrote:
> The cookie returned by xa_alloc() in iommufd_fault_fops_read() is per fault
> group, but the inner copy_to_user() runs per fault inside the group. If a
> copy fails mid-group, xa_erase clears the cookie and the group is restored
> to the deliver list, yet done is not rolled back. The function returns the
> partial byte count, with the successfully copied faults sitting at offsets
> below done carrying the now-erased cookie. The next read() then re-fetches
> the group, allocates a fresh cookie, and re-delivers every fault including
> the ones already copied; userspace sees duplicates carrying the new cookie,
> and a stale cookie that can never be responded to.
>
> Use a local group_done variable that tracks the per-group progress inside
> the inner loop, and only commit done = group_done after the inner loop has
> finished successfully. On a copy_to_user failure the outer break skips the
> commit, so done remains at its prior start-of-group baseline; the partial
> bytes already written past done are undefined to userspace per the read(2)
> contract, and the next read re-delivers the whole group atomically.
>
> Fixes: 07838f7fd529 ("iommufd: Add iommufd fault object")
> Cc: stable@vger.kernel.org
> Assisted-by: Claude:claude-opus-4-7
> Signed-off-by: Nicolin Chen <nicolinc@nvidia.com>
Reviewed-by: Pranjal Shrivastava <praan@google.com>
Thanks,
Praan
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH v1 7/7] iommufd/selftest: Cover invalid read counts on vEVENTQ FD
2026-06-01 20:42 ` [PATCH v1 7/7] iommufd/selftest: Cover invalid read counts on vEVENTQ FD Nicolin Chen
@ 2026-06-03 14:46 ` Pranjal Shrivastava
0 siblings, 0 replies; 18+ messages in thread
From: Pranjal Shrivastava @ 2026-06-03 14:46 UTC (permalink / raw)
To: Nicolin Chen
Cc: jgg, kevin.tian, joro, baolu.lu, iommu, linux-kernel,
linux-kselftest
On Mon, Jun 01, 2026 at 01:42:38PM -0700, Nicolin Chen wrote:
> 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@nvidia.com>
Reviewed-by: Pranjal Shrivastava <praan@google.com>
Thanks,
Praan
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH v1 0/7] iommufd: Fix bugs in eventq fops_read paths
2026-06-01 20:42 [PATCH v1 0/7] iommufd: Fix bugs in eventq fops_read paths Nicolin Chen
` (8 preceding siblings ...)
2026-06-03 6:59 ` Tian, Kevin
@ 2026-06-05 14:30 ` Jason Gunthorpe
9 siblings, 0 replies; 18+ messages in thread
From: Jason Gunthorpe @ 2026-06-05 14:30 UTC (permalink / raw)
To: Nicolin Chen
Cc: kevin.tian, joro, baolu.lu, iommu, linux-kernel, linux-kselftest
On Mon, Jun 01, 2026 at 01:42:31PM -0700, Nicolin Chen wrote:
> Nicolin Chen (7):
> iommufd: Rewind header length in done if iommufd_veventq_fops_read()
> fails
> iommufd: Reject invalid read count in iommufd_veventq_fops_read()
> iommufd: Propagate allocation failure in
> iommufd_veventq_deliver_fetch()
> iommufd: Reject invalid read count in iommufd_fault_fops_read()
> iommufd: Break the loop on failure in iommufd_fault_fops_read()
> iommufd: Avoid partial fault group delivery in
> iommufd_fault_fops_read()
> iommufd/selftest: Cover invalid read counts on vEVENTQ FD
Applied to for-next
Thanks,
Jason
^ permalink raw reply [flat|nested] 18+ messages in thread
end of thread, other threads:[~2026-06-05 14:30 UTC | newest]
Thread overview: 18+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-06-01 20:42 [PATCH v1 0/7] iommufd: Fix bugs in eventq fops_read paths Nicolin Chen
2026-06-01 20:42 ` [PATCH v1 1/7] iommufd: Rewind header length in done if iommufd_veventq_fops_read() fails Nicolin Chen
2026-06-03 14:01 ` Pranjal Shrivastava
2026-06-01 20:42 ` [PATCH v1 2/7] iommufd: Reject invalid read count in iommufd_veventq_fops_read() Nicolin Chen
2026-06-03 14:08 ` Pranjal Shrivastava
2026-06-01 20:42 ` [PATCH v1 3/7] iommufd: Propagate allocation failure in iommufd_veventq_deliver_fetch() Nicolin Chen
2026-06-03 14:13 ` Pranjal Shrivastava
2026-06-01 20:42 ` [PATCH v1 4/7] iommufd: Reject invalid read count in iommufd_fault_fops_read() Nicolin Chen
2026-06-03 14:15 ` Pranjal Shrivastava
2026-06-01 20:42 ` [PATCH v1 5/7] iommufd: Break the loop on failure " Nicolin Chen
2026-06-03 14:18 ` Pranjal Shrivastava
2026-06-01 20:42 ` [PATCH v1 6/7] iommufd: Avoid partial fault group delivery " Nicolin Chen
2026-06-03 14:26 ` Pranjal Shrivastava
2026-06-01 20:42 ` [PATCH v1 7/7] iommufd/selftest: Cover invalid read counts on vEVENTQ FD Nicolin Chen
2026-06-03 14:46 ` Pranjal Shrivastava
2026-06-02 6:27 ` [PATCH v1 0/7] iommufd: Fix bugs in eventq fops_read paths Nicolin Chen
2026-06-03 6:59 ` Tian, Kevin
2026-06-05 14:30 ` Jason Gunthorpe
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.