| 8c07df7c | 11-Aug-2026 |
Peiyang He <peiyang_he@smail.nju.edu.cn> |
iommufd: Fix UAF in selftest IOPF reporting
IOMMUFD selftest TRIGGER_IOPF borrows an attach handle from group->pasid_array without synchronizing against PASID detach, then a concurrent iommu_report_
iommufd: Fix UAF in selftest IOPF reporting
IOMMUFD selftest TRIGGER_IOPF borrows an attach handle from group->pasid_array without synchronizing against PASID detach, then a concurrent iommu_report_device_fault() can dereference that borrowed handle's domain pointer after the detach erases the handle and frees the backing struct iommufd_attach_handle. TRIGGER_IOPF then dereferences the freed handle, causing a UAF.
Fix by adding a iopf_rwsem in mock_dev to follow the expected design of a real driver. Hold its read side across the whole iommu_report_device_fault() call, and its write side around every path that attaches, detaches, or replaces a device domain. This can block new reports and drains in-flight reports before an old attach handle or the IOPF fault parameter can be removed. Also take the write side while registering a mock device, since it can invoke the mock driver's default-domain attach callback.
Closes: https://lore.kernel.org/all/D5E3AA41600B2056+f4e15662-bd2b-43ea-91cb-518de429e72c@smail.nju.edu.cn/ Fixes: ddee19971081 ("iommufd/selftest: Add IOPF support for mock device") Cc: stable@vger.kernel.org Suggested-by: Jason Gunthorpe <jgg@ziepe.ca> Assisted-by: Codex:gpt-5.6-terra Signed-off-by: Peiyang He <peiyang_he@smail.nju.edu.cn> Link: https://patch.msgid.link/38C8DF0A118B7176+20260811095551.2756745-1-peiyang_he@smail.nju.edu.cn Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
show more ...
|
| d616de49 | 06-Aug-2026 |
Peiyang He <peiyang_he@smail.nju.edu.cn> |
iommu/iommufd: Fix NULL pointer deref in iommufd_ioas_change_process when racing with iopt_map_file_pages
iommufd_ioas_change_process() iterates every IOAS area while only holding every IOAS iova_rw
iommu/iommufd: Fix NULL pointer deref in iommufd_ioas_change_process when racing with iopt_map_file_pages
iommufd_ioas_change_process() iterates every IOAS area while only holding every IOAS iova_rwsem, so it assumes every area has a non-NULL pages pointer. That assumption can be false when it runs concurrently with iopt_map_file_pages().
iopt_map_pages() executes in two phases. It first creates the area and inserts it into the interval tree under iova_rwsem, with area->pages still NULL. It then drops iova_rwsem and later fills area->pages under domains_rwsem. This leaves a window between area creation and area->pages fill where a concurrent iommufd_ioas_change_process() can observe the area and dereference a NULL area->pages pointer, leading to a NULL pointer dereference:
BUG: kernel NULL pointer dereference, address: 00000000000000c0 #PF: supervisor read access in kernel mode #PF: error_code(0x0000) - not-present page PGD 4b655067 P4D 4b655067 PUD 0 Oops: Oops: 0000 [#1] SMP NOPTI CPU: 0 UID: 0 PID: 11841 Comm: syz.1.628 Not tainted 7.1.0 #3 PREEMPT(full) Hardware name: QEMU Ubuntu 24.04 PC v2 (i440FX + PIIX, arch_caps fix, 1996), BIOS 1.16.3-debian-1.16.3-2 04/01/2014 RIP: 0010:iommufd_ioas_change_process+0x419/0xd50 drivers/iommu/iommufd/ioas.c:538 Code: 48 89 c3 48 85 c0 0f 84 cc 00 00 00 e8 10 f5 cb fd 48 8d 7b 68 e8 a7 b5 eb fd 48 8b 6b 68 48 8d bd c0 00 00 00 e8 17 b2 eb fd <8b> ad c0 00 00 00 bf 01 00 00 00 89 ee e8 85 ef cb fd 83 fd 01 74 RSP: 0018:ffffc90015c17d28 EFLAGS: 00010246 RAX: ffff8880186d5328 RBX: ffff88801d25e240 RCX: 0000000080000000 RDX: 00000000000002d7 RSI: ffffffff83ba9e10 RDI: 00000000000000c0 RBP: 0000000000000000 R08: ffffffff8e781eb8 R09: 0000000000000000 R10: 00000000000000c0 R11: ffffffff83ba9e29 R12: ffff88802e216008 R13: ffff88802e216000 R14: 0000000000000001 R15: 0000000000000000 FS: 00007f4aea3f66c0(0000) GS:ffff8880b1fa1000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 00000000000000c0 CR3: 000000004b75c000 CR4: 0000000000350ef0 Call Trace: <TASK> iommufd_fops_ioctl+0x287/0x400 drivers/iommu/iommufd/main.c:533 vfs_ioctl fs/ioctl.c:51 [inline] __do_sys_ioctl fs/ioctl.c:597 [inline] __se_sys_ioctl fs/ioctl.c:583 [inline] __x64_sys_ioctl+0x120/0x170 fs/ioctl.c:583 x64_sys_call+0x1092/0x1fb0 arch/x86/include/generated/asm/syscalls_64.h:17 do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline] do_syscall_64+0x10a/0x680 arch/x86/entry/syscall_64.c:94 entry_SYSCALL_64_after_hwframe+0x77/0x7f RIP: 0033:0x7f4aec1a82bd Code: ff c3 66 2e 0f 1f 84 00 00 00 00 00 90 f3 0f 1e fa 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 c7 c1 b0 ff ff ff f7 d8 64 89 01 48 RSP: 002b:00007f4aea3f6018 EFLAGS: 00000246 ORIG_RAX: 0000000000000010 RAX: ffffffffffffffda RBX: 00007f4aec436090 RCX: 00007f4aec1a82bd RDX: 0000200000000180 RSI: 0000000000003b92 RDI: 0000000000000003 RBP: 00007f4aec250295 R08: 0000000000000000 R09: 0000000000000000 R10: 0000000000000000 R11: 0000000000000246 R12: 0000000000000000 R13: 00007f4aec436128 R14: 00007f4aec436090 R15: 00007ffd04ef23e0 </TASK> Modules linked in: CR2: 00000000000000c0 ---[ end trace 0000000000000000 ]--- RIP: 0010:iommufd_ioas_change_process+0x419/0xd50 drivers/iommu/iommufd/ioas.c:538 Code: 48 89 c3 48 85 c0 0f 84 cc 00 00 00 e8 10 f5 cb fd 48 8d 7b 68 e8 a7 b5 eb fd 48 8b 6b 68 48 8d bd c0 00 00 00 e8 17 b2 eb fd <8b> ad c0 00 00 00 bf 01 00 00 00 89 ee e8 85 ef cb fd 83 fd 01 74 RSP: 0018:ffffc90015c17d28 EFLAGS: 00010246 RAX: ffff8880186d5328 RBX: ffff88801d25e240 RCX: 0000000080000000 RDX: 00000000000002d7 RSI: ffffffff83ba9e10 RDI: 00000000000000c0 RBP: 0000000000000000 R08: ffffffff8e781eb8 R09: 0000000000000000 R10: 00000000000000c0 R11: ffffffff83ba9e29 R12: ffff88802e216008 R13: ffff88802e216000 R14: 0000000000000001 R15: 0000000000000000 FS: 00007f4aea3f66c0(0000) GS:ffff8880b1fa1000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 00000000000000c0 CR3: 000000004b75c000 CR4: 0000000000350ef0 ---------------- Code disassembly (best guess): 0: 48 89 c3 mov %rax,%rbx 3: 48 85 c0 test %rax,%rax 6: 0f 84 cc 00 00 00 je 0xd8 c: e8 10 f5 cb fd call 0xfdcbf521 11: 48 8d 7b 68 lea 0x68(%rbx),%rdi 15: e8 a7 b5 eb fd call 0xfdebb5c1 1a: 48 8b 6b 68 mov 0x68(%rbx),%rbp 1e: 48 8d bd c0 00 00 00 lea 0xc0(%rbp),%rdi 25: e8 17 b2 eb fd call 0xfdebb241 * 2a: 8b ad c0 00 00 00 mov 0xc0(%rbp),%ebp <-- trapping instruction 30: bf 01 00 00 00 mov $0x1,%edi 35: 89 ee mov %ebp,%esi 37: e8 85 ef cb fd call 0xfdcbefc1 3c: 83 fd 01 cmp $0x1,%ebp 3f: 74 .byte 0x74
Fix by mirroring the handling logic in iopt_unmap_iova_range(), i.e. return -EBUSY if area->pages is NULL.
Fixes: 829ed626499c ("iommufd: Add IOMMU_IOAS_CHANGE_PROCESS") Link: https://patch.msgid.link/r/7344B7A7B9957A65+20260806045059.1884737-1-peiyang_he@smail.nju.edu.cn Cc: stable@vger.kernel.org Signed-off-by: Peiyang He <peiyang_he@smail.nju.edu.cn> Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
show more ...
|
| 4ac2ce12 | 26-Jul-2026 |
Shuai Xue <xueshuai@linux.alibaba.com> |
iommufd: Release current IOAS on xa_store() failure
iommufd_take_all_iova_rwsem() takes an object reference and the iova_rwsem write lock before storing the IOAS in the temporary ioas_list xarray.
iommufd: Release current IOAS on xa_store() failure
iommufd_take_all_iova_rwsem() takes an object reference and the iova_rwsem write lock before storing the IOAS in the temporary ioas_list xarray.
If xa_store() fails, the current IOAS has not been inserted into ioas_list yet. iommufd_release_all_iova_rwsem() only unwinds IOAS objects already present in that xarray, so it cannot release the current IOAS.
Release the current IOAS rwsem and object reference before unwinding the previously stored entries.
Fixes: 051ae5aa73d7 ("iommufd: Lock all IOAS objects") Cc: stable@vger.kernel.org Assisted-by: Qoder:Qwen-3.8-MAX-Preview Signed-off-by: Shuai Xue <xueshuai@linux.alibaba.com> Reviewed-by: Kevin Tian <kevin.tian@intel.com> Reviewed-by: Jason Gunthorpe <jgg@nvidia.com> Signed-off-by: Joerg Roedel <joerg.roedel@amd.com>
show more ...
|
| 738e6f32 | 20-Jul-2026 |
Peiyang He <peiyang_he@smail.nju.edu.cn> |
iommu/iommufd: Fix IOPF group ownership UAF
iopf_group_alloc() links each last-page IOPF group into the generic IOPF pending list before invoking the domain fault handler. iommufd_fault_iopf_handler
iommu/iommufd: Fix IOPF group ownership UAF
iopf_group_alloc() links each last-page IOPF group into the generic IOPF pending list before invoking the domain fault handler. iommufd_fault_iopf_handler() also queued an accepted group in the IOMMUFD deliver list without removing it from the generic pending list.
When detach or HWPT replacement drops the device's IOPF reference count to zero, an IOMMU driver may call iopf_queue_remove_device(). That function responds to and frees groups through the generic pending list without removing the same groups from IOMMUFD's deliver list or response xarray. A later read, response, or cleanup can then access the freed group and cause a UAF.
Fix this by dequeuing an accepted group from the generic pending list before IOMMUFD queues it for userspace response. Make iopf_group_response() send a response regardless of pending-list membership, so the dequeued group can still be completed by IOMMUFD.
Link: https://patch.msgid.link/r/3CFD314D0FE4D7EC+20260720085017.3998878-2-peiyang_he@smail.nju.edu.cn Closes: https://lore.kernel.org/all/B4F28798E2E784CA+d29f723c-b2b5-4b67-8d1c-4f7b9b0b27cb@smail.nju.edu.cn/ Fixes: 34765cbc679c ("iommufd: Associate fault object with iommufd_hw_pgtable") Cc: stable@vger.kernel.org Tested-by: Peiyang He <peiyang_he@smail.nju.edu.cn> Assisted-by: Codex:gpt-5.6-sol Signed-off-by: Peiyang He <peiyang_he@smail.nju.edu.cn> Reviewed-by: Kevin Tian <kevin.tian@intel.com> Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
show more ...
|
| 60decab3 | 06-Jul-2026 |
Jacob Pan <jacob.pan@linux.microsoft.com> |
iommufd: Add an ioctl to query PA from IOVA for noiommu mode
To support no-IOMMU mode where userspace drivers perform unsafe DMA using physical addresses, introduce a new API to retrieve the physica
iommufd: Add an ioctl to query PA from IOVA for noiommu mode
To support no-IOMMU mode where userspace drivers perform unsafe DMA using physical addresses, introduce a new API to retrieve the physical address of a user-allocated DMA buffer that has been mapped to an IOVA via IOMMU_IOAS_MAP. The mapping is backed by SW-only I/O page tables maintained by the GENERIC_PT framework.
Link: https://patch.msgid.link/r/a60a601509688e8552c75e668deb548c93974a3b.1783360051.git.jacob.pan@linux.microsoft.com Reviewed-by: Lu Baolu <baolu.lu@linux.intel.com> Reviewed-by: Kevin Tian <kevin.tian@intel.com> Reviewed-by: Pranjal Shrivastava <praan@google.com> Reviewed-by: Yi Liu <yi.l.liu@intel.com> Suggested-by: Jason Gunthorpe <jgg@nvidia.com> Co-developed-by: Jason Gunthorpe <jgg@nvidia.com> Signed-off-by: Jacob Pan <jacob.pan@linux.microsoft.com> Fixes: 2c6cf6ab1564 ("iommufd: Allow binding to a noiommu device") Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
show more ...
|
| 072f454c | 06-Jul-2026 |
Jason Gunthorpe <jgg@nvidia.com> |
iommufd: Allow binding to a noiommu device
Allow iommufd to bind devices without an IOMMU (noiommu mode) by creating a dummy igroup for such devices and skipping hwpt operations.
This enables noiom
iommufd: Allow binding to a noiommu device
Allow iommufd to bind devices without an IOMMU (noiommu mode) by creating a dummy igroup for such devices and skipping hwpt operations.
This enables noiommu devices to operate through the same iommufd API as IOMMU- capable devices.
Link: https://patch.msgid.link/r/2c6cf6ab1564426050e637863c9b0d3b25541c63.1783360051.git.jacob.pan@linux.microsoft.com Reviewed-by: Kevin Tian <kevin.tian@intel.com> Reviewed-by: Yi Liu <yi.l.liu@intel.com> Reviewed-by: Lu Baolu <baolu.lu@linux.intel.com> Reviewed-by: Pranjal Shrivastava <praan@google.com> Signed-off-by: Jacob Pan <jacob.pan@linux.microsoft.com> Fixes: 2c6cf6ab1564 ("iommufd: Allow binding to a noiommu device") Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
show more ...
|
| cfa82148 | 06-Jul-2026 |
Jason Gunthorpe <jgg@nvidia.com> |
iommufd: Move igroup allocation to a function
So it can be reused in the next patch which allows binding to noiommu device.
Link: https://patch.msgid.link/r/6bc8e5eaee89e1dc5f07d13dff69b9670b55923a
iommufd: Move igroup allocation to a function
So it can be reused in the next patch which allows binding to noiommu device.
Link: https://patch.msgid.link/r/6bc8e5eaee89e1dc5f07d13dff69b9670b55923a.1783360051.git.jacob.pan@linux.microsoft.com Reviewed-by: Samiullah Khawaja <skhawaja@google.com> Reviewed-by: Yi Liu <yi.l.liu@intel.com> Reviewed-by: Kevin Tian <kevin.tian@intel.com> Reviewed-by: Lu Baolu <baolu.lu@linux.intel.com> Signed-off-by: Jacob Pan <jacob.pan@linux.microsoft.com> Fixes: 2c6cf6ab1564 ("iommufd: Allow binding to a noiommu device") Reviewed-by: Pranjal Shrivastava <praan@google.com> Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
show more ...
|
| 17ea9f74 | 06-Jul-2026 |
Jason Gunthorpe <jgg@nvidia.com> |
iommufd: Support a HWPT without an iommu driver for noiommu
Create just a little part of a real iommu driver, enough to slot in under the dev_iommu_ops() and allow iommufd to call domain_alloc_pagin
iommufd: Support a HWPT without an iommu driver for noiommu
Create just a little part of a real iommu driver, enough to slot in under the dev_iommu_ops() and allow iommufd to call domain_alloc_paging_flags() and fail everything else.
This allows explicitly creating a HWPT under an IOAS.
A new Kconfig option IOMMUFD_NOIOMMU is introduced to differentiate from the VFIO group/container based noiommu mode.
Link: https://patch.msgid.link/r/8d1ad0b90db0381d4139eda5c126cc8d168d89f8.1783360051.git.jacob.pan@linux.microsoft.com Reviewed-by: Lu Baolu <baolu.lu@linux.intel.com> Reviewed-by: Samiullah Khawaja <skhawaja@google.com> Reviewed-by: Kevin Tian <kevin.tian@intel.com> Reviewed-by: Pranjal Shrivastava <praan@google.com> Signed-off-by: Jacob Pan <jacob.pan@linux.microsoft.com> Fixes: 2c6cf6ab1564 ("iommufd: Allow binding to a noiommu device") Reviewed-by: Yi Liu <yi.l.liu@intel.com> Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
show more ...
|
| 9be311cf | 06-Jul-2026 |
Nicolin Chen <nicolinc@nvidia.com> |
iommufd/viommu: Publish a vDEVICE only after vdevice_init() succeeds
iommufd_vdevice_alloc_ioctl() adds the vDEVICE to the viommu->vdevs xarray with xa_cmpxchg() before the driver's vdevice_init() o
iommufd/viommu: Publish a vDEVICE only after vdevice_init() succeeds
iommufd_vdevice_alloc_ioctl() adds the vDEVICE to the viommu->vdevs xarray with xa_cmpxchg() before the driver's vdevice_init() op runs. That op is where a driver validates the device and may reject it, but the xarray entry is already live by then: a concurrent IOMMU_HWPT_INVALIDATE can look it up with iommufd_viommu_find_dev() and run the driver invalidation path against a device that vdevice_init() would have refused.
Reserve the index with xa_insert(): it stores a zero entry that reads back as NULL, and returns -EBUSY on a duplicate virt_id. Run vdevice_init() and store the vDEVICE pointer only once it succeeds. A failed vdevice_init() releases the reservation, so lookups observe the vDEVICE only after it is fully initialized and accepted.
Fixes: ed42eee797ff3 ("iommufd/viommu: Add driver-defined vDEVICE support") Link: https://patch.msgid.link/r/1e05999347f4bf583edbc6a1312c857d5548708c.1783311134.git.nicolinc@nvidia.com Cc: stable@vger.kernel.org Reviewed-by: Kevin Tian <kevin.tian@intel.com> Assisted-by: Claude:claude-opus-4-8 Reviewed-by: Pranjal Shrivastava <praan@google.com> Signed-off-by: Nicolin Chen <nicolinc@nvidia.com> Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
show more ...
|
| 339bd115 | 06-Jul-2026 |
Nicolin Chen <nicolinc@nvidia.com> |
iommufd/viommu: Release the igroup lock on the vdevice_size error path
iommufd_vdevice_alloc_ioctl() takes idev->igroup->lock, then validates the driver's vdevice_size against the core structure siz
iommufd/viommu: Release the igroup lock on the vdevice_size error path
iommufd_vdevice_alloc_ioctl() takes idev->igroup->lock, then validates the driver's vdevice_size against the core structure size with a WARN_ON_ONCE. On failure that guard jumps to out_put_idev, below out_unlock_igroup, so it skips the mutex_unlock(), leaving the igroup lock held and deadlocking the next vDEVICE operation on that group.
Jump to out_unlock_igroup instead.
Fixes: ed42eee797ff3 ("iommufd/viommu: Add driver-defined vDEVICE support") Link: https://patch.msgid.link/r/e903f775d491296a525097e2a90b3eb6a47cf2ef.1783311134.git.nicolinc@nvidia.com Cc: stable@vger.kernel.org Reviewed-by: Kevin Tian <kevin.tian@intel.com> Assisted-by: Claude:claude-opus-4-8 Reviewed-by: Pranjal Shrivastava <praan@google.com> Signed-off-by: Nicolin Chen <nicolinc@nvidia.com> Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
show more ...
|
| 80621480 | 13-Jul-2026 |
Jason Gunthorpe <jgg@nvidia.com> |
iommufd: Simplify iommufd_device_remove_vdev()
Peiyang reports that this function indirectly includes a fault injection point through iommufd_get_object() that was intended to cover the uAPI use of
iommufd: Simplify iommufd_device_remove_vdev()
Peiyang reports that this function indirectly includes a fault injection point through iommufd_get_object() that was intended to cover the uAPI use of object IDs, not in places like this that cannot fail.
On deeper inspection this can be written using a dedicated helper to obtain a users refcount relying entirely on the xa locking instead of going through the whole get/put scheme. The new helper doesn't need the fault injection point.
Fixes: 850f14f5b919 ("iommufd: Destroy vdevice on idevice destroy") Link: https://patch.msgid.link/r/0-v1-719003d53a5b+38b-iommufd_fault_inj_vdev_jgg@nvidia.com Reported-by: Peiyang He <peiyang_he@smail.nju.edu.cn> Closes: https://lore.kernel.org/r/870BB9ADBBEDDD1A+37c5bfab-ad32-4fc5-a302-57c81a8432b5@smail.nju.edu.cn Reviewed-by: Nicolin Chen <nicolinc@nvidia.com> Reviewed-by: Kevin Tian <kevin.tian@intel.com> Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
show more ...
|
| 29f39658 | 14-Jul-2026 |
xiongweimin <xiongweimin@kylinos.cn> |
iommufd: Fix grammar and spelling in comments
Correct detach kdoc ("device/pasid from"), article use before IOMMUFD_OBJ_*, and "propogated" -> "propagated".
Link: https://patch.msgid.link/r/2026071
iommufd: Fix grammar and spelling in comments
Correct detach kdoc ("device/pasid from"), article use before IOMMUFD_OBJ_*, and "propogated" -> "propagated".
Link: https://patch.msgid.link/r/20260714024440.188358-1-15927021679@163.com Signed-off-by: xiongweimin <xiongweimin@kylinos.cn> Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
show more ...
|
| 5f3fc0ad | 09-Jul-2026 |
Peiyang He <peiyang_he@smail.nju.edu.cn> |
iommufd: Reject DMABUF pages from the access pin path
DMABUF pages are not supported for iommufd access pinning. iommufd_access_pin_pages() returns struct page pointers for in-kernel CPU access, but
iommufd: Reject DMABUF pages from the access pin path
DMABUF pages are not supported for iommufd access pinning. iommufd_access_pin_pages() returns struct page pointers for in-kernel CPU access, but DMABUF-backed iopt_pages do not carry a userspace address that can be passed to the GUP path.
iopt_pages_rw_access() already rejects IOPT_ADDRESS_DMABUF before doing CPU access. Apply the same rejection to iopt_area_add_access() before it takes pages->mutex and calls iopt_pages_fill_xarray(). Otherwise a DMABUF-backed iopt_pages can reach the hole-fill path, where pfn_reader_user_pin() interprets the union as uptr and calls pin_user_pages_fast()/pin_user_pages_remote().
This fix also avoids the lockdep warning reported from that path, where pages_dmabuf_mutex_key is held while gup_fast_fallback() may acquire mmap_lock.
Link: https://patch.msgid.link/r/CD68F549BF3761B7+20260709050800.520607-1-peiyang_he@smail.nju.edu.cn Reported-by: Peiyang He <peiyang_he@smail.nju.edu.cn> Closes: https://lore.kernel.org/all/E8540D7D05768C91+8b2ef227-3368-494e-909d-7b28e1489dfb@smail.nju.edu.cn/ Fixes: 71db84a092c3 ("iommufd: Add DMABUF to iopt_pages") Cc: stable@vger.kernel.org Tested-by: Peiyang He <peiyang_he@smail.nju.edu.cn> Signed-off-by: Peiyang He <peiyang_he@smail.nju.edu.cn> Reviewed-by: Kevin Tian <kevin.tian@intel.com> Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
show more ...
|
| dba4254e | 07-Jul-2026 |
yeeli <seven.yi.lee@gmail.com> |
iommufd/selftest: Fix dmabuf leak in iommufd_test_dmabuf_get()
When dma_buf_export() succeeds but dma_buf_fd() fails (e.g. -EMFILE from fd exhaustion), the dmabuf is leaked with no dma_buf_put() cal
iommufd/selftest: Fix dmabuf leak in iommufd_test_dmabuf_get()
When dma_buf_export() succeeds but dma_buf_fd() fails (e.g. -EMFILE from fd exhaustion), the dmabuf is leaked with no dma_buf_put() called.
Reproducer: exhaust fd table near RLIMIT_NOFILE, then repeatedly call IOMMU_TEST_OP_DMABUF_GET — htop shows unbounded memory growth.
Fix by calling dma_buf_put(dmabuf) on error and returning directly.
Fixes: d2041f1f11dd ("iommufd/selftest: Add some tests for the dmabuf flow") Link: https://patch.msgid.link/r/20260707030635.221577-1-seven.yi.lee@gmail.com Signed-off-by: yeeli <seven.yi.lee@gmail.com> Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
show more ...
|
| 4d709860 | 03-Jun-2026 |
Nicolin Chen <nicolinc@nvidia.com> |
iommufd: Set upper bounds on cache invalidation entry_num and entry_len
iommufd_hwpt_invalidate() takes a user-controlled entry_num and entry_len, each bounded only by U32_MAX. An entry_len beyond t
iommufd: Set upper bounds on cache invalidation entry_num and entry_len
iommufd_hwpt_invalidate() takes a user-controlled entry_num and entry_len, each bounded only by U32_MAX. An entry_len beyond the kernel's struct size makes the copy helper verify the extra bytes are zero, scanning that excess in one uninterruptible pass; a multi-gigabyte value over zeroed user memory trips the soft-lockup watchdog.
A large entry_num is the other half, driving the backend invalidation loop with no reschedule. The VT-d nested handler, for one, copies each entry and flushes caches per iteration, pinning the CPU on a non-preemptible kernel.
Cap both in the ioctl. entry_len is held under PAGE_SIZE, above any request struct, and entry_num under 1 << 19, the order of a hardware invalidation queue and well beyond any real batch, bounding the per-call loop length.
Fixes: 8c6eabae3807 ("iommufd: Add IOMMU_HWPT_INVALIDATE") Link: https://patch.msgid.link/r/447fa93663f7526eb361719e83fa8b649464483d.1780521606.git.nicolinc@nvidia.com Cc: stable@vger.kernel.org Assisted-by: Claude:claude-opus-4-8 Signed-off-by: Nicolin Chen <nicolinc@nvidia.com> Reviewed-by: Lu Baolu <baolu.lu@linux.intel.com> Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
show more ...
|
| f2d70dbd | 09-Jun-2026 |
Jason Gunthorpe <jgg@nvidia.com> |
iommufd: Destroy the pages content after detaching from dmabuf
Sashiko points out this has gotten out of order, the mutex could still be in use through the dmabuf invalidation callbacks. Don't destr
iommufd: Destroy the pages content after detaching from dmabuf
Sashiko points out this has gotten out of order, the mutex could still be in use through the dmabuf invalidation callbacks. Don't destroy any of the pages content until the dmabuf is fully detached.
Fixes: 71db84a092c3 ("iommufd: Add DMABUF to iopt_pages") Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
show more ...
|
| e745cd2c | 26-May-2026 |
Ankit Soni <Ankit.Soni@amd.com> |
iommufd: Take dma_resv lock before dma_buf_unpin() in release path
dma_buf_unpin() requires the caller to hold the exporter's dma_resv lock:
void dma_buf_unpin(struct dma_buf_attachment *attach)
iommufd: Take dma_resv lock before dma_buf_unpin() in release path
dma_buf_unpin() requires the caller to hold the exporter's dma_resv lock:
void dma_buf_unpin(struct dma_buf_attachment *attach) { ... dma_resv_assert_held(dmabuf->resv); ... }
iopt_release_pages() calls dma_buf_unpin() without taking that lock, so every iommufd_ioas_destroy()/iommufd_ioas_unmap() that releases the last reference on a DMABUF-backed iopt_pages triggers a WARN. This was hit while running tools/testing/selftests/iommu/iommufd:
WARNING: drivers/dma-buf/dma-buf.c:1137 at dma_buf_unpin+0x62/0x70 RIP: 0010:dma_buf_unpin+0x62/0x70 Call Trace: <TASK> dma_buf_unpin+0x62/0x70 iopt_release_pages+0xe4/0x190 iopt_unmap_iova_range+0x1c7/0x290 iopt_unmap_all+0x1a/0x30 iommufd_ioas_destroy+0x1d/0x50 iommufd_fops_release+0x93/0x150 __fput+0xfc/0x2c0 __x64_sys_close+0x3d/0x80 do_syscall_64+0x65/0x180 </TASK>
Take the dma_resv lock around dma_buf_unpin() in iopt_release_pages(), matching the iopt_map_dmabuf() convention. dma_buf_detach() acquires the reservation lock internally, so it must remain outside the locked region.
Fixes: 8c5f9645c389 ("iommufd: Add dma_buf_pin()") Link: https://patch.msgid.link/r/20260526111034.4079-1-Ankit.Soni@amd.com Reported-by: Ankit Soni <Ankit.Soni@amd.com> Signed-off-by: Ankit Soni <Ankit.Soni@amd.com> Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
show more ...
|
| 091ab6d7 | 01-Jun-2026 |
Nicolin Chen <nicolinc@nvidia.com> |
iommufd: Avoid partial fault group delivery in iommufd_fault_fops_read()
The cookie returned by xa_alloc() in iommufd_fault_fops_read() is per fault group, but the inner copy_to_user() runs per faul
iommufd: Avoid partial fault group delivery in iommufd_fault_fops_read()
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") Link: https://patch.msgid.link/r/360cab4d4aeccb0bae275a970e2b3c340a71e0e0.1780343944.git.nicolinc@nvidia.com 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> Reviewed-by: Kevin Tian <kevin.tian@intel.com> Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
show more ...
|
| 172fc8b1 | 01-Jun-2026 |
Nicolin Chen <nicolinc@nvidia.com> |
iommufd: Break the loop on failure in iommufd_fault_fops_read()
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-rest
iommufd: Break the loop on failure in iommufd_fault_fops_read()
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") Link: https://patch.msgid.link/r/336a9b6e44fe66a24199d3be777c405c85c98622.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>
show more ...
|