iommufd: Do not allow creating areas without READ or WRITE
This results in passing 0 or just IOMMU_CACHE to iommu_map(). Most of
the page table formats don't like this:
amdv1 - -EINVAL
armv7s - returns 0, doesn't update mapped
arm-lpae - returns 0 doesn't update mapped
dart - returns 0, doesn't update mapped
VT-D - returns -EINVAL
Unfortunately the three formats that return 0 cause serious problems:
- Returning ret = but not uppdating mapped from domain->map_pages()
causes an infinite loop in __iommu_map()
- Not writing ioptes means that VFIO/iommufd have no way to recover them
and we will have memory leaks and worse during unmap
Since almost nothing can support this, and it is a useless thing to do,
block it early in iommufd.
Cc: stable@kernel.org
Fixes: aad37e71d5
("iommufd: IOCTLs for the io_pagetable")
Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
Reviewed-by: Nicolin Chen <nicolinc@nvidia.com>
Reviewed-by: Kevin Tian <kevin.tian@intel.com>
Link: https://lore.kernel.org/r/1-v1-1211e1294c27+4b1-iommu_no_prot_jgg@nvidia.com
Signed-off-by: Joerg Roedel <jroedel@suse.de>
This commit is contained in:
parent
7af6c72041
commit
996dc53ac2
@ -213,6 +213,10 @@ int iommufd_ioas_map(struct iommufd_ucmd *ucmd)
|
||||
if (cmd->iova >= ULONG_MAX || cmd->length >= ULONG_MAX)
|
||||
return -EOVERFLOW;
|
||||
|
||||
if (!(cmd->flags &
|
||||
(IOMMU_IOAS_MAP_WRITEABLE | IOMMU_IOAS_MAP_READABLE)))
|
||||
return -EINVAL;
|
||||
|
||||
ioas = iommufd_get_ioas(ucmd->ictx, cmd->ioas_id);
|
||||
if (IS_ERR(ioas))
|
||||
return PTR_ERR(ioas);
|
||||
@ -253,6 +257,10 @@ int iommufd_ioas_copy(struct iommufd_ucmd *ucmd)
|
||||
cmd->dst_iova >= ULONG_MAX)
|
||||
return -EOVERFLOW;
|
||||
|
||||
if (!(cmd->flags &
|
||||
(IOMMU_IOAS_MAP_WRITEABLE | IOMMU_IOAS_MAP_READABLE)))
|
||||
return -EINVAL;
|
||||
|
||||
src_ioas = iommufd_get_ioas(ucmd->ictx, cmd->src_ioas_id);
|
||||
if (IS_ERR(src_ioas))
|
||||
return PTR_ERR(src_ioas);
|
||||
|
@ -825,7 +825,7 @@ TEST_F(iommufd_ioas, copy_area)
|
||||
{
|
||||
struct iommu_ioas_copy copy_cmd = {
|
||||
.size = sizeof(copy_cmd),
|
||||
.flags = IOMMU_IOAS_MAP_FIXED_IOVA,
|
||||
.flags = IOMMU_IOAS_MAP_FIXED_IOVA | IOMMU_IOAS_MAP_WRITEABLE,
|
||||
.dst_ioas_id = self->ioas_id,
|
||||
.src_ioas_id = self->ioas_id,
|
||||
.length = PAGE_SIZE,
|
||||
@ -1318,7 +1318,7 @@ TEST_F(iommufd_ioas, copy_sweep)
|
||||
{
|
||||
struct iommu_ioas_copy copy_cmd = {
|
||||
.size = sizeof(copy_cmd),
|
||||
.flags = IOMMU_IOAS_MAP_FIXED_IOVA,
|
||||
.flags = IOMMU_IOAS_MAP_FIXED_IOVA | IOMMU_IOAS_MAP_WRITEABLE,
|
||||
.src_ioas_id = self->ioas_id,
|
||||
.dst_iova = MOCK_APERTURE_START,
|
||||
.length = MOCK_PAGE_SIZE,
|
||||
@ -1608,7 +1608,7 @@ TEST_F(iommufd_mock_domain, user_copy)
|
||||
};
|
||||
struct iommu_ioas_copy copy_cmd = {
|
||||
.size = sizeof(copy_cmd),
|
||||
.flags = IOMMU_IOAS_MAP_FIXED_IOVA,
|
||||
.flags = IOMMU_IOAS_MAP_FIXED_IOVA | IOMMU_IOAS_MAP_WRITEABLE,
|
||||
.dst_ioas_id = self->ioas_id,
|
||||
.dst_iova = MOCK_APERTURE_START,
|
||||
.length = BUFFER_SIZE,
|
||||
|
Loading…
Reference in New Issue
Block a user