Re: [PATCH v3 9/15] iommufd: Data structure to provide IOVA to PFN mapping

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Tue, Oct 25, 2022 at 03:12:18PM -0300, Jason Gunthorpe wrote:
> +struct iopt_area *iopt_area_contig_init(struct iopt_area_contig_iter *iter,
> +					struct io_pagetable *iopt,
> +					unsigned long iova,
> +					unsigned long last_iova)
> +{
> +	lockdep_assert_held(&iopt->iova_rwsem);
> +
> +	iter->cur_iova = iova;
> +	iter->last_iova = last_iova;
> +	iter->area = iopt_area_iter_first(iopt, iova, last_iova);
> +	if (!iter->area)
> +		return NULL;

This one is a bit neat, syzkaller discovered that if a copy range is
requested with a partial area in it then things go wrong. The
contigous iterator is supposed to step over areas that completely
cover a range. The little thinko is that interval_tree_iter_first(),
when given a range, will return the lowest tree node that intersects
the range. Thus a leading partial intersection of the range to the
areas will not result in the iterator failing. Instead we want to find
the area that includes the starting iova, or fail if it is not found:

@@ -35,7 +35,7 @@ struct iopt_area *iopt_area_contig_init(struct iopt_area_contig_iter *iter,

        iter->cur_iova = iova;
        iter->last_iova = last_iova;
-       iter->area = iopt_area_iter_first(iopt, iova, last_iova);
+       iter->area = iopt_area_iter_first(iopt, iova, iova);
        if (!iter->area)
                return NULL;
        if (!iter->area->pages) {

Add a test to cover as well.

Jason



[Index of Archives]     [KVM ARM]     [KVM ia64]     [KVM ppc]     [Virtualization Tools]     [Spice Development]     [Libvirt]     [Libvirt Users]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite Questions]     [Linux Kernel]     [Linux SCSI]     [XFree86]

  Powered by Linux