kvm: iommu: fix the third parameter of kvm_iommu_put_pages (CVE-2014-3601)

The third parameter of kvm_iommu_put_pages is wrong,
It should be 'gfn - slot->base_gfn'.

By making gfn very large, malicious guest or userspace can cause kvm to
go to this error path, and subsequently to pass a huge value as size.
Alternatively if gfn is small, then pages would be pinned but never
unpinned, causing host memory leak and local DOS.

Passing a reasonable but large value could be the most dangerous case,
because it would unpin a page that should have stayed pinned, and thus
allow the device to DMA into arbitrary memory.  However, this cannot
happen because of the condition that can trigger the error:

- out of memory (where you can't allocate even a single page)
  should not be possible for the attacker to trigger

- when exceeding the iommu's address space, guest pages after gfn
  will also exceed the iommu's address space, and inside
  kvm_iommu_put_pages() the iommu_iova_to_phys() will fail.  The
  page thus would not be unpinned at all.

Reported-by: Jack Morgenstein <jackm@mellanox.com>
Cc: stable@vger.kernel.org
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
int kvm_assign_device(struct kvm *kvm,
		      struct kvm_assigned_dev_kernel *assigned_dev)
{
	struct pci_dev *pdev = NULL;
	struct iommu_domain *domain = kvm->arch.iommu_domain;
	int r;
	bool noncoherent;

	/* check if iommu exists and in use */
	if (!domain)
		return 0;

	pdev = assigned_dev->dev;
	if (pdev == NULL)
		return -ENODEV;

	r = iommu_attach_device(domain, &pdev->dev);
	if (r) {
		dev_err(&pdev->dev, "kvm assign device failed ret %d", r);
		return r;
	}

	noncoherent = !iommu_domain_has_cap(kvm->arch.iommu_domain,
					    IOMMU_CAP_CACHE_COHERENCY);

	/* Check if need to update IOMMU page table for guest memory */
	if (noncoherent != kvm->arch.iommu_noncoherent) {
		kvm_iommu_unmap_memslots(kvm);
		kvm->arch.iommu_noncoherent = noncoherent;
		r = kvm_iommu_map_memslots(kvm);
		if (r)
			goto out_unmap;
	}

	pdev->dev_flags |= PCI_DEV_FLAGS_ASSIGNED;

	dev_info(&pdev->dev, "kvm assign device\n");

	return 0;
out_unmap:
	kvm_iommu_unmap_memslots(kvm);
	return r;
}

int kvm_assign_device(struct kvm *kvm,
		      struct kvm_assigned_dev_kernel *assigned_dev)
{
	struct pci_dev *pdev = NULL;
	struct iommu_domain *domain = kvm->arch.iommu_domain;
	int r;
	bool noncoherent;

	/* check if iommu exists and in use */
	if (!domain)
		return 0;

	pdev = assigned_dev->dev;
	if (pdev == NULL)
		return -ENODEV;

	r = iommu_attach_device(domain, &pdev->dev);
	if (r) {
		dev_err(&pdev->dev, "kvm assign device failed ret %d", r);
		return r;
	}

	noncoherent = !iommu_domain_has_cap(kvm->arch.iommu_domain,
					    IOMMU_CAP_CACHE_COHERENCY);

	/* Check if need to update IOMMU page table for guest memory */
	if (noncoherent != kvm->arch.iommu_noncoherent) {
		kvm_iommu_unmap_memslots(kvm);
		kvm->arch.iommu_noncoherent = noncoherent;
		r = kvm_iommu_map_memslots(kvm);
		if (r)
			goto out_unmap;
	}

	pdev->dev_flags |= PCI_DEV_FLAGS_ASSIGNED;

	dev_info(&pdev->dev, "kvm assign device\n");

	return 0;
out_unmap:
	kvm_iommu_unmap_memslots(kvm);
	return r;
}
