2
0
mirror of https://github.com/edk2-porting/linux-next.git synced 2024-12-15 08:44:14 +08:00

iommufd for 6.5

Just two RC syzkaller fixes, both for the same basic issue, using the area
 pointer during an access forced unmap while the locks protecting it were
 let go.
 -----BEGIN PGP SIGNATURE-----
 
 iHUEABYIAB0WIQRRRCHOFoQz/8F5bUaFwuHvBreFYQUCZJmGygAKCRCFwuHvBreF
 YVNSAQC7SgejTvwD6EYXr8AUDko1v0G0M/o60OrWIuC7xWiFPQD/RDwtItRLzf4h
 i+YCfMtn/7IB/uV/sRTF4m0HzudcDAM=
 =0fm4
 -----END PGP SIGNATURE-----

Merge tag 'for-linus-iommufd' of git://git.kernel.org/pub/scm/linux/kernel/git/jgg/iommufd

Pull iommufd updates from Jason Gunthorpe:
 "Just two syzkaller fixes, both for the same basic issue: using the
  area pointer during an access forced unmap while the locks protecting
  it were let go"

* tag 'for-linus-iommufd' of git://git.kernel.org/pub/scm/linux/kernel/git/jgg/iommufd:
  iommufd: Call iopt_area_contig_done() under the lock
  iommufd: Do not access the area pointer after unlocking
This commit is contained in:
Linus Torvalds 2023-06-29 20:57:27 -07:00
commit 31929ae008
2 changed files with 12 additions and 4 deletions

View File

@ -553,8 +553,8 @@ void iommufd_access_unpin_pages(struct iommufd_access *access,
iopt_area_iova_to_index(
area,
min(last_iova, iopt_area_last_iova(area))));
up_read(&iopt->iova_rwsem);
WARN_ON(!iopt_area_contig_done(&iter));
up_read(&iopt->iova_rwsem);
}
EXPORT_SYMBOL_NS_GPL(iommufd_access_unpin_pages, IOMMUFD);

View File

@ -458,6 +458,7 @@ static int iopt_unmap_iova_range(struct io_pagetable *iopt, unsigned long start,
{
struct iopt_area *area;
unsigned long unmapped_bytes = 0;
unsigned int tries = 0;
int rc = -ENOENT;
/*
@ -484,19 +485,26 @@ again:
goto out_unlock_iova;
}
if (area_first != start)
tries = 0;
/*
* num_accesses writers must hold the iova_rwsem too, so we can
* safely read it under the write side of the iovam_rwsem
* without the pages->mutex.
*/
if (area->num_accesses) {
size_t length = iopt_area_length(area);
start = area_first;
area->prevent_access = true;
up_write(&iopt->iova_rwsem);
up_read(&iopt->domains_rwsem);
iommufd_access_notify_unmap(iopt, area_first,
iopt_area_length(area));
if (WARN_ON(READ_ONCE(area->num_accesses)))
iommufd_access_notify_unmap(iopt, area_first, length);
/* Something is not responding to unmap requests. */
tries++;
if (WARN_ON(tries > 100))
return -EDEADLOCK;
goto again;
}