Bugzilla: 1713567 Z-Bugzilla: 1739309 CVE: CVE-2019-11085 Build Info: https://brewweb.engineering.redhat.com/brew/taskinfo?taskID=25302094
This is a backport of 7.6.z patch to 7.4.z - 7.4.z needs intel_vgpu_in_aperture(), so add it.
7.6.z patch tested: Win10 VM with assigned Intel vGPU still works
This is to fix missed mmap range check on vGPU bar2 region and only allow to map vGPU allocated GMADDR range, which means user space should support sparse mmap to get proper offset for mmap vGPU aperture. And this takes care of actual pgoff in mmap request as original code always does from beginning of vGPU aperture.
Fixes: 659643f7d814 ("drm/i915/gvt/kvmgt: add vfio/mdev support to KVMGT") Cc: "Monroy, Rodrigo Axel" rodrigo.axel.monroy@intel.com Cc: "Orrala Contreras, Alfredo" alfredo.orrala.contreras@intel.com Cc: stable@vger.kernel.org # v4.10+ Reviewed-by: Hang Yuan hang.yuan@intel.com Signed-off-by: Zhenyu Wang zhenyuw@linux.intel.com (cherry picked from commit 51b00d8509dc69c98740da2ad07308b630d3eb7d) Signed-off-by: Denys Vlasenko dvlasenk@redhat.com --- drivers/gpu/drm/i915/gvt/kvmgt.c | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/i915/gvt/kvmgt.c b/drivers/gpu/drm/i915/gvt/kvmgt.c index e466259034e..d2696636f82 100644 --- a/drivers/gpu/drm/i915/gvt/kvmgt.c +++ b/drivers/gpu/drm/i915/gvt/kvmgt.c @@ -85,6 +85,12 @@ static inline bool handle_valid(unsigned long handle) return !!(handle & ~0xff); }
+static inline bool intel_vgpu_in_aperture(struct intel_vgpu *vgpu, uint64_t off) +{ + return off >= vgpu_aperture_offset(vgpu) && + off < vgpu_aperture_offset(vgpu) + vgpu_aperture_sz(vgpu); +} + static int kvmgt_guest_init(struct mdev_device *mdev); static void intel_vgpu_release_work(struct work_struct *work); static bool kvmgt_guest_exit(struct kvmgt_guest_info *info); @@ -803,7 +809,7 @@ static int intel_vgpu_mmap(struct mdev_device *mdev, struct vm_area_struct *vma) { unsigned int index; u64 virtaddr; - unsigned long req_size, pgoff = 0; + unsigned long req_size, pgoff, req_start; pgprot_t pg_prot; struct intel_vgpu *vgpu = mdev_get_drvdata(mdev);
@@ -821,7 +827,17 @@ static int intel_vgpu_mmap(struct mdev_device *mdev, struct vm_area_struct *vma) pg_prot = vma->vm_page_prot; virtaddr = vma->vm_start; req_size = vma->vm_end - vma->vm_start; - pgoff = vgpu_aperture_pa_base(vgpu) >> PAGE_SHIFT; + pgoff = vma->vm_pgoff & + ((1U << (VFIO_PCI_OFFSET_SHIFT - PAGE_SHIFT)) - 1); + req_start = pgoff << PAGE_SHIFT; + + if (!intel_vgpu_in_aperture(vgpu, req_start)) + return -EINVAL; + if (req_start + req_size > + vgpu_aperture_offset(vgpu) + vgpu_aperture_sz(vgpu)) + return -EINVAL; + + pgoff = (gvt_aperture_pa_base(vgpu->gvt) >> PAGE_SHIFT) + pgoff;
return remap_pfn_range(vma, virtaddr, pgoff, req_size, pg_prot); }