* [PATCH] drm/i915/gvt: fix double-free bug in split_2MB_gtt_entry @ 2022-09-18 19:24 Zheng Wang 2022-09-19 9:30 ` Jani Nikula 0 siblings, 1 reply; 50+ messages in thread From: Zheng Wang @ 2022-09-18 19:24 UTC (permalink / raw) To: gregkh Cc: alex000young, security, tvrtko.ursulin, airlied, intel-gfx, hackerzheng666, dri-devel, linux-kernel From afe79848cb74cc8e45ab426d13fa2394c87e0422 Mon Sep 17 00:00:00 2001 From: xmzyshypnc <1002992920@qq.com> Date: Fri, 16 Sep 2022 23:48:23 +0800 Subject: [PATCH] drm/i915/gvt: fix double-free bug in split_2MB_gtt_entry There is a double-free security bug in split_2MB_gtt_entry. Here is a calling chain : ppgtt_populate_spt->ppgtt_populate_shadow_entry->split_2MB_gtt_entry. If intel_gvt_dma_map_guest_page failed, it will call ppgtt_invalidate_spt, which will finally call ppgtt_free_spt and kfree(spt). But the caller does not notice that, and it will call ppgtt_free_spt again in error path. Fix this by only freeing spt in ppgtt_invalidate_spt in good case. Signed-off-by: xmzyshypnc <1002992920@qq.com> --- drivers/gpu/drm/i915/gvt/gtt.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/i915/gvt/gtt.c b/drivers/gpu/drm/i915/gvt/gtt.c index ce0eb03709c3..550519f0acca 100644 --- a/drivers/gpu/drm/i915/gvt/gtt.c +++ b/drivers/gpu/drm/i915/gvt/gtt.c @@ -959,7 +959,7 @@ static inline int ppgtt_put_spt(struct intel_vgpu_ppgtt_spt *spt) return atomic_dec_return(&spt->refcount); } -static int ppgtt_invalidate_spt(struct intel_vgpu_ppgtt_spt *spt); +static int ppgtt_invalidate_spt(struct intel_vgpu_ppgtt_spt *spt, int is_error); static int ppgtt_invalidate_spt_by_shadow_entry(struct intel_vgpu *vgpu, struct intel_gvt_gtt_entry *e) @@ -995,7 +995,7 @@ static int ppgtt_invalidate_spt_by_shadow_entry(struct intel_vgpu *vgpu, ops->get_pfn(e)); return -ENXIO; } - return ppgtt_invalidate_spt(s); + return ppgtt_invalidate_spt(s, 0); } static inline void ppgtt_invalidate_pte(struct intel_vgpu_ppgtt_spt *spt, @@ -1016,7 +1016,7 @@ static inline void ppgtt_invalidate_pte(struct intel_vgpu_ppgtt_spt *spt, intel_gvt_dma_unmap_guest_page(vgpu, pfn << PAGE_SHIFT); } -static int ppgtt_invalidate_spt(struct intel_vgpu_ppgtt_spt *spt) +static int ppgtt_invalidate_spt(struct intel_vgpu_ppgtt_spt *spt, int is_error) { struct intel_vgpu *vgpu = spt->vgpu; struct intel_gvt_gtt_entry e; @@ -1059,9 +1059,11 @@ static int ppgtt_invalidate_spt(struct intel_vgpu_ppgtt_spt *spt) } } - trace_spt_change(spt->vgpu->id, "release", spt, + if (!is_error) { + trace_spt_change(spt->vgpu->id, "release", spt, spt->guest_page.gfn, spt->shadow_page.type); - ppgtt_free_spt(spt); + ppgtt_free_spt(spt); + } return 0; fail: gvt_vgpu_err("fail: shadow page %p shadow entry 0x%llx type %d\n", @@ -1215,7 +1217,7 @@ static int split_2MB_gtt_entry(struct intel_vgpu *vgpu, ret = intel_gvt_dma_map_guest_page(vgpu, start_gfn + sub_index, PAGE_SIZE, &dma_addr); if (ret) { - ppgtt_invalidate_spt(spt); + ppgtt_invalidate_spt(spt, 1); return ret; } sub_se.val64 = se->val64; @@ -1393,7 +1395,7 @@ static int ppgtt_handle_guest_entry_removal(struct intel_vgpu_ppgtt_spt *spt, ret = -ENXIO; goto fail; } - ret = ppgtt_invalidate_spt(s); + ret = ppgtt_invalidate_spt(s, 0); if (ret) goto fail; } else { -- 2.25.1 ^ permalink raw reply related [flat|nested] 50+ messages in thread
* Re: [PATCH] drm/i915/gvt: fix double-free bug in split_2MB_gtt_entry 2022-09-18 19:24 [PATCH] drm/i915/gvt: fix double-free bug in split_2MB_gtt_entry Zheng Wang @ 2022-09-19 9:30 ` Jani Nikula 2022-09-19 9:55 ` Zheng Hacker 2022-09-21 9:13 ` Zheng Hacker 0 siblings, 2 replies; 50+ messages in thread From: Jani Nikula @ 2022-09-19 9:30 UTC (permalink / raw) To: Zheng Wang, gregkh Cc: alex000young, security, tvrtko.ursulin, airlied, intel-gfx, hackerzheng666, dri-devel, linux-kernel On Mon, 19 Sep 2022, Zheng Wang <1002992920@qq.com> wrote: > From afe79848cb74cc8e45ab426d13fa2394c87e0422 Mon Sep 17 00:00:00 2001 > From: xmzyshypnc <1002992920@qq.com> > Date: Fri, 16 Sep 2022 23:48:23 +0800 > Subject: [PATCH] drm/i915/gvt: fix double-free bug in split_2MB_gtt_entry > > There is a double-free security bug in split_2MB_gtt_entry. > > Here is a calling chain : > ppgtt_populate_spt->ppgtt_populate_shadow_entry->split_2MB_gtt_entry. > > If intel_gvt_dma_map_guest_page failed, it will call > ppgtt_invalidate_spt, which will finally call ppgtt_free_spt and > kfree(spt). But the caller does not notice that, and it will call > ppgtt_free_spt again in error path. > > Fix this by only freeing spt in ppgtt_invalidate_spt in good case. > > Signed-off-by: xmzyshypnc <1002992920@qq.com> Please use git send-email. The patch is whitespace broken and line wrapped, making it unusable. BR, Jani. > --- > drivers/gpu/drm/i915/gvt/gtt.c | 16 +++++++++------- > 1 file changed, 9 insertions(+), 7 deletions(-) > > diff --git a/drivers/gpu/drm/i915/gvt/gtt.c b/drivers/gpu/drm/i915/gvt/gtt.c > index ce0eb03709c3..550519f0acca 100644 > --- a/drivers/gpu/drm/i915/gvt/gtt.c > +++ b/drivers/gpu/drm/i915/gvt/gtt.c > @@ -959,7 +959,7 @@ static inline int ppgtt_put_spt(struct > intel_vgpu_ppgtt_spt *spt) > return atomic_dec_return(&spt->refcount); > } > > -static int ppgtt_invalidate_spt(struct intel_vgpu_ppgtt_spt *spt); > +static int ppgtt_invalidate_spt(struct intel_vgpu_ppgtt_spt *spt, int > is_error); > > static int ppgtt_invalidate_spt_by_shadow_entry(struct intel_vgpu *vgpu, > struct intel_gvt_gtt_entry *e) > @@ -995,7 +995,7 @@ static int > ppgtt_invalidate_spt_by_shadow_entry(struct intel_vgpu *vgpu, > ops->get_pfn(e)); > return -ENXIO; > } > - return ppgtt_invalidate_spt(s); > + return ppgtt_invalidate_spt(s, 0); > } > > static inline void ppgtt_invalidate_pte(struct intel_vgpu_ppgtt_spt *spt, > @@ -1016,7 +1016,7 @@ static inline void ppgtt_invalidate_pte(struct > intel_vgpu_ppgtt_spt *spt, > intel_gvt_dma_unmap_guest_page(vgpu, pfn << PAGE_SHIFT); > } > > -static int ppgtt_invalidate_spt(struct intel_vgpu_ppgtt_spt *spt) > +static int ppgtt_invalidate_spt(struct intel_vgpu_ppgtt_spt *spt, int > is_error) > { > struct intel_vgpu *vgpu = spt->vgpu; > struct intel_gvt_gtt_entry e; > @@ -1059,9 +1059,11 @@ static int ppgtt_invalidate_spt(struct > intel_vgpu_ppgtt_spt *spt) > } > } > > - trace_spt_change(spt->vgpu->id, "release", spt, > + if (!is_error) { > + trace_spt_change(spt->vgpu->id, "release", spt, > spt->guest_page.gfn, spt->shadow_page.type); > - ppgtt_free_spt(spt); > + ppgtt_free_spt(spt); > + } > return 0; > fail: > gvt_vgpu_err("fail: shadow page %p shadow entry 0x%llx type %d\n", > @@ -1215,7 +1217,7 @@ static int split_2MB_gtt_entry(struct intel_vgpu > *vgpu, > ret = intel_gvt_dma_map_guest_page(vgpu, start_gfn + sub_index, > PAGE_SIZE, &dma_addr); > if (ret) { > - ppgtt_invalidate_spt(spt); > + ppgtt_invalidate_spt(spt, 1); > return ret; > } > sub_se.val64 = se->val64; > @@ -1393,7 +1395,7 @@ static int ppgtt_handle_guest_entry_removal(struct > intel_vgpu_ppgtt_spt *spt, > ret = -ENXIO; > goto fail; > } > - ret = ppgtt_invalidate_spt(s); > + ret = ppgtt_invalidate_spt(s, 0); > if (ret) > goto fail; > } else { -- Jani Nikula, Intel Open Source Graphics Center ^ permalink raw reply [flat|nested] 50+ messages in thread
* Re: [PATCH] drm/i915/gvt: fix double-free bug in split_2MB_gtt_entry 2022-09-19 9:30 ` Jani Nikula @ 2022-09-19 9:55 ` Zheng Hacker 2022-09-21 9:13 ` Zheng Hacker 1 sibling, 0 replies; 50+ messages in thread From: Zheng Hacker @ 2022-09-19 9:55 UTC (permalink / raw) To: Jani Nikula Cc: tvrtko.ursulin, security, alex000young, airlied, gregkh, intel-gfx, linux-kernel, dri-devel, Zheng Wang Got it. I'll try again later. Best Regards, Zheng Wang Jani Nikula <jani.nikula@linux.intel.com> 于2022年9月19日周一 17:30写道: > > On Mon, 19 Sep 2022, Zheng Wang <1002992920@qq.com> wrote: > > From afe79848cb74cc8e45ab426d13fa2394c87e0422 Mon Sep 17 00:00:00 2001 > > From: xmzyshypnc <1002992920@qq.com> > > Date: Fri, 16 Sep 2022 23:48:23 +0800 > > Subject: [PATCH] drm/i915/gvt: fix double-free bug in split_2MB_gtt_entry > > > > There is a double-free security bug in split_2MB_gtt_entry. > > > > Here is a calling chain : > > ppgtt_populate_spt->ppgtt_populate_shadow_entry->split_2MB_gtt_entry. > > > > If intel_gvt_dma_map_guest_page failed, it will call > > ppgtt_invalidate_spt, which will finally call ppgtt_free_spt and > > kfree(spt). But the caller does not notice that, and it will call > > ppgtt_free_spt again in error path. > > > > Fix this by only freeing spt in ppgtt_invalidate_spt in good case. > > > > Signed-off-by: xmzyshypnc <1002992920@qq.com> > > Please use git send-email. The patch is whitespace broken and line > wrapped, making it unusable. > > BR, > Jani. > > > > --- > > drivers/gpu/drm/i915/gvt/gtt.c | 16 +++++++++------- > > 1 file changed, 9 insertions(+), 7 deletions(-) > > > > diff --git a/drivers/gpu/drm/i915/gvt/gtt.c b/drivers/gpu/drm/i915/gvt/gtt.c > > index ce0eb03709c3..550519f0acca 100644 > > --- a/drivers/gpu/drm/i915/gvt/gtt.c > > +++ b/drivers/gpu/drm/i915/gvt/gtt.c > > @@ -959,7 +959,7 @@ static inline int ppgtt_put_spt(struct > > intel_vgpu_ppgtt_spt *spt) > > return atomic_dec_return(&spt->refcount); > > } > > > > -static int ppgtt_invalidate_spt(struct intel_vgpu_ppgtt_spt *spt); > > +static int ppgtt_invalidate_spt(struct intel_vgpu_ppgtt_spt *spt, int > > is_error); > > > > static int ppgtt_invalidate_spt_by_shadow_entry(struct intel_vgpu *vgpu, > > struct intel_gvt_gtt_entry *e) > > @@ -995,7 +995,7 @@ static int > > ppgtt_invalidate_spt_by_shadow_entry(struct intel_vgpu *vgpu, > > ops->get_pfn(e)); > > return -ENXIO; > > } > > - return ppgtt_invalidate_spt(s); > > + return ppgtt_invalidate_spt(s, 0); > > } > > > > static inline void ppgtt_invalidate_pte(struct intel_vgpu_ppgtt_spt *spt, > > @@ -1016,7 +1016,7 @@ static inline void ppgtt_invalidate_pte(struct > > intel_vgpu_ppgtt_spt *spt, > > intel_gvt_dma_unmap_guest_page(vgpu, pfn << PAGE_SHIFT); > > } > > > > -static int ppgtt_invalidate_spt(struct intel_vgpu_ppgtt_spt *spt) > > +static int ppgtt_invalidate_spt(struct intel_vgpu_ppgtt_spt *spt, int > > is_error) > > { > > struct intel_vgpu *vgpu = spt->vgpu; > > struct intel_gvt_gtt_entry e; > > @@ -1059,9 +1059,11 @@ static int ppgtt_invalidate_spt(struct > > intel_vgpu_ppgtt_spt *spt) > > } > > } > > > > - trace_spt_change(spt->vgpu->id, "release", spt, > > + if (!is_error) { > > + trace_spt_change(spt->vgpu->id, "release", spt, > > spt->guest_page.gfn, spt->shadow_page.type); > > - ppgtt_free_spt(spt); > > + ppgtt_free_spt(spt); > > + } > > return 0; > > fail: > > gvt_vgpu_err("fail: shadow page %p shadow entry 0x%llx type %d\n", > > @@ -1215,7 +1217,7 @@ static int split_2MB_gtt_entry(struct intel_vgpu > > *vgpu, > > ret = intel_gvt_dma_map_guest_page(vgpu, start_gfn + sub_index, > > PAGE_SIZE, &dma_addr); > > if (ret) { > > - ppgtt_invalidate_spt(spt); > > + ppgtt_invalidate_spt(spt, 1); > > return ret; > > } > > sub_se.val64 = se->val64; > > @@ -1393,7 +1395,7 @@ static int ppgtt_handle_guest_entry_removal(struct > > intel_vgpu_ppgtt_spt *spt, > > ret = -ENXIO; > > goto fail; > > } > > - ret = ppgtt_invalidate_spt(s); > > + ret = ppgtt_invalidate_spt(s, 0); > > if (ret) > > goto fail; > > } else { > > -- > Jani Nikula, Intel Open Source Graphics Center ^ permalink raw reply [flat|nested] 50+ messages in thread
* Re: [PATCH] drm/i915/gvt: fix double-free bug in split_2MB_gtt_entry 2022-09-19 9:30 ` Jani Nikula 2022-09-19 9:55 ` Zheng Hacker @ 2022-09-21 9:13 ` Zheng Hacker 2022-09-28 3:33 ` [PATCH] drm/i915/gvt: fix double free " Zheng Wang 1 sibling, 1 reply; 50+ messages in thread From: Zheng Hacker @ 2022-09-21 9:13 UTC (permalink / raw) To: Jani Nikula Cc: tvrtko.ursulin, security, alex000young, airlied, gregkh, intel-gfx, linux-kernel, dri-devel, Zheng Wang I've sent it using git send-email with another email account (zyytlz.wz@163.com) Regards, Zheng Wang Jani Nikula <jani.nikula@linux.intel.com> 于2022年9月19日周一 17:30写道: > > On Mon, 19 Sep 2022, Zheng Wang <1002992920@qq.com> wrote: > > From afe79848cb74cc8e45ab426d13fa2394c87e0422 Mon Sep 17 00:00:00 2001 > > From: xmzyshypnc <1002992920@qq.com> > > Date: Fri, 16 Sep 2022 23:48:23 +0800 > > Subject: [PATCH] drm/i915/gvt: fix double-free bug in split_2MB_gtt_entry > > > > There is a double-free security bug in split_2MB_gtt_entry. > > > > Here is a calling chain : > > ppgtt_populate_spt->ppgtt_populate_shadow_entry->split_2MB_gtt_entry. > > > > If intel_gvt_dma_map_guest_page failed, it will call > > ppgtt_invalidate_spt, which will finally call ppgtt_free_spt and > > kfree(spt). But the caller does not notice that, and it will call > > ppgtt_free_spt again in error path. > > > > Fix this by only freeing spt in ppgtt_invalidate_spt in good case. > > > > Signed-off-by: xmzyshypnc <1002992920@qq.com> > > Please use git send-email. The patch is whitespace broken and line > wrapped, making it unusable. > > BR, > Jani. > > > > --- > > drivers/gpu/drm/i915/gvt/gtt.c | 16 +++++++++------- > > 1 file changed, 9 insertions(+), 7 deletions(-) > > > > diff --git a/drivers/gpu/drm/i915/gvt/gtt.c b/drivers/gpu/drm/i915/gvt/gtt.c > > index ce0eb03709c3..550519f0acca 100644 > > --- a/drivers/gpu/drm/i915/gvt/gtt.c > > +++ b/drivers/gpu/drm/i915/gvt/gtt.c > > @@ -959,7 +959,7 @@ static inline int ppgtt_put_spt(struct > > intel_vgpu_ppgtt_spt *spt) > > return atomic_dec_return(&spt->refcount); > > } > > > > -static int ppgtt_invalidate_spt(struct intel_vgpu_ppgtt_spt *spt); > > +static int ppgtt_invalidate_spt(struct intel_vgpu_ppgtt_spt *spt, int > > is_error); > > > > static int ppgtt_invalidate_spt_by_shadow_entry(struct intel_vgpu *vgpu, > > struct intel_gvt_gtt_entry *e) > > @@ -995,7 +995,7 @@ static int > > ppgtt_invalidate_spt_by_shadow_entry(struct intel_vgpu *vgpu, > > ops->get_pfn(e)); > > return -ENXIO; > > } > > - return ppgtt_invalidate_spt(s); > > + return ppgtt_invalidate_spt(s, 0); > > } > > > > static inline void ppgtt_invalidate_pte(struct intel_vgpu_ppgtt_spt *spt, > > @@ -1016,7 +1016,7 @@ static inline void ppgtt_invalidate_pte(struct > > intel_vgpu_ppgtt_spt *spt, > > intel_gvt_dma_unmap_guest_page(vgpu, pfn << PAGE_SHIFT); > > } > > > > -static int ppgtt_invalidate_spt(struct intel_vgpu_ppgtt_spt *spt) > > +static int ppgtt_invalidate_spt(struct intel_vgpu_ppgtt_spt *spt, int > > is_error) > > { > > struct intel_vgpu *vgpu = spt->vgpu; > > struct intel_gvt_gtt_entry e; > > @@ -1059,9 +1059,11 @@ static int ppgtt_invalidate_spt(struct > > intel_vgpu_ppgtt_spt *spt) > > } > > } > > > > - trace_spt_change(spt->vgpu->id, "release", spt, > > + if (!is_error) { > > + trace_spt_change(spt->vgpu->id, "release", spt, > > spt->guest_page.gfn, spt->shadow_page.type); > > - ppgtt_free_spt(spt); > > + ppgtt_free_spt(spt); > > + } > > return 0; > > fail: > > gvt_vgpu_err("fail: shadow page %p shadow entry 0x%llx type %d\n", > > @@ -1215,7 +1217,7 @@ static int split_2MB_gtt_entry(struct intel_vgpu > > *vgpu, > > ret = intel_gvt_dma_map_guest_page(vgpu, start_gfn + sub_index, > > PAGE_SIZE, &dma_addr); > > if (ret) { > > - ppgtt_invalidate_spt(spt); > > + ppgtt_invalidate_spt(spt, 1); > > return ret; > > } > > sub_se.val64 = se->val64; > > @@ -1393,7 +1395,7 @@ static int ppgtt_handle_guest_entry_removal(struct > > intel_vgpu_ppgtt_spt *spt, > > ret = -ENXIO; > > goto fail; > > } > > - ret = ppgtt_invalidate_spt(s); > > + ret = ppgtt_invalidate_spt(s, 0); > > if (ret) > > goto fail; > > } else { > > -- > Jani Nikula, Intel Open Source Graphics Center ^ permalink raw reply [flat|nested] 50+ messages in thread
* [PATCH] drm/i915/gvt: fix double free bug in split_2MB_gtt_entry 2022-09-21 9:13 ` Zheng Hacker @ 2022-09-28 3:33 ` Zheng Wang 2022-10-02 14:18 ` Greg KH 2022-10-06 16:58 ` [PATCH v2] " Zheng Wang 0 siblings, 2 replies; 50+ messages in thread From: Zheng Wang @ 2022-09-28 3:33 UTC (permalink / raw) To: hackerzheng666 Cc: alex000young, security, tvrtko.ursulin, airlied, gregkh, intel-gfx, linux-kernel, dri-devel, 1002992920, Zheng Wang If intel_gvt_dma_map_guest_page failed, it will call ppgtt_invalidate_spt, which will finally free the spt. But the caller does not notice that, it will free spt again in error path. Fix this by only freeing spt in ppgtt_invalidate_spt in good case. Fixes: b901b252b6cf ("drm/i915/gvt: Add 2M huge gtt support") Reported-by: Zheng Wang <hackerzheng666@gmail.com> Signed-off-by: Zheng Wang <zyytlz.wz@163.com> --- drivers/gpu/drm/i915/gvt/gtt.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/i915/gvt/gtt.c b/drivers/gpu/drm/i915/gvt/gtt.c index ce0eb03709c3..550519f0acca 100644 --- a/drivers/gpu/drm/i915/gvt/gtt.c +++ b/drivers/gpu/drm/i915/gvt/gtt.c @@ -959,7 +959,7 @@ static inline int ppgtt_put_spt(struct intel_vgpu_ppgtt_spt *spt) return atomic_dec_return(&spt->refcount); } -static int ppgtt_invalidate_spt(struct intel_vgpu_ppgtt_spt *spt); +static int ppgtt_invalidate_spt(struct intel_vgpu_ppgtt_spt *spt, int is_error); static int ppgtt_invalidate_spt_by_shadow_entry(struct intel_vgpu *vgpu, struct intel_gvt_gtt_entry *e) @@ -995,7 +995,7 @@ static int ppgtt_invalidate_spt_by_shadow_entry(struct intel_vgpu *vgpu, ops->get_pfn(e)); return -ENXIO; } - return ppgtt_invalidate_spt(s); + return ppgtt_invalidate_spt(s, 0); } static inline void ppgtt_invalidate_pte(struct intel_vgpu_ppgtt_spt *spt, @@ -1016,7 +1016,7 @@ static inline void ppgtt_invalidate_pte(struct intel_vgpu_ppgtt_spt *spt, intel_gvt_dma_unmap_guest_page(vgpu, pfn << PAGE_SHIFT); } -static int ppgtt_invalidate_spt(struct intel_vgpu_ppgtt_spt *spt) +static int ppgtt_invalidate_spt(struct intel_vgpu_ppgtt_spt *spt, int is_error) { struct intel_vgpu *vgpu = spt->vgpu; struct intel_gvt_gtt_entry e; @@ -1059,9 +1059,11 @@ static int ppgtt_invalidate_spt(struct intel_vgpu_ppgtt_spt *spt) } } - trace_spt_change(spt->vgpu->id, "release", spt, + if (!is_error) { + trace_spt_change(spt->vgpu->id, "release", spt, spt->guest_page.gfn, spt->shadow_page.type); - ppgtt_free_spt(spt); + ppgtt_free_spt(spt); + } return 0; fail: gvt_vgpu_err("fail: shadow page %p shadow entry 0x%llx type %d\n", @@ -1215,7 +1217,7 @@ static int split_2MB_gtt_entry(struct intel_vgpu *vgpu, ret = intel_gvt_dma_map_guest_page(vgpu, start_gfn + sub_index, PAGE_SIZE, &dma_addr); if (ret) { - ppgtt_invalidate_spt(spt); + ppgtt_invalidate_spt(spt, 1); return ret; } sub_se.val64 = se->val64; @@ -1393,7 +1395,7 @@ static int ppgtt_handle_guest_entry_removal(struct intel_vgpu_ppgtt_spt *spt, ret = -ENXIO; goto fail; } - ret = ppgtt_invalidate_spt(s); + ret = ppgtt_invalidate_spt(s, 0); if (ret) goto fail; } else { -- 2.25.1 ^ permalink raw reply related [flat|nested] 50+ messages in thread
* Re: [PATCH] drm/i915/gvt: fix double free bug in split_2MB_gtt_entry 2022-09-28 3:33 ` [PATCH] drm/i915/gvt: fix double free " Zheng Wang @ 2022-10-02 14:18 ` Greg KH 2022-10-03 4:36 ` Zheng Hacker 2022-10-06 16:58 ` [PATCH v2] " Zheng Wang 1 sibling, 1 reply; 50+ messages in thread From: Greg KH @ 2022-10-02 14:18 UTC (permalink / raw) To: Zheng Wang Cc: alex000young, security, tvrtko.ursulin, airlied, intel-gfx, hackerzheng666, dri-devel, linux-kernel, 1002992920 On Wed, Sep 28, 2022 at 11:33:40AM +0800, Zheng Wang wrote: > If intel_gvt_dma_map_guest_page failed, it will call > ppgtt_invalidate_spt, which will finally free the spt. > But the caller does not notice that, it will free spt again in error path. > > Fix this by only freeing spt in ppgtt_invalidate_spt in good case. > > Fixes: b901b252b6cf ("drm/i915/gvt: Add 2M huge gtt support") > Reported-by: Zheng Wang <hackerzheng666@gmail.com> > Signed-off-by: Zheng Wang <zyytlz.wz@163.com> > --- > drivers/gpu/drm/i915/gvt/gtt.c | 16 +++++++++------- > 1 file changed, 9 insertions(+), 7 deletions(-) > > diff --git a/drivers/gpu/drm/i915/gvt/gtt.c b/drivers/gpu/drm/i915/gvt/gtt.c > index ce0eb03709c3..550519f0acca 100644 > --- a/drivers/gpu/drm/i915/gvt/gtt.c > +++ b/drivers/gpu/drm/i915/gvt/gtt.c > @@ -959,7 +959,7 @@ static inline int ppgtt_put_spt(struct intel_vgpu_ppgtt_spt *spt) > return atomic_dec_return(&spt->refcount); > } > > -static int ppgtt_invalidate_spt(struct intel_vgpu_ppgtt_spt *spt); > +static int ppgtt_invalidate_spt(struct intel_vgpu_ppgtt_spt *spt, int is_error); That is a horrible way to make an api (and it should be a bool too.) Now every time you see this call in the code, you have to go look up what the last parameter means. Just make 2 functions, one that does the "is error" thing, and one that does not, and that will be much easier to maintain and understand for the next 10+ years. thanks, greg k-h ^ permalink raw reply [flat|nested] 50+ messages in thread
* Re: [PATCH] drm/i915/gvt: fix double free bug in split_2MB_gtt_entry 2022-10-02 14:18 ` Greg KH @ 2022-10-03 4:36 ` Zheng Hacker 0 siblings, 0 replies; 50+ messages in thread From: Zheng Hacker @ 2022-10-03 4:36 UTC (permalink / raw) To: Greg KH Cc: alex000young, security, tvrtko.ursulin, airlied, intel-gfx, linux-kernel, dri-devel, 1002992920, Zheng Wang > That is a horrible way to make an api (and it should be a bool too.) > Now every time you see this call in the code, you have to go look up > what the last parameter means. Just make 2 functions, one that does the > "is error" thing, and one that does not, and that will be much easier to > maintain and understand for the next 10+ years. Got it. I'll figure out anothr way. :) Thanks, Zheng Wang ^ permalink raw reply [flat|nested] 50+ messages in thread
* [PATCH v2] drm/i915/gvt: fix double free bug in split_2MB_gtt_entry 2022-09-28 3:33 ` [PATCH] drm/i915/gvt: fix double free " Zheng Wang 2022-10-02 14:18 ` Greg KH @ 2022-10-06 16:58 ` Zheng Wang 2022-10-06 19:23 ` Greg KH 1 sibling, 1 reply; 50+ messages in thread From: Zheng Wang @ 2022-10-06 16:58 UTC (permalink / raw) To: zyytlz.wz Cc: alex000young, security, tvrtko.ursulin, airlied, gregkh, intel-gfx, hackerzheng666, dri-devel, linux-kernel, 1002992920 If intel_gvt_dma_map_guest_page failed, it will call ppgtt_invalidate_spt, which will finally free the spt. But the caller does not notice that, it will free spt again in error path. Fix this by spliting invalidate and free in ppgtt_invalidate_spt. Only free spt when in good case. Reported-by: Zheng Wang <hackerzheng666@gmail.com> Signed-off-by: Zheng Wang <zyytlz.wz@163.com> --- v2: - split initial function into two api function suggested by Greg v1: https://lore.kernel.org/all/20220928033340.1063949-1-zyytlz.wz@163.com/ --- drivers/gpu/drm/i915/gvt/gtt.c | 31 +++++++++++++++++++++---------- 1 file changed, 21 insertions(+), 10 deletions(-) diff --git a/drivers/gpu/drm/i915/gvt/gtt.c b/drivers/gpu/drm/i915/gvt/gtt.c index ce0eb03709c3..55d8e1419302 100644 --- a/drivers/gpu/drm/i915/gvt/gtt.c +++ b/drivers/gpu/drm/i915/gvt/gtt.c @@ -959,6 +959,7 @@ static inline int ppgtt_put_spt(struct intel_vgpu_ppgtt_spt *spt) return atomic_dec_return(&spt->refcount); } +static int ppgtt_invalidate_and_free_spt(struct intel_vgpu_ppgtt_spt *spt); static int ppgtt_invalidate_spt(struct intel_vgpu_ppgtt_spt *spt); static int ppgtt_invalidate_spt_by_shadow_entry(struct intel_vgpu *vgpu, @@ -995,7 +996,7 @@ static int ppgtt_invalidate_spt_by_shadow_entry(struct intel_vgpu *vgpu, ops->get_pfn(e)); return -ENXIO; } - return ppgtt_invalidate_spt(s); + return ppgtt_invalidate_and_free_spt(s); } static inline void ppgtt_invalidate_pte(struct intel_vgpu_ppgtt_spt *spt, @@ -1016,18 +1017,31 @@ static inline void ppgtt_invalidate_pte(struct intel_vgpu_ppgtt_spt *spt, intel_gvt_dma_unmap_guest_page(vgpu, pfn << PAGE_SHIFT); } -static int ppgtt_invalidate_spt(struct intel_vgpu_ppgtt_spt *spt) +static int ppgtt_invalidate_and_free_spt(struct intel_vgpu_ppgtt_spt *spt) { struct intel_vgpu *vgpu = spt->vgpu; - struct intel_gvt_gtt_entry e; - unsigned long index; int ret; trace_spt_change(spt->vgpu->id, "die", spt, - spt->guest_page.gfn, spt->shadow_page.type); - + spt->guest_page.gfn, spt->shadow_page.type); if (ppgtt_put_spt(spt) > 0) return 0; + ret = ppgtt_invalidate_spt(spt); + if (!ret) { + trace_spt_change(spt->vgpu->id, "release", spt, + spt->guest_page.gfn, spt->shadow_page.type); + ppgtt_free_spt(spt); + } + + return ret; +} + +static int ppgtt_invalidate_spt(struct intel_vgpu_ppgtt_spt *spt) +{ + struct intel_vgpu *vgpu = spt->vgpu; + struct intel_gvt_gtt_entry e; + unsigned long index; + int ret; for_each_present_shadow_entry(spt, &e, index) { switch (e.type) { @@ -1059,9 +1073,6 @@ static int ppgtt_invalidate_spt(struct intel_vgpu_ppgtt_spt *spt) } } - trace_spt_change(spt->vgpu->id, "release", spt, - spt->guest_page.gfn, spt->shadow_page.type); - ppgtt_free_spt(spt); return 0; fail: gvt_vgpu_err("fail: shadow page %p shadow entry 0x%llx type %d\n", @@ -1393,7 +1404,7 @@ static int ppgtt_handle_guest_entry_removal(struct intel_vgpu_ppgtt_spt *spt, ret = -ENXIO; goto fail; } - ret = ppgtt_invalidate_spt(s); + ret = ppgtt_invalidate_and_free_spt(s); if (ret) goto fail; } else { -- 2.25.1 ^ permalink raw reply related [flat|nested] 50+ messages in thread
* Re: [PATCH v2] drm/i915/gvt: fix double free bug in split_2MB_gtt_entry 2022-10-06 16:58 ` [PATCH v2] " Zheng Wang @ 2022-10-06 19:23 ` Greg KH 2022-10-07 0:39 ` Zheng Hacker 2022-10-07 1:37 ` [PATCH v3] " Zheng Wang 0 siblings, 2 replies; 50+ messages in thread From: Greg KH @ 2022-10-06 19:23 UTC (permalink / raw) To: Zheng Wang Cc: alex000young, security, tvrtko.ursulin, airlied, intel-gfx, hackerzheng666, dri-devel, linux-kernel, 1002992920 On Fri, Oct 07, 2022 at 12:58:45AM +0800, Zheng Wang wrote: > If intel_gvt_dma_map_guest_page failed, it will call > ppgtt_invalidate_spt, which will finally free the spt. > But the caller does not notice that, it will free spt again in error path. > > Fix this by spliting invalidate and free in ppgtt_invalidate_spt. > Only free spt when in good case. > > Reported-by: Zheng Wang <hackerzheng666@gmail.com> > Signed-off-by: Zheng Wang <zyytlz.wz@163.com> > --- > v2: > - split initial function into two api function suggested by Greg > > v1: https://lore.kernel.org/all/20220928033340.1063949-1-zyytlz.wz@163.com/ > --- > drivers/gpu/drm/i915/gvt/gtt.c | 31 +++++++++++++++++++++---------- > 1 file changed, 21 insertions(+), 10 deletions(-) > > diff --git a/drivers/gpu/drm/i915/gvt/gtt.c b/drivers/gpu/drm/i915/gvt/gtt.c > index ce0eb03709c3..55d8e1419302 100644 > --- a/drivers/gpu/drm/i915/gvt/gtt.c > +++ b/drivers/gpu/drm/i915/gvt/gtt.c > @@ -959,6 +959,7 @@ static inline int ppgtt_put_spt(struct intel_vgpu_ppgtt_spt *spt) > return atomic_dec_return(&spt->refcount); > } > > +static int ppgtt_invalidate_and_free_spt(struct intel_vgpu_ppgtt_spt *spt); Odd extra space after the 'int', why? ^ permalink raw reply [flat|nested] 50+ messages in thread
* Re: [PATCH v2] drm/i915/gvt: fix double free bug in split_2MB_gtt_entry 2022-10-06 19:23 ` Greg KH @ 2022-10-07 0:39 ` Zheng Hacker 2022-10-07 1:37 ` [PATCH v3] " Zheng Wang 1 sibling, 0 replies; 50+ messages in thread From: Zheng Hacker @ 2022-10-07 0:39 UTC (permalink / raw) To: Greg KH Cc: alex000young, security, tvrtko.ursulin, airlied, intel-gfx, linux-kernel, dri-devel, 1002992920, Zheng Wang Greg KH <gregkh@linuxfoundation.org> 于2022年10月7日周五 03:22写道: > > On Fri, Oct 07, 2022 at 12:58:45AM +0800, Zheng Wang wrote: > > If intel_gvt_dma_map_guest_page failed, it will call > > ppgtt_invalidate_spt, which will finally free the spt. > > But the caller does not notice that, it will free spt again in error path. > > > > Fix this by spliting invalidate and free in ppgtt_invalidate_spt. > > Only free spt when in good case. > > > > Reported-by: Zheng Wang <hackerzheng666@gmail.com> > > Signed-off-by: Zheng Wang <zyytlz.wz@163.com> > > --- > > v2: > > - split initial function into two api function suggested by Greg > > > > v1: https://lore.kernel.org/all/20220928033340.1063949-1-zyytlz.wz@163.com/ > > --- > > drivers/gpu/drm/i915/gvt/gtt.c | 31 +++++++++++++++++++++---------- > > 1 file changed, 21 insertions(+), 10 deletions(-) > > > > diff --git a/drivers/gpu/drm/i915/gvt/gtt.c b/drivers/gpu/drm/i915/gvt/gtt.c > > index ce0eb03709c3..55d8e1419302 100644 > > --- a/drivers/gpu/drm/i915/gvt/gtt.c > > +++ b/drivers/gpu/drm/i915/gvt/gtt.c > > @@ -959,6 +959,7 @@ static inline int ppgtt_put_spt(struct intel_vgpu_ppgtt_spt *spt) > > return atomic_dec_return(&spt->refcount); > > } > > > > +static int ppgtt_invalidate_and_free_spt(struct intel_vgpu_ppgtt_spt *spt); > > Odd extra space after the 'int', why? > Hi Greg, Sorry it's a spelling mistake. I'll correct it right away :) Thanks, Zheng Wang ^ permalink raw reply [flat|nested] 50+ messages in thread
* [PATCH v3] drm/i915/gvt: fix double free bug in split_2MB_gtt_entry 2022-10-06 19:23 ` Greg KH 2022-10-07 0:39 ` Zheng Hacker @ 2022-10-07 1:37 ` Zheng Wang 2022-10-27 0:01 ` Dave Airlie 1 sibling, 1 reply; 50+ messages in thread From: Zheng Wang @ 2022-10-07 1:37 UTC (permalink / raw) To: gregkh Cc: alex000young, security, airlied, intel-gfx, hackerzheng666, dri-devel, linux-kernel, 1002992920, zyytlz.wz If intel_gvt_dma_map_guest_page failed, it will call ppgtt_invalidate_spt, which will finally free the spt. But the caller does not notice that, it will free spt again in error path. Fix this by spliting invalidate and free in ppgtt_invalidate_spt. Only free spt when in good case. Reported-by: Zheng Wang <hackerzheng666@gmail.com> Signed-off-by: Zheng Wang <zyytlz.wz@163.com> --- v3: - correct spelling mistake and remove unused variable suggested by Greg v2: https://lore.kernel.org/all/20221006165845.1735393-1-zyytlz.wz@163.com/ v1: https://lore.kernel.org/all/20220928033340.1063949-1-zyytlz.wz@163.com/ --- drivers/gpu/drm/i915/gvt/gtt.c | 32 +++++++++++++++++++++----------- 1 file changed, 21 insertions(+), 11 deletions(-) diff --git a/drivers/gpu/drm/i915/gvt/gtt.c b/drivers/gpu/drm/i915/gvt/gtt.c index ce0eb03709c3..865d33762e45 100644 --- a/drivers/gpu/drm/i915/gvt/gtt.c +++ b/drivers/gpu/drm/i915/gvt/gtt.c @@ -959,6 +959,7 @@ static inline int ppgtt_put_spt(struct intel_vgpu_ppgtt_spt *spt) return atomic_dec_return(&spt->refcount); } +static int ppgtt_invalidate_and_free_spt(struct intel_vgpu_ppgtt_spt *spt); static int ppgtt_invalidate_spt(struct intel_vgpu_ppgtt_spt *spt); static int ppgtt_invalidate_spt_by_shadow_entry(struct intel_vgpu *vgpu, @@ -995,7 +996,7 @@ static int ppgtt_invalidate_spt_by_shadow_entry(struct intel_vgpu *vgpu, ops->get_pfn(e)); return -ENXIO; } - return ppgtt_invalidate_spt(s); + return ppgtt_invalidate_and_free_spt(s); } static inline void ppgtt_invalidate_pte(struct intel_vgpu_ppgtt_spt *spt, @@ -1016,18 +1017,30 @@ static inline void ppgtt_invalidate_pte(struct intel_vgpu_ppgtt_spt *spt, intel_gvt_dma_unmap_guest_page(vgpu, pfn << PAGE_SHIFT); } -static int ppgtt_invalidate_spt(struct intel_vgpu_ppgtt_spt *spt) +static int ppgtt_invalidate_and_free_spt(struct intel_vgpu_ppgtt_spt *spt) { - struct intel_vgpu *vgpu = spt->vgpu; - struct intel_gvt_gtt_entry e; - unsigned long index; int ret; trace_spt_change(spt->vgpu->id, "die", spt, - spt->guest_page.gfn, spt->shadow_page.type); - + spt->guest_page.gfn, spt->shadow_page.type); if (ppgtt_put_spt(spt) > 0) return 0; + ret = ppgtt_invalidate_spt(spt); + if (!ret) { + trace_spt_change(spt->vgpu->id, "release", spt, + spt->guest_page.gfn, spt->shadow_page.type); + ppgtt_free_spt(spt); + } + + return ret; +} + +static int ppgtt_invalidate_spt(struct intel_vgpu_ppgtt_spt *spt) +{ + struct intel_vgpu *vgpu = spt->vgpu; + struct intel_gvt_gtt_entry e; + unsigned long index; + int ret; for_each_present_shadow_entry(spt, &e, index) { switch (e.type) { @@ -1059,9 +1072,6 @@ static int ppgtt_invalidate_spt(struct intel_vgpu_ppgtt_spt *spt) } } - trace_spt_change(spt->vgpu->id, "release", spt, - spt->guest_page.gfn, spt->shadow_page.type); - ppgtt_free_spt(spt); return 0; fail: gvt_vgpu_err("fail: shadow page %p shadow entry 0x%llx type %d\n", @@ -1393,7 +1403,7 @@ static int ppgtt_handle_guest_entry_removal(struct intel_vgpu_ppgtt_spt *spt, ret = -ENXIO; goto fail; } - ret = ppgtt_invalidate_spt(s); + ret = ppgtt_invalidate_and_free_spt(s); if (ret) goto fail; } else { -- 2.25.1 ^ permalink raw reply related [flat|nested] 50+ messages in thread
* Re: [PATCH v3] drm/i915/gvt: fix double free bug in split_2MB_gtt_entry 2022-10-07 1:37 ` [PATCH v3] " Zheng Wang @ 2022-10-27 0:01 ` Dave Airlie 2022-10-27 3:26 ` Zheng Hacker 0 siblings, 1 reply; 50+ messages in thread From: Dave Airlie @ 2022-10-27 0:01 UTC (permalink / raw) To: Zheng Wang Cc: alex000young, security, airlied, gregkh, intel-gfx, hackerzheng666, dri-devel, linux-kernel, 1002992920 On Fri, 7 Oct 2022 at 11:38, Zheng Wang <zyytlz.wz@163.com> wrote: > > If intel_gvt_dma_map_guest_page failed, it will call > ppgtt_invalidate_spt, which will finally free the spt. > But the caller does not notice that, it will free spt again in error path. > > Fix this by spliting invalidate and free in ppgtt_invalidate_spt. > Only free spt when in good case. > > Reported-by: Zheng Wang <hackerzheng666@gmail.com> > Signed-off-by: Zheng Wang <zyytlz.wz@163.com> Has this landed in a tree yet, since it's a possible CVE, might be good to merge it somewhere. Dave. > --- > v3: > - correct spelling mistake and remove unused variable suggested by Greg > > v2: https://lore.kernel.org/all/20221006165845.1735393-1-zyytlz.wz@163.com/ > > v1: https://lore.kernel.org/all/20220928033340.1063949-1-zyytlz.wz@163.com/ > --- > drivers/gpu/drm/i915/gvt/gtt.c | 32 +++++++++++++++++++++----------- > 1 file changed, 21 insertions(+), 11 deletions(-) > > diff --git a/drivers/gpu/drm/i915/gvt/gtt.c b/drivers/gpu/drm/i915/gvt/gtt.c > index ce0eb03709c3..865d33762e45 100644 > --- a/drivers/gpu/drm/i915/gvt/gtt.c > +++ b/drivers/gpu/drm/i915/gvt/gtt.c > @@ -959,6 +959,7 @@ static inline int ppgtt_put_spt(struct intel_vgpu_ppgtt_spt *spt) > return atomic_dec_return(&spt->refcount); > } > > +static int ppgtt_invalidate_and_free_spt(struct intel_vgpu_ppgtt_spt *spt); > static int ppgtt_invalidate_spt(struct intel_vgpu_ppgtt_spt *spt); > > static int ppgtt_invalidate_spt_by_shadow_entry(struct intel_vgpu *vgpu, > @@ -995,7 +996,7 @@ static int ppgtt_invalidate_spt_by_shadow_entry(struct intel_vgpu *vgpu, > ops->get_pfn(e)); > return -ENXIO; > } > - return ppgtt_invalidate_spt(s); > + return ppgtt_invalidate_and_free_spt(s); > } > > static inline void ppgtt_invalidate_pte(struct intel_vgpu_ppgtt_spt *spt, > @@ -1016,18 +1017,30 @@ static inline void ppgtt_invalidate_pte(struct intel_vgpu_ppgtt_spt *spt, > intel_gvt_dma_unmap_guest_page(vgpu, pfn << PAGE_SHIFT); > } > > -static int ppgtt_invalidate_spt(struct intel_vgpu_ppgtt_spt *spt) > +static int ppgtt_invalidate_and_free_spt(struct intel_vgpu_ppgtt_spt *spt) > { > - struct intel_vgpu *vgpu = spt->vgpu; > - struct intel_gvt_gtt_entry e; > - unsigned long index; > int ret; > > trace_spt_change(spt->vgpu->id, "die", spt, > - spt->guest_page.gfn, spt->shadow_page.type); > - > + spt->guest_page.gfn, spt->shadow_page.type); > if (ppgtt_put_spt(spt) > 0) > return 0; > + ret = ppgtt_invalidate_spt(spt); > + if (!ret) { > + trace_spt_change(spt->vgpu->id, "release", spt, > + spt->guest_page.gfn, spt->shadow_page.type); > + ppgtt_free_spt(spt); > + } > + > + return ret; > +} > + > +static int ppgtt_invalidate_spt(struct intel_vgpu_ppgtt_spt *spt) > +{ > + struct intel_vgpu *vgpu = spt->vgpu; > + struct intel_gvt_gtt_entry e; > + unsigned long index; > + int ret; > > for_each_present_shadow_entry(spt, &e, index) { > switch (e.type) { > @@ -1059,9 +1072,6 @@ static int ppgtt_invalidate_spt(struct intel_vgpu_ppgtt_spt *spt) > } > } > > - trace_spt_change(spt->vgpu->id, "release", spt, > - spt->guest_page.gfn, spt->shadow_page.type); > - ppgtt_free_spt(spt); > return 0; > fail: > gvt_vgpu_err("fail: shadow page %p shadow entry 0x%llx type %d\n", > @@ -1393,7 +1403,7 @@ static int ppgtt_handle_guest_entry_removal(struct intel_vgpu_ppgtt_spt *spt, > ret = -ENXIO; > goto fail; > } > - ret = ppgtt_invalidate_spt(s); > + ret = ppgtt_invalidate_and_free_spt(s); > if (ret) > goto fail; > } else { > -- > 2.25.1 > ^ permalink raw reply [flat|nested] 50+ messages in thread
* Re: [PATCH v3] drm/i915/gvt: fix double free bug in split_2MB_gtt_entry 2022-10-27 0:01 ` Dave Airlie @ 2022-10-27 3:26 ` Zheng Hacker 2022-10-27 5:12 ` Dave Airlie 0 siblings, 1 reply; 50+ messages in thread From: Zheng Hacker @ 2022-10-27 3:26 UTC (permalink / raw) To: Dave Airlie Cc: alex000young, security, airlied, gregkh, intel-gfx, linux-kernel, dri-devel, 1002992920, Zheng Wang Dave Airlie <airlied@gmail.com> 于2022年10月27日周四 08:01写道: > > On Fri, 7 Oct 2022 at 11:38, Zheng Wang <zyytlz.wz@163.com> wrote: > > > > If intel_gvt_dma_map_guest_page failed, it will call > > ppgtt_invalidate_spt, which will finally free the spt. > > But the caller does not notice that, it will free spt again in error path. > > > > Fix this by spliting invalidate and free in ppgtt_invalidate_spt. > > Only free spt when in good case. > > > > Reported-by: Zheng Wang <hackerzheng666@gmail.com> > > Signed-off-by: Zheng Wang <zyytlz.wz@163.com> > > Has this landed in a tree yet, since it's a possible CVE, might be > good to merge it somewhere. > > Dave. > Hi Dave, This patched hasn't been merged yet. Could you please help with this? Best Regards, Zheng Wang ^ permalink raw reply [flat|nested] 50+ messages in thread
* Re: [PATCH v3] drm/i915/gvt: fix double free bug in split_2MB_gtt_entry 2022-10-27 3:26 ` Zheng Hacker @ 2022-10-27 5:12 ` Dave Airlie 2022-10-30 15:10 ` Zheng Hacker 2022-12-15 10:47 ` Joonas Lahtinen 0 siblings, 2 replies; 50+ messages in thread From: Dave Airlie @ 2022-10-27 5:12 UTC (permalink / raw) To: Zheng Hacker Cc: alex000young, security, airlied, gregkh, intel-gfx, linux-kernel, dri-devel, 1002992920, Zheng Wang, intel-gvt-dev, zhi.a.wang On Thu, 27 Oct 2022 at 13:26, Zheng Hacker <hackerzheng666@gmail.com> wrote: > > Dave Airlie <airlied@gmail.com> 于2022年10月27日周四 08:01写道: > > > > On Fri, 7 Oct 2022 at 11:38, Zheng Wang <zyytlz.wz@163.com> wrote: > > > > > > If intel_gvt_dma_map_guest_page failed, it will call > > > ppgtt_invalidate_spt, which will finally free the spt. > > > But the caller does not notice that, it will free spt again in error path. > > > > > > Fix this by spliting invalidate and free in ppgtt_invalidate_spt. > > > Only free spt when in good case. > > > > > > Reported-by: Zheng Wang <hackerzheng666@gmail.com> > > > Signed-off-by: Zheng Wang <zyytlz.wz@163.com> > > > > Has this landed in a tree yet, since it's a possible CVE, might be > > good to merge it somewhere. > > > > Dave. > > > > Hi Dave, > > This patched hasn't been merged yet. Could you please help with this? I'll add some more people who can probably look at it. Dave. ^ permalink raw reply [flat|nested] 50+ messages in thread
* Re: [PATCH v3] drm/i915/gvt: fix double free bug in split_2MB_gtt_entry 2022-10-27 5:12 ` Dave Airlie @ 2022-10-30 15:10 ` Zheng Hacker 2022-12-15 10:47 ` Joonas Lahtinen 1 sibling, 0 replies; 50+ messages in thread From: Zheng Hacker @ 2022-10-30 15:10 UTC (permalink / raw) To: Dave Airlie Cc: alex000young, security, airlied, gregkh, intel-gfx, linux-kernel, dri-devel, 1002992920, Zheng Wang, intel-gvt-dev, zhi.a.wang Dave Airlie <airlied@gmail.com> 于2022年10月27日周四 13:12写道: > I'll add some more people who can probably look at it. > > Dave. Got it, Thanks Dave. Regards, Zheng Wang ^ permalink raw reply [flat|nested] 50+ messages in thread
* Re: [PATCH v3] drm/i915/gvt: fix double free bug in split_2MB_gtt_entry 2022-10-27 5:12 ` Dave Airlie 2022-10-30 15:10 ` Zheng Hacker @ 2022-12-15 10:47 ` Joonas Lahtinen 2022-12-15 11:33 ` Wang, Zhi A 1 sibling, 1 reply; 50+ messages in thread From: Joonas Lahtinen @ 2022-12-15 10:47 UTC (permalink / raw) To: Dave Airlie, Zheng Hacker, Zhenyu Wang, Tvrtko Ursulin Cc: alex000young, security, airlied, gregkh, intel-gfx, linux-kernel, dri-devel, 1002992920, Zheng Wang, intel-gvt-dev, zhi.a.wang (+ Tvrtko as FYI) Zhenyu, can you take a look at the patch ASAP. Regards, Joonas Quoting Dave Airlie (2022-10-27 08:12:31) > On Thu, 27 Oct 2022 at 13:26, Zheng Hacker <hackerzheng666@gmail.com> wrote: > > > > Dave Airlie <airlied@gmail.com> 于2022年10月27日周四 08:01写道: > > > > > > On Fri, 7 Oct 2022 at 11:38, Zheng Wang <zyytlz.wz@163.com> wrote: > > > > > > > > If intel_gvt_dma_map_guest_page failed, it will call > > > > ppgtt_invalidate_spt, which will finally free the spt. > > > > But the caller does not notice that, it will free spt again in error path. > > > > > > > > Fix this by spliting invalidate and free in ppgtt_invalidate_spt. > > > > Only free spt when in good case. > > > > > > > > Reported-by: Zheng Wang <hackerzheng666@gmail.com> > > > > Signed-off-by: Zheng Wang <zyytlz.wz@163.com> > > > > > > Has this landed in a tree yet, since it's a possible CVE, might be > > > good to merge it somewhere. > > > > > > Dave. > > > > > > > Hi Dave, > > > > This patched hasn't been merged yet. Could you please help with this? > > I'll add some more people who can probably look at it. > > Dave. ^ permalink raw reply [flat|nested] 50+ messages in thread
* Re: [PATCH v3] drm/i915/gvt: fix double free bug in split_2MB_gtt_entry 2022-12-15 10:47 ` Joonas Lahtinen @ 2022-12-15 11:33 ` Wang, Zhi A 2022-12-15 13:26 ` Zheng Hacker 2022-12-19 7:57 ` [Intel-gfx] " Zheng Wang 0 siblings, 2 replies; 50+ messages in thread From: Wang, Zhi A @ 2022-12-15 11:33 UTC (permalink / raw) To: Joonas Lahtinen, Dave Airlie, Zheng Hacker, Zhenyu Wang, Tvrtko Ursulin Cc: alex000young, security, airlied, gregkh, intel-gfx, linux-kernel, dri-devel, 1002992920, Zheng Wang, intel-gvt-dev On 12/15/2022 12:47 PM, Joonas Lahtinen wrote: > (+ Tvrtko as FYI) > > Zhenyu, can you take a look at the patch ASAP. > > Regards, Joonas Thanks so much for the reminding and patch. Actually I don't think it is proper fix as: split_2MB_gtt_entry() is going to allocate a new spt structure, which is a PTE page to hold the mapping of the 2MB. It will map the sub 4k pages for DMA addrs, form them as PTE entries, write the entries into the new PTE page, and then link the page to the parent table entry so that the GPU can reach it. Now something wrong happens when mapping the sub 4K pages. What we need are 1) The existing mappings of DMA addr need to be un-done and 2) the newly allocated spt structure needs to be freed. These can be handle by ppgtt_invalidate_spt() which will handle the 1) and 2) based on the type of shadow page table, either recursively or not. i.e. in this case, it's a PTE page. I guess the code wrongly does 1) 2) on the parent page table when something error happens in DMA mapping . You can fix it by releasing the newly allocated spt in the error case and put a Fixes: b901b252b6cf ("drm/i915/gvt: Add 2M huge gtt support") in the patch comment. BTW: For sending the patches, you can take a look on "git send-email". It will promise the correct format and prevent quite some bumps. For email clients, if you feel mutt is hard to ramp up, you can try the Claws Mail. More information can be found in Documentation/process/email-clients.rst Thanks, Zhi. > > Quoting Dave Airlie (2022-10-27 08:12:31) >> On Thu, 27 Oct 2022 at 13:26, Zheng Hacker <hackerzheng666@gmail.com> wrote: >>> Dave Airlie <airlied@gmail.com> 于2022年10月27日周四 08:01写道: >>>> On Fri, 7 Oct 2022 at 11:38, Zheng Wang <zyytlz.wz@163.com> wrote: >>>>> If intel_gvt_dma_map_guest_page failed, it will call >>>>> ppgtt_invalidate_spt, which will finally free the spt. >>>>> But the caller does not notice that, it will free spt again in error path. >>>>> >>>>> Fix this by spliting invalidate and free in ppgtt_invalidate_spt. >>>>> Only free spt when in good case. >>>>> >>>>> Reported-by: Zheng Wang <hackerzheng666@gmail.com> >>>>> Signed-off-by: Zheng Wang <zyytlz.wz@163.com> >>>> Has this landed in a tree yet, since it's a possible CVE, might be >>>> good to merge it somewhere. >>>> >>>> Dave. >>>> >>> Hi Dave, >>> >>> This patched hasn't been merged yet. Could you please help with this? >> I'll add some more people who can probably look at it. >> >> Dave. ^ permalink raw reply [flat|nested] 50+ messages in thread
* Re: [PATCH v3] drm/i915/gvt: fix double free bug in split_2MB_gtt_entry 2022-12-15 11:33 ` Wang, Zhi A @ 2022-12-15 13:26 ` Zheng Hacker 2022-12-19 7:57 ` [Intel-gfx] " Zheng Wang 1 sibling, 0 replies; 50+ messages in thread From: Zheng Hacker @ 2022-12-15 13:26 UTC (permalink / raw) To: Wang, Zhi A Cc: Tvrtko Ursulin, security, intel-gvt-dev, alex000young, airlied, gregkh, intel-gfx, linux-kernel, 1002992920, dri-devel, Zheng Wang Hi Zhi, Thanks for your reply and suggestion about fix. I am a little bit busy now. I will review the code as soon as possible. Also thanks Joonas for the reminding. We'll try to think out the new fix. Best regards, Zheng Wang ^ permalink raw reply [flat|nested] 50+ messages in thread
* Re: [Intel-gfx] [PATCH v3] drm/i915/gvt: fix double free bug in split_2MB_gtt_entry 2022-12-15 11:33 ` Wang, Zhi A 2022-12-15 13:26 ` Zheng Hacker @ 2022-12-19 7:57 ` Zheng Wang 2022-12-19 8:22 ` Wang, Zhi A 1 sibling, 1 reply; 50+ messages in thread From: Zheng Wang @ 2022-12-19 7:57 UTC (permalink / raw) To: zhi.a.wang Cc: alex000young, security, intel-gvt-dev, tvrtko.ursulin, airlied, gregkh, intel-gfx, hackerzheng666, dri-devel, linux-kernel, 1002992920, zyytlz.wz Hi Zhi, Thanks again for your reply and clear explaination about the function. I still have some doubt about the fix. Here is a invoke chain : ppgtt_populate_spt ->ppgtt_populate_shadow_entry ->split_2MB_gtt_entry As far as I'm concerned, when something error happens in DMA mapping, which will make intel_gvt_dma_map_guest_page return none-zero code, It will invoke ppgtt_invalidate_spt and call ppgtt_free_spt,which will finally free spt by kfree. But the caller doesn't notice that and frees spt by calling ppgtt_free_spt again. This is a typical UAF/Double Free vulnerability. So I think the key point is about how to handle spt properly. The handle newly allocated spt (aka sub_spt) is not the root cause of this issue. Could you please give me more advice about how to fix this security bug? Besides, I'm not sure if there are more similar problems in othe location. Best regards, Zheng Wang -- 2.25.1 ^ permalink raw reply [flat|nested] 50+ messages in thread
* Re: [Intel-gfx] [PATCH v3] drm/i915/gvt: fix double free bug in split_2MB_gtt_entry 2022-12-19 7:57 ` [Intel-gfx] " Zheng Wang @ 2022-12-19 8:22 ` Wang, Zhi A 2022-12-19 9:21 ` Zheng Wang ` (4 more replies) 0 siblings, 5 replies; 50+ messages in thread From: Wang, Zhi A @ 2022-12-19 8:22 UTC (permalink / raw) To: Zheng Wang Cc: alex000young, security, intel-gvt-dev, tvrtko.ursulin, airlied, gregkh, intel-gfx, hackerzheng666, dri-devel, linux-kernel, 1002992920 On 12/19/2022 9:57 AM, Zheng Wang wrote: > Hi Zhi, > > Thanks again for your reply and clear explaination about the function. > I still have some doubt about the fix. Here is a invoke chain : > ppgtt_populate_spt > ->ppgtt_populate_shadow_entry > ->split_2MB_gtt_entry > As far as I'm concerned, when something error happens in DMA mapping, > which will make intel_gvt_dma_map_guest_page return none-zero code, > It will invoke ppgtt_invalidate_spt and call ppgtt_free_spt,which will > finally free spt by kfree. But the caller doesn't notice that and frees > spt by calling ppgtt_free_spt again. This is a typical UAF/Double Free > vulnerability. So I think the key point is about how to handle spt properly. > The handle newly allocated spt (aka sub_spt) is not the root cause of this > issue. Could you please give me more advice about how to fix this security > bug? Besides, I'm not sure if there are more similar problems in othe location. > > Best regards, > Zheng Wang > I think it is a case-by-case thing. For example: The current scenario in this function looks like below: caller pass spt a function alloc spt b something error free spt a return error The problem is: the function wrongly frees the spt a instead free what it allocates. A proper fix should be: caller pass spt a function alloc spt b something error *free spt b* return error Thanks, Zhi. ^ permalink raw reply [flat|nested] 50+ messages in thread
* Re: [Intel-gfx] [PATCH v3] drm/i915/gvt: fix double free bug in split_2MB_gtt_entry 2022-12-19 8:22 ` Wang, Zhi A @ 2022-12-19 9:21 ` Zheng Wang 2022-12-19 12:46 ` [PATCH v4] [PATCH v4] " Zheng Wang ` (3 subsequent siblings) 4 siblings, 0 replies; 50+ messages in thread From: Zheng Wang @ 2022-12-19 9:21 UTC (permalink / raw) To: zhi.a.wang Cc: alex000young, security, intel-gvt-dev, tvrtko.ursulin, airlied, gregkh, intel-gfx, hackerzheng666, dri-devel, linux-kernel, 1002992920, zyytlz.wz Wang, Zhi A <zhi.a.wang@intel.com> 于2022年12月19日周一 16:22写道: > > I think it is a case-by-case thing. For example: > > The current scenario in this function looks like below: > > caller pass spt a > function > alloc spt b > something error > free spt a > return error > > The problem is: the function wrongly frees the spt a instead free what > it allocates. Thanks for your clear explaination. It’s really helpfult to me. I think I might know how to fix now. > A proper fix should be: > > caller pass spt a > function > alloc spt b > something error > *free spt b* > return error > As it's a case-by-case thing, I'll extract the un-done-mapping-dma part from ppgtt_invalidate_spt and put it in error path. Then I'll add the code of freeing new allocated spt. If I misunderstand your meaning, feel free to let me know. Working on a new fix now. Best regards, Zheng Wang ^ permalink raw reply [flat|nested] 50+ messages in thread
* [PATCH v4] [PATCH v4] drm/i915/gvt: fix double free bug in split_2MB_gtt_entry 2022-12-19 8:22 ` Wang, Zhi A 2022-12-19 9:21 ` Zheng Wang @ 2022-12-19 12:46 ` Zheng Wang 2022-12-19 12:52 ` [RESEND PATCH " Zheng Wang ` (2 subsequent siblings) 4 siblings, 0 replies; 50+ messages in thread From: Zheng Wang @ 2022-12-19 12:46 UTC (permalink / raw) To: zhi.a.wang Cc: alex000young, security, intel-gvt-dev, tvrtko.ursulin, airlied, gregkh, intel-gfx, hackerzheng666, dri-devel, linux-kernel, 1002992920, zyytlz.wz If intel_gvt_dma_map_guest_page failed, it will call ppgtt_invalidate_spt, which will finally free the spt. But the caller does not notice that, it will free spt again in error path. Fix this by undoing the mapping of DMA address and freeing sub_spt. Fixes: b901b252b6cf ("drm/i915/gvt: Add 2M huge gtt support") Signed-off-by: Zheng Wang <zyytlz.wz@163.com> --- v4: - fix by undo the mapping of DMA address and free sub_spt suggested by Zhi v3: - correct spelling mistake and remove unused variable suggested by Greg v2: https://lore.kernel.org/all/20221006165845.1735393-1-zyytlz.wz@163.com/ v1: https://lore.kernel.org/all/20220928033340.1063949-1-zyytlz.wz@163.com/ --- drivers/gpu/drm/i915/gvt/gtt.c | 58 +++++++++++++++++----------------- 1 file changed, 29 insertions(+), 29 deletions(-) diff --git a/drivers/gpu/drm/i915/gvt/gtt.c b/drivers/gpu/drm/i915/gvt/gtt.c index 45271acc5038..b472e021e5a4 100644 --- a/drivers/gpu/drm/i915/gvt/gtt.c +++ b/drivers/gpu/drm/i915/gvt/gtt.c @@ -1209,7 +1209,7 @@ static int split_2MB_gtt_entry(struct intel_vgpu *vgpu, for_each_shadow_entry(sub_spt, &sub_se, sub_index) { ret = intel_gvt_dma_map_guest_page(vgpu, start_gfn + sub_index, PAGE_SIZE, &dma_addr); - if (ret) + if (ret) goto err; sub_se.val64 = se->val64; @@ -1233,34 +1233,34 @@ static int split_2MB_gtt_entry(struct intel_vgpu *vgpu, /* Undone the existing mappings of DMA addr. */ for_each_present_shadow_entry(spt, &e, parent_index) { switch (e.type) { - case GTT_TYPE_PPGTT_PTE_4K_ENTRY: - gvt_vdbg_mm("invalidate 4K entry\n"); - ppgtt_invalidate_pte(spt, &e); - break; - case GTT_TYPE_PPGTT_PTE_64K_ENTRY: - /* We don't setup 64K shadow entry so far. */ - WARN(1, "suspicious 64K gtt entry\n"); - continue; - case GTT_TYPE_PPGTT_PTE_2M_ENTRY: - gvt_vdbg_mm("invalidate 2M entry\n"); - continue; - case GTT_TYPE_PPGTT_PTE_1G_ENTRY: - WARN(1, "GVT doesn't support 1GB page\n"); - continue; - case GTT_TYPE_PPGTT_PML4_ENTRY: - case GTT_TYPE_PPGTT_PDP_ENTRY: - case GTT_TYPE_PPGTT_PDE_ENTRY: - gvt_vdbg_mm("invalidate PMUL4/PDP/PDE entry\n"); - ret1 = ppgtt_invalidate_spt_by_shadow_entry( - spt->vgpu, &e); - if (ret1) { - gvt_vgpu_err("fail: shadow page %p shadow entry 0x%llx type %d\n", - spt, e.val64, e.type); - goto free_spt; - } - break; - default: - GEM_BUG_ON(1); + case GTT_TYPE_PPGTT_PTE_4K_ENTRY: + gvt_vdbg_mm("invalidate 4K entry\n"); + ppgtt_invalidate_pte(spt, &e); + break; + case GTT_TYPE_PPGTT_PTE_64K_ENTRY: + /* We don't setup 64K shadow entry so far. */ + WARN(1, "suspicious 64K gtt entry\n"); + continue; + case GTT_TYPE_PPGTT_PTE_2M_ENTRY: + gvt_vdbg_mm("invalidate 2M entry\n"); + continue; + case GTT_TYPE_PPGTT_PTE_1G_ENTRY: + WARN(1, "GVT doesn't support 1GB page\n"); + continue; + case GTT_TYPE_PPGTT_PML4_ENTRY: + case GTT_TYPE_PPGTT_PDP_ENTRY: + case GTT_TYPE_PPGTT_PDE_ENTRY: + gvt_vdbg_mm("invalidate PMUL4/PDP/PDE entry\n"); + ret1 = ppgtt_invalidate_spt_by_shadow_entry( + spt->vgpu, &e); + if (ret1) { + gvt_vgpu_err("fail: shadow page %p shadow entry 0x%llx type %d\n", + spt, e.val64, e.type); + goto free_spt; + } + break; + default: + GEM_BUG_ON(1); } } /* Release the new alloced apt. */ -- 2.25.1 ^ permalink raw reply related [flat|nested] 50+ messages in thread
* [RESEND PATCH v4] drm/i915/gvt: fix double free bug in split_2MB_gtt_entry 2022-12-19 8:22 ` Wang, Zhi A 2022-12-19 9:21 ` Zheng Wang 2022-12-19 12:46 ` [PATCH v4] [PATCH v4] " Zheng Wang @ 2022-12-19 12:52 ` Zheng Wang 2022-12-20 8:22 ` Zhenyu Wang 2022-12-20 9:40 ` [PATCH v5] " Zheng Wang 2022-12-29 16:56 ` [PATCH v6] " Zheng Wang 4 siblings, 1 reply; 50+ messages in thread From: Zheng Wang @ 2022-12-19 12:52 UTC (permalink / raw) To: zhi.a.wang Cc: alex000young, security, intel-gvt-dev, tvrtko.ursulin, airlied, gregkh, intel-gfx, hackerzheng666, dri-devel, linux-kernel, 1002992920, zyytlz.wz If intel_gvt_dma_map_guest_page failed, it will call ppgtt_invalidate_spt, which will finally free the spt. But the caller does not notice that, it will free spt again in error path. Fix this by undoing the mapping of DMA address and freeing sub_spt. Fixes: b901b252b6cf ("drm/i915/gvt: Add 2M huge gtt support") Signed-off-by: Zheng Wang <zyytlz.wz@163.com> --- v4: - fix by undo the mapping of DMA address and free sub_spt suggested by Zhi v3: - correct spelling mistake and remove unused variable suggested by Greg v2: https://lore.kernel.org/all/20221006165845.1735393-1-zyytlz.wz@163.com/ v1: https://lore.kernel.org/all/20220928033340.1063949-1-zyytlz.wz@163.com/ --- drivers/gpu/drm/i915/gvt/gtt.c | 53 +++++++++++++++++++++++++++++----- 1 file changed, 46 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/i915/gvt/gtt.c b/drivers/gpu/drm/i915/gvt/gtt.c index 51e5e8fb505b..b472e021e5a4 100644 --- a/drivers/gpu/drm/i915/gvt/gtt.c +++ b/drivers/gpu/drm/i915/gvt/gtt.c @@ -1192,11 +1192,11 @@ static int split_2MB_gtt_entry(struct intel_vgpu *vgpu, { const struct intel_gvt_gtt_pte_ops *ops = vgpu->gvt->gtt.pte_ops; struct intel_vgpu_ppgtt_spt *sub_spt; - struct intel_gvt_gtt_entry sub_se; + struct intel_gvt_gtt_entry sub_se, e; unsigned long start_gfn; dma_addr_t dma_addr; - unsigned long sub_index; - int ret; + unsigned long sub_index, parent_index; + int ret, ret1; gvt_dbg_mm("Split 2M gtt entry, index %lu\n", index); @@ -1209,10 +1209,8 @@ static int split_2MB_gtt_entry(struct intel_vgpu *vgpu, for_each_shadow_entry(sub_spt, &sub_se, sub_index) { ret = intel_gvt_dma_map_guest_page(vgpu, start_gfn + sub_index, PAGE_SIZE, &dma_addr); - if (ret) { - ppgtt_invalidate_spt(spt); - return ret; - } + if (ret) + goto err; sub_se.val64 = se->val64; /* Copy the PAT field from PDE. */ @@ -1231,6 +1229,47 @@ static int split_2MB_gtt_entry(struct intel_vgpu *vgpu, ops->set_pfn(se, sub_spt->shadow_page.mfn); ppgtt_set_shadow_entry(spt, se, index); return 0; +err: + /* Undone the existing mappings of DMA addr. */ + for_each_present_shadow_entry(spt, &e, parent_index) { + switch (e.type) { + case GTT_TYPE_PPGTT_PTE_4K_ENTRY: + gvt_vdbg_mm("invalidate 4K entry\n"); + ppgtt_invalidate_pte(spt, &e); + break; + case GTT_TYPE_PPGTT_PTE_64K_ENTRY: + /* We don't setup 64K shadow entry so far. */ + WARN(1, "suspicious 64K gtt entry\n"); + continue; + case GTT_TYPE_PPGTT_PTE_2M_ENTRY: + gvt_vdbg_mm("invalidate 2M entry\n"); + continue; + case GTT_TYPE_PPGTT_PTE_1G_ENTRY: + WARN(1, "GVT doesn't support 1GB page\n"); + continue; + case GTT_TYPE_PPGTT_PML4_ENTRY: + case GTT_TYPE_PPGTT_PDP_ENTRY: + case GTT_TYPE_PPGTT_PDE_ENTRY: + gvt_vdbg_mm("invalidate PMUL4/PDP/PDE entry\n"); + ret1 = ppgtt_invalidate_spt_by_shadow_entry( + spt->vgpu, &e); + if (ret1) { + gvt_vgpu_err("fail: shadow page %p shadow entry 0x%llx type %d\n", + spt, e.val64, e.type); + goto free_spt; + } + break; + default: + GEM_BUG_ON(1); + } + } + /* Release the new alloced apt. */ +free_spt: + trace_spt_change(sub_spt->vgpu->id, "release", sub_spt, + sub_spt->guest_page.gfn, sub_spt->shadow_page.type); + ppgtt_free_spt(sub_spt); + sub_spt = NULL; + return ret; } static int split_64KB_gtt_entry(struct intel_vgpu *vgpu, -- 2.25.1 ^ permalink raw reply related [flat|nested] 50+ messages in thread
* Re: [RESEND PATCH v4] drm/i915/gvt: fix double free bug in split_2MB_gtt_entry 2022-12-19 12:52 ` [RESEND PATCH " Zheng Wang @ 2022-12-20 8:22 ` Zhenyu Wang 2022-12-20 9:03 ` Zheng Hacker 0 siblings, 1 reply; 50+ messages in thread From: Zhenyu Wang @ 2022-12-20 8:22 UTC (permalink / raw) To: Zheng Wang Cc: alex000young, security, tvrtko.ursulin, airlied, gregkh, intel-gfx, hackerzheng666, dri-devel, linux-kernel, 1002992920, intel-gvt-dev, zhi.a.wang [-- Attachment #1: Type: text/plain, Size: 4376 bytes --] On 2022.12.19 20:52:04 +0800, Zheng Wang wrote: > If intel_gvt_dma_map_guest_page failed, it will call > ppgtt_invalidate_spt, which will finally free the spt. But the caller does > not notice that, it will free spt again in error path. > It's not clear from this description which caller is actually wrong, better to clarify the problem in ppgtt_populate_spt_by_guest_entry() function. > Fix this by undoing the mapping of DMA address and freeing sub_spt. > > Fixes: b901b252b6cf ("drm/i915/gvt: Add 2M huge gtt support") > Signed-off-by: Zheng Wang <zyytlz.wz@163.com> > --- > v4: > - fix by undo the mapping of DMA address and free sub_spt suggested by Zhi > > v3: > - correct spelling mistake and remove unused variable suggested by Greg > > v2: https://lore.kernel.org/all/20221006165845.1735393-1-zyytlz.wz@163.com/ > > v1: https://lore.kernel.org/all/20220928033340.1063949-1-zyytlz.wz@163.com/ > --- > drivers/gpu/drm/i915/gvt/gtt.c | 53 +++++++++++++++++++++++++++++----- > 1 file changed, 46 insertions(+), 7 deletions(-) > > diff --git a/drivers/gpu/drm/i915/gvt/gtt.c b/drivers/gpu/drm/i915/gvt/gtt.c > index 51e5e8fb505b..b472e021e5a4 100644 > --- a/drivers/gpu/drm/i915/gvt/gtt.c > +++ b/drivers/gpu/drm/i915/gvt/gtt.c > @@ -1192,11 +1192,11 @@ static int split_2MB_gtt_entry(struct intel_vgpu *vgpu, > { > const struct intel_gvt_gtt_pte_ops *ops = vgpu->gvt->gtt.pte_ops; > struct intel_vgpu_ppgtt_spt *sub_spt; > - struct intel_gvt_gtt_entry sub_se; > + struct intel_gvt_gtt_entry sub_se, e; > unsigned long start_gfn; > dma_addr_t dma_addr; > - unsigned long sub_index; > - int ret; > + unsigned long sub_index, parent_index; > + int ret, ret1; > > gvt_dbg_mm("Split 2M gtt entry, index %lu\n", index); > > @@ -1209,10 +1209,8 @@ static int split_2MB_gtt_entry(struct intel_vgpu *vgpu, > for_each_shadow_entry(sub_spt, &sub_se, sub_index) { > ret = intel_gvt_dma_map_guest_page(vgpu, start_gfn + sub_index, > PAGE_SIZE, &dma_addr); > - if (ret) { > - ppgtt_invalidate_spt(spt); > - return ret; > - } > + if (ret) > + goto err; I think it's fine to remove this and leave to upper caller, but again please describe the behavior change in commit message as well, e.g to fix the sanity of spt destroy that leaving previous invalidate and free of spt to caller function instead of within callee function. > sub_se.val64 = se->val64; > > /* Copy the PAT field from PDE. */ > @@ -1231,6 +1229,47 @@ static int split_2MB_gtt_entry(struct intel_vgpu *vgpu, > ops->set_pfn(se, sub_spt->shadow_page.mfn); > ppgtt_set_shadow_entry(spt, se, index); > return 0; > +err: > + /* Undone the existing mappings of DMA addr. */ > + for_each_present_shadow_entry(spt, &e, parent_index) { sub_spt? We're undoing what's mapped for sub_spt right? > + switch (e.type) { > + case GTT_TYPE_PPGTT_PTE_4K_ENTRY: > + gvt_vdbg_mm("invalidate 4K entry\n"); > + ppgtt_invalidate_pte(spt, &e); > + break; > + case GTT_TYPE_PPGTT_PTE_64K_ENTRY: > + /* We don't setup 64K shadow entry so far. */ > + WARN(1, "suspicious 64K gtt entry\n"); > + continue; > + case GTT_TYPE_PPGTT_PTE_2M_ENTRY: > + gvt_vdbg_mm("invalidate 2M entry\n"); > + continue; > + case GTT_TYPE_PPGTT_PTE_1G_ENTRY: > + WARN(1, "GVT doesn't support 1GB page\n"); > + continue; > + case GTT_TYPE_PPGTT_PML4_ENTRY: > + case GTT_TYPE_PPGTT_PDP_ENTRY: > + case GTT_TYPE_PPGTT_PDE_ENTRY: I don't think this all entry type makes sense, as here we just split 2M entry for multiple 4K PTE entry. > + gvt_vdbg_mm("invalidate PMUL4/PDP/PDE entry\n"); > + ret1 = ppgtt_invalidate_spt_by_shadow_entry( > + spt->vgpu, &e); > + if (ret1) { > + gvt_vgpu_err("fail: shadow page %p shadow entry 0x%llx type %d\n", > + spt, e.val64, e.type); > + goto free_spt; > + } for above reason, I don't think this is valid. > + break; > + default: > + GEM_BUG_ON(1); > + } > + } > + /* Release the new alloced apt. */ > +free_spt: > + trace_spt_change(sub_spt->vgpu->id, "release", sub_spt, > + sub_spt->guest_page.gfn, sub_spt->shadow_page.type); > + ppgtt_free_spt(sub_spt); > + sub_spt = NULL; > + return ret; > } > > static int split_64KB_gtt_entry(struct intel_vgpu *vgpu, > -- > 2.25.1 > [-- Attachment #2: signature.asc --] [-- Type: application/pgp-signature, Size: 195 bytes --] ^ permalink raw reply [flat|nested] 50+ messages in thread
* Re: [RESEND PATCH v4] drm/i915/gvt: fix double free bug in split_2MB_gtt_entry 2022-12-20 8:22 ` Zhenyu Wang @ 2022-12-20 9:03 ` Zheng Hacker 0 siblings, 0 replies; 50+ messages in thread From: Zheng Hacker @ 2022-12-20 9:03 UTC (permalink / raw) To: Zhenyu Wang Cc: alex000young, security, tvrtko.ursulin, airlied, gregkh, intel-gfx, linux-kernel, dri-devel, 1002992920, Zheng Wang, intel-gvt-dev, zhi.a.wang Zhenyu Wang <zhenyuw@linux.intel.com> 于2022年12月20日周二 16:25写道: > > On 2022.12.19 20:52:04 +0800, Zheng Wang wrote: > > If intel_gvt_dma_map_guest_page failed, it will call > > ppgtt_invalidate_spt, which will finally free the spt. But the caller does > > not notice that, it will free spt again in error path. > > > > It's not clear from this description which caller is actually wrong, > better to clarify the problem in ppgtt_populate_spt_by_guest_entry() function. > Get it, will do in the next fix. > > PAGE_SIZE, &dma_addr); > > - if (ret) { > > - ppgtt_invalidate_spt(spt); > > - return ret; > > - } > > + if (ret) > > + goto err; > > I think it's fine to remove this and leave to upper caller, but again please > describe the behavior change in commit message as well, e.g to fix the sanity > of spt destroy that leaving previous invalidate and free of spt to caller function > instead of within callee function. Sorry for my bad habit. Will do in the next version. > > sub_se.val64 = se->val64; > > > > /* Copy the PAT field from PDE. */ > > @@ -1231,6 +1229,47 @@ static int split_2MB_gtt_entry(struct intel_vgpu *vgpu, > > ops->set_pfn(se, sub_spt->shadow_page.mfn); > > ppgtt_set_shadow_entry(spt, se, index); > > return 0; > > +err: > > + /* Undone the existing mappings of DMA addr. */ > > + for_each_present_shadow_entry(spt, &e, parent_index) { > > sub_spt? We're undoing what's mapped for sub_spt right? Yes, will change it to sub_spt in the next version. > > > + switch (e.type) { > > + case GTT_TYPE_PPGTT_PTE_4K_ENTRY: > > + gvt_vdbg_mm("invalidate 4K entry\n"); > > + ppgtt_invalidate_pte(spt, &e); > > + break; > > + case GTT_TYPE_PPGTT_PTE_64K_ENTRY: > > + /* We don't setup 64K shadow entry so far. */ > > + WARN(1, "suspicious 64K gtt entry\n"); > > + continue; > > + case GTT_TYPE_PPGTT_PTE_2M_ENTRY: > > + gvt_vdbg_mm("invalidate 2M entry\n"); > > + continue; > > + case GTT_TYPE_PPGTT_PTE_1G_ENTRY: > > + WARN(1, "GVT doesn't support 1GB page\n"); > > + continue; > > + case GTT_TYPE_PPGTT_PML4_ENTRY: > > + case GTT_TYPE_PPGTT_PDP_ENTRY: > > + case GTT_TYPE_PPGTT_PDE_ENTRY: > > I don't think this all entry type makes sense, as here we just split > 2M entry for multiple 4K PTE entry. I got it. I will leave the code for handling 4K PTE entry only. > > > + gvt_vdbg_mm("invalidate PMUL4/PDP/PDE entry\n"); > > + ret1 = ppgtt_invalidate_spt_by_shadow_entry( > > + spt->vgpu, &e); > > + if (ret1) { > > + gvt_vgpu_err("fail: shadow page %p shadow entry 0x%llx type %d\n", > > + spt, e.val64, e.type); > > + goto free_spt; > > + } > > for above reason, I don't think this is valid. Got it. Thanks for your carefully reviewing. I'll try to fix that in the coming patch. Best regards, Zheng Wang ^ permalink raw reply [flat|nested] 50+ messages in thread
* [PATCH v5] drm/i915/gvt: fix double free bug in split_2MB_gtt_entry 2022-12-19 8:22 ` Wang, Zhi A ` (2 preceding siblings ...) 2022-12-19 12:52 ` [RESEND PATCH " Zheng Wang @ 2022-12-20 9:40 ` Zheng Wang 2022-12-21 2:58 ` Zhenyu Wang 2022-12-29 16:56 ` [PATCH v6] " Zheng Wang 4 siblings, 1 reply; 50+ messages in thread From: Zheng Wang @ 2022-12-20 9:40 UTC (permalink / raw) To: zhi.a.wang Cc: alex000young, security, intel-gvt-dev, tvrtko.ursulin, airlied, gregkh, intel-gfx, hackerzheng666, dri-devel, linux-kernel, 1002992920, zyytlz.wz If intel_gvt_dma_map_guest_page failed, it will call ppgtt_invalidate_spt, which will finally free the spt. But the caller function ppgtt_populate_spt_by_guest_entry does not notice that, it will free spt again in its error path. Fix this by undoing the mapping of DMA address and freeing sub_spt. Besides, leave the handle of spt destroy to caller function instead of callee function when error occurs. Fixes: b901b252b6cf ("drm/i915/gvt: Add 2M huge gtt support") Signed-off-by: Zheng Wang <zyytlz.wz@163.com> --- v5: - remove unnecessary switch-case code for there is only one particular case, correct the unmap target from parent_spt to sub_spt.add more details in commit message. All suggested by Zhenyu v4: - fix by undo the mapping of DMA address and free sub_spt suggested by Zhi v3: - correct spelling mistake and remove unused variable suggested by Greg v2: https://lore.kernel.org/all/20221006165845.1735393-1-zyytlz.wz@163.com/ v1: https://lore.kernel.org/all/20220928033340.1063949-1-zyytlz.wz@163.com/ --- drivers/gpu/drm/i915/gvt/gtt.c | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/i915/gvt/gtt.c b/drivers/gpu/drm/i915/gvt/gtt.c index 51e5e8fb505b..4d478a59eb7d 100644 --- a/drivers/gpu/drm/i915/gvt/gtt.c +++ b/drivers/gpu/drm/i915/gvt/gtt.c @@ -1209,10 +1209,8 @@ static int split_2MB_gtt_entry(struct intel_vgpu *vgpu, for_each_shadow_entry(sub_spt, &sub_se, sub_index) { ret = intel_gvt_dma_map_guest_page(vgpu, start_gfn + sub_index, PAGE_SIZE, &dma_addr); - if (ret) { - ppgtt_invalidate_spt(spt); - return ret; - } + if (ret) + goto err; sub_se.val64 = se->val64; /* Copy the PAT field from PDE. */ @@ -1231,6 +1229,18 @@ static int split_2MB_gtt_entry(struct intel_vgpu *vgpu, ops->set_pfn(se, sub_spt->shadow_page.mfn); ppgtt_set_shadow_entry(spt, se, index); return 0; +err: + /* Undone the existing mappings of DMA addr. */ + for_each_present_shadow_entry(sub_spt, &sub_se, sub_index) { + gvt_vdbg_mm("invalidate 4K entry\n"); + ppgtt_invalidate_pte(sub_spt, &sub_se); + } + /* Release the new allocated spt. */ + trace_spt_change(sub_spt->vgpu->id, "release", sub_spt, + sub_spt->guest_page.gfn, sub_spt->shadow_page.type); + ppgtt_free_spt(sub_spt); + sub_spt = NULL; + return ret; } static int split_64KB_gtt_entry(struct intel_vgpu *vgpu, -- 2.25.1 ^ permalink raw reply related [flat|nested] 50+ messages in thread
* Re: [PATCH v5] drm/i915/gvt: fix double free bug in split_2MB_gtt_entry 2022-12-20 9:40 ` [PATCH v5] " Zheng Wang @ 2022-12-21 2:58 ` Zhenyu Wang 2022-12-21 5:01 ` Zheng Hacker 0 siblings, 1 reply; 50+ messages in thread From: Zhenyu Wang @ 2022-12-21 2:58 UTC (permalink / raw) To: Zheng Wang Cc: alex000young, security, tvrtko.ursulin, airlied, gregkh, intel-gfx, hackerzheng666, dri-devel, linux-kernel, 1002992920, intel-gvt-dev, zhi.a.wang [-- Attachment #1: Type: text/plain, Size: 2875 bytes --] On 2022.12.20 17:40:14 +0800, Zheng Wang wrote: > If intel_gvt_dma_map_guest_page failed, it will call > ppgtt_invalidate_spt, which will finally free the spt. But the > caller function ppgtt_populate_spt_by_guest_entry does not notice > that, it will free spt again in its error path. indent > > Fix this by undoing the mapping of DMA address and freeing sub_spt. > Besides, leave the handle of spt destroy to caller function instead of > callee function when error occurs. > > Fixes: b901b252b6cf ("drm/i915/gvt: Add 2M huge gtt support") > Signed-off-by: Zheng Wang <zyytlz.wz@163.com> > --- > v5: > - remove unnecessary switch-case code for there is only one particular case, > correct the unmap target from parent_spt to sub_spt.add more details in > commit message. All suggested by Zhenyu > > v4: > - fix by undo the mapping of DMA address and free sub_spt suggested by Zhi > > v3: > - correct spelling mistake and remove unused variable suggested by Greg > > v2: https://lore.kernel.org/all/20221006165845.1735393-1-zyytlz.wz@163.com/ > > v1: https://lore.kernel.org/all/20220928033340.1063949-1-zyytlz.wz@163.com/ > --- > drivers/gpu/drm/i915/gvt/gtt.c | 18 ++++++++++++++---- > 1 file changed, 14 insertions(+), 4 deletions(-) > > diff --git a/drivers/gpu/drm/i915/gvt/gtt.c b/drivers/gpu/drm/i915/gvt/gtt.c > index 51e5e8fb505b..4d478a59eb7d 100644 > --- a/drivers/gpu/drm/i915/gvt/gtt.c > +++ b/drivers/gpu/drm/i915/gvt/gtt.c > @@ -1209,10 +1209,8 @@ static int split_2MB_gtt_entry(struct intel_vgpu *vgpu, > for_each_shadow_entry(sub_spt, &sub_se, sub_index) { > ret = intel_gvt_dma_map_guest_page(vgpu, start_gfn + sub_index, > PAGE_SIZE, &dma_addr); > - if (ret) { > - ppgtt_invalidate_spt(spt); > - return ret; > - } > + if (ret) > + goto err; > sub_se.val64 = se->val64; > > /* Copy the PAT field from PDE. */ > @@ -1231,6 +1229,18 @@ static int split_2MB_gtt_entry(struct intel_vgpu *vgpu, > ops->set_pfn(se, sub_spt->shadow_page.mfn); > ppgtt_set_shadow_entry(spt, se, index); > return 0; > +err: > + /* Undone the existing mappings of DMA addr. */ We need a verb here for Undo. > + for_each_present_shadow_entry(sub_spt, &sub_se, sub_index) { > + gvt_vdbg_mm("invalidate 4K entry\n"); > + ppgtt_invalidate_pte(sub_spt, &sub_se); > + } > + /* Release the new allocated spt. */ > + trace_spt_change(sub_spt->vgpu->id, "release", sub_spt, > + sub_spt->guest_page.gfn, sub_spt->shadow_page.type); > + ppgtt_free_spt(sub_spt); > + sub_spt = NULL; Not need to reset local variable that has no use then. I'll handle these trivial fixes during the merge. Reviewed-by: Zhenyu Wang <zhenyuw@linux.intel.com> thanks > + return ret; > } > > static int split_64KB_gtt_entry(struct intel_vgpu *vgpu, > -- > 2.25.1 > [-- Attachment #2: signature.asc --] [-- Type: application/pgp-signature, Size: 195 bytes --] ^ permalink raw reply [flat|nested] 50+ messages in thread
* Re: [PATCH v5] drm/i915/gvt: fix double free bug in split_2MB_gtt_entry 2022-12-21 2:58 ` Zhenyu Wang @ 2022-12-21 5:01 ` Zheng Hacker 0 siblings, 0 replies; 50+ messages in thread From: Zheng Hacker @ 2022-12-21 5:01 UTC (permalink / raw) To: Zhenyu Wang Cc: alex000young, security, tvrtko.ursulin, airlied, gregkh, intel-gfx, linux-kernel, dri-devel, 1002992920, Zheng Wang, intel-gvt-dev, zhi.a.wang Zhenyu Wang <zhenyuw@linux.intel.com> 于2022年12月21日周三 11:01写道: > > On 2022.12.20 17:40:14 +0800, Zheng Wang wrote: > > If intel_gvt_dma_map_guest_page failed, it will call > > ppgtt_invalidate_spt, which will finally free the spt. But the > > caller function ppgtt_populate_spt_by_guest_entry does not notice > > that, it will free spt again in its error path. > > indent Yeap :) > > + if (ret) > > + goto err; > > sub_se.val64 = se->val64; > > > > /* Copy the PAT field from PDE. */ > > @@ -1231,6 +1229,18 @@ static int split_2MB_gtt_entry(struct intel_vgpu *vgpu, > > ops->set_pfn(se, sub_spt->shadow_page.mfn); > > ppgtt_set_shadow_entry(spt, se, index); > > return 0; > > +err: > > + /* Undone the existing mappings of DMA addr. */ > > We need a verb here for Undo. Get it. > > > + for_each_present_shadow_entry(sub_spt, &sub_se, sub_index) { > > + gvt_vdbg_mm("invalidate 4K entry\n"); > > + ppgtt_invalidate_pte(sub_spt, &sub_se); > > + } > > + /* Release the new allocated spt. */ > > + trace_spt_change(sub_spt->vgpu->id, "release", sub_spt, > > + sub_spt->guest_page.gfn, sub_spt->shadow_page.type); > > + ppgtt_free_spt(sub_spt); > > + sub_spt = NULL; > > Not need to reset local variable that has no use then. > > I'll handle these trivial fixes during the merge. > Very thanks for that. Best regards, Zheng Wang ^ permalink raw reply [flat|nested] 50+ messages in thread
* [PATCH v6] drm/i915/gvt: fix double free bug in split_2MB_gtt_entry 2022-12-19 8:22 ` Wang, Zhi A ` (3 preceding siblings ...) 2022-12-20 9:40 ` [PATCH v5] " Zheng Wang @ 2022-12-29 16:56 ` Zheng Wang 4 siblings, 0 replies; 50+ messages in thread From: Zheng Wang @ 2022-12-29 16:56 UTC (permalink / raw) To: zhi.a.wang Cc: alex000young, security, intel-gvt-dev, tvrtko.ursulin, airlied, gregkh, intel-gfx, hackerzheng666, dri-devel, linux-kernel, 1002992920, zyytlz.wz If intel_gvt_dma_map_guest_page failed, it will call ppgtt_invalidate_spt, which will finally free the spt. But the caller function ppgtt_populate_spt_by_guest_entry does not notice that, it will free spt again in its error path. Fix this by canceling the mapping of DMA address and freeing sub_spt. Besides, leave the handle of spt destroy to caller function instead of callee function when error occurs. Fixes: b901b252b6cf ("drm/i915/gvt: Add 2M huge gtt support") Signed-off-by: Zheng Wang <zyytlz.wz@163.com> Reviewed-by: Zhenyu Wang <zhenyuw@linux.intel.com> --- v6: - remove the code for setting unused variable to NULL and fix type suggested by Zhenyu v5: - remove unnecessary switch-case code for there is only one particular case, correct the unmap target from parent_spt to sub_spt.add more details in commit message. All suggested by Zhenyu v4: - fix by undo the mapping of DMA address and free sub_spt suggested by Zhi v3: - correct spelling mistake and remove unused variable suggested by Greg v2: https://lore.kernel.org/all/20221006165845.1735393-1-zyytlz.wz@163.com/ v1: https://lore.kernel.org/all/20220928033340.1063949-1-zyytlz.wz@163.com/ --- drivers/gpu/drm/i915/gvt/gtt.c | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/i915/gvt/gtt.c b/drivers/gpu/drm/i915/gvt/gtt.c index 51e5e8fb505b..7379e8d98417 100644 --- a/drivers/gpu/drm/i915/gvt/gtt.c +++ b/drivers/gpu/drm/i915/gvt/gtt.c @@ -1209,10 +1209,8 @@ static int split_2MB_gtt_entry(struct intel_vgpu *vgpu, for_each_shadow_entry(sub_spt, &sub_se, sub_index) { ret = intel_gvt_dma_map_guest_page(vgpu, start_gfn + sub_index, PAGE_SIZE, &dma_addr); - if (ret) { - ppgtt_invalidate_spt(spt); - return ret; - } + if (ret) + goto err; sub_se.val64 = se->val64; /* Copy the PAT field from PDE. */ @@ -1231,6 +1229,17 @@ static int split_2MB_gtt_entry(struct intel_vgpu *vgpu, ops->set_pfn(se, sub_spt->shadow_page.mfn); ppgtt_set_shadow_entry(spt, se, index); return 0; +err: + /* Cancel the existing addess mappings of DMA addr. */ + for_each_present_shadow_entry(sub_spt, &sub_se, sub_index) { + gvt_vdbg_mm("invalidate 4K entry\n"); + ppgtt_invalidate_pte(sub_spt, &sub_se); + } + /* Release the new allocated spt. */ + trace_spt_change(sub_spt->vgpu->id, "release", sub_spt, + sub_spt->guest_page.gfn, sub_spt->shadow_page.type); + ppgtt_free_spt(sub_spt); + return ret; } static int split_64KB_gtt_entry(struct intel_vgpu *vgpu, -- 2.25.1 ^ permalink raw reply related [flat|nested] 50+ messages in thread
[parent not found: <tencent_E1BBF05904DFB73C478DCD592740AAE0780A@qq.com>]
* Re: [PATCH] drm/i915/gvt: fix double-free bug in split_2MB_gtt_entry. [not found] <tencent_E1BBF05904DFB73C478DCD592740AAE0780A@qq.com> @ 2022-09-05 4:47 ` Zheng Hacker 2022-09-05 6:11 ` Zheng Hacker 2022-09-05 7:35 ` Zheng Hacker 0 siblings, 2 replies; 50+ messages in thread From: Zheng Hacker @ 2022-09-05 4:47 UTC (permalink / raw) To: xmzyshypnc Cc: alex000young, security, dri-devel, tvrtko.ursulin, airlied, intel-gfx, linux-kernel, rodrigo.vivi, intel-gvt-dev, zhi.a.wang [-- Attachment #1: Type: text/plain, Size: 1719 bytes --] Hello everyone, I'm Zheng Wang. I found a potential double-free bug in drivers/gpu/drm/i915/gvt/gtt.c. I haven't been replied for a long time. So I decided to send it to more relavent supporters and developers to help to solve the problem. Best regards, Zheng Wang. xmzyshypnc <1002992920@qq.com> 于2022年9月4日周日 20:32写道: > There is a double-free security bug in split_2MB_gtt_entry. > > Here is a calling chain : > ppgtt_populate_spt->ppgtt_populate_shadow_entry->split_2MB_gtt_entry. If > intel_gvt_dma_map_guest_page failed, it will call ppgtt_invalidate_spt, > which will finally call ppgtt_free_spt and kfree(spt). But the caller does > not notice that, and it will call ppgtt_free_spt again in error path. > > Fix this by returning the result of ppgtt_invalidate_spt to > split_2MB_gtt_entry. > > Signed-off-by: Zheng Wang <1002992920@qq.com> > --- > drivers/gpu/drm/i915/gvt/gtt.c | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > > diff --git a/drivers/gpu/drm/i915/gvt/gtt.c > b/drivers/gpu/drm/i915/gvt/gtt.c > index ce0eb03709c3..9f14fded8c0c 100644 > --- a/drivers/gpu/drm/i915/gvt/gtt.c > +++ b/drivers/gpu/drm/i915/gvt/gtt.c > @@ -1215,7 +1215,7 @@ static int split_2MB_gtt_entry(struct intel_vgpu > *vgpu, > ret = intel_gvt_dma_map_guest_page(vgpu, start_gfn + > sub_index, > PAGE_SIZE, &dma_addr); > if (ret) { > - ppgtt_invalidate_spt(spt); > + ret = ppgtt_invalidate_spt(spt); > return ret; > } > sub_se.val64 = se->val64; > -- > 2.25.1 > > [-- Attachment #2: Type: text/html, Size: 2277 bytes --] ^ permalink raw reply [flat|nested] 50+ messages in thread
* Re: [PATCH] drm/i915/gvt: fix double-free bug in split_2MB_gtt_entry. 2022-09-05 4:47 ` [PATCH] drm/i915/gvt: fix double-free " Zheng Hacker @ 2022-09-05 6:11 ` Zheng Hacker 2022-09-05 7:35 ` Zheng Hacker 1 sibling, 0 replies; 50+ messages in thread From: Zheng Hacker @ 2022-09-05 6:11 UTC (permalink / raw) To: xmzyshypnc Cc: alex000young, security, dri-devel, tvrtko.ursulin, airlied, intel-gfx, linux-kernel, rodrigo.vivi, intel-gvt-dev, zhi.a.wang [-- Attachment #1: Type: text/plain, Size: 1945 bytes --] Resent the mail for the former letter contains html text. Regards, Zheng Wang Zheng Hacker <hackerzheng666@gmail.com> 于2022年9月5日周一 12:47写道: > Hello everyone, > > I'm Zheng Wang. I found a potential double-free bug > in drivers/gpu/drm/i915/gvt/gtt.c. I haven't been replied for a long time. > So I decided to send it to more relavent supporters and developers to help > to solve the problem. > > Best regards, > Zheng Wang. > > xmzyshypnc <1002992920@qq.com> 于2022年9月4日周日 20:32写道: > >> There is a double-free security bug in split_2MB_gtt_entry. >> >> Here is a calling chain : >> ppgtt_populate_spt->ppgtt_populate_shadow_entry->split_2MB_gtt_entry. If >> intel_gvt_dma_map_guest_page failed, it will call ppgtt_invalidate_spt, >> which will finally call ppgtt_free_spt and kfree(spt). But the caller does >> not notice that, and it will call ppgtt_free_spt again in error path. >> >> Fix this by returning the result of ppgtt_invalidate_spt to >> split_2MB_gtt_entry. >> >> Signed-off-by: Zheng Wang <1002992920@qq.com> >> --- >> drivers/gpu/drm/i915/gvt/gtt.c | 2 +- >> 1 file changed, 1 insertion(+), 1 deletion(-) >> >> diff --git a/drivers/gpu/drm/i915/gvt/gtt.c >> b/drivers/gpu/drm/i915/gvt/gtt.c >> index ce0eb03709c3..9f14fded8c0c 100644 >> --- a/drivers/gpu/drm/i915/gvt/gtt.c >> +++ b/drivers/gpu/drm/i915/gvt/gtt.c >> @@ -1215,7 +1215,7 @@ static int split_2MB_gtt_entry(struct intel_vgpu >> *vgpu, >> ret = intel_gvt_dma_map_guest_page(vgpu, start_gfn + >> sub_index, >> PAGE_SIZE, &dma_addr); >> if (ret) { >> - ppgtt_invalidate_spt(spt); >> + ret = ppgtt_invalidate_spt(spt); >> return ret; >> } >> sub_se.val64 = se->val64; >> -- >> 2.25.1 >> >> [-- Attachment #2: Type: text/html, Size: 2770 bytes --] ^ permalink raw reply [flat|nested] 50+ messages in thread
* Re: [PATCH] drm/i915/gvt: fix double-free bug in split_2MB_gtt_entry. 2022-09-05 4:47 ` [PATCH] drm/i915/gvt: fix double-free " Zheng Hacker 2022-09-05 6:11 ` Zheng Hacker @ 2022-09-05 7:35 ` Zheng Hacker 2022-09-05 7:46 ` Zheng Hacker 1 sibling, 1 reply; 50+ messages in thread From: Zheng Hacker @ 2022-09-05 7:35 UTC (permalink / raw) To: xmzyshypnc Cc: alex000young, security, dri-devel, tvrtko.ursulin, airlied, Greg KH, intel-gfx, linux-kernel, rodrigo.vivi, intel-gvt-dev, zhi.a.wang Hi everyone, Now the letter is really plain-text now :) Thanks Greg Regards, Zheng Wang Zheng Hacker <hackerzheng666@gmail.com> 于2022年9月5日周一 12:47写道: > > Hello everyone, > > I'm Zheng Wang. I found a potential double-free bug in drivers/gpu/drm/i915/gvt/gtt.c. I haven't been replied for a long time. So I decided to send it to more relavent supporters and developers to help to solve the problem. > > Best regards, > Zheng Wang. > > xmzyshypnc <1002992920@qq.com> 于2022年9月4日周日 20:32写道: >> >> There is a double-free security bug in split_2MB_gtt_entry. >> >> Here is a calling chain : ppgtt_populate_spt->ppgtt_populate_shadow_entry->split_2MB_gtt_entry. If intel_gvt_dma_map_guest_page failed, it will call ppgtt_invalidate_spt, which will finally call ppgtt_free_spt and kfree(spt). But the caller does not notice that, and it will call ppgtt_free_spt again in error path. >> >> Fix this by returning the result of ppgtt_invalidate_spt to split_2MB_gtt_entry. >> >> Signed-off-by: Zheng Wang <1002992920@qq.com> >> --- >> drivers/gpu/drm/i915/gvt/gtt.c | 2 +- >> 1 file changed, 1 insertion(+), 1 deletion(-) >> >> diff --git a/drivers/gpu/drm/i915/gvt/gtt.c b/drivers/gpu/drm/i915/gvt/gtt.c >> index ce0eb03709c3..9f14fded8c0c 100644 >> --- a/drivers/gpu/drm/i915/gvt/gtt.c >> +++ b/drivers/gpu/drm/i915/gvt/gtt.c >> @@ -1215,7 +1215,7 @@ static int split_2MB_gtt_entry(struct intel_vgpu *vgpu, >> ret = intel_gvt_dma_map_guest_page(vgpu, start_gfn + sub_index, >> PAGE_SIZE, &dma_addr); >> if (ret) { >> - ppgtt_invalidate_spt(spt); >> + ret = ppgtt_invalidate_spt(spt); >> return ret; >> } >> sub_se.val64 = se->val64; >> -- >> 2.25.1 >> ^ permalink raw reply [flat|nested] 50+ messages in thread
* Re: [PATCH] drm/i915/gvt: fix double-free bug in split_2MB_gtt_entry. 2022-09-05 7:35 ` Zheng Hacker @ 2022-09-05 7:46 ` Zheng Hacker 2022-09-05 8:04 ` Greg KH 0 siblings, 1 reply; 50+ messages in thread From: Zheng Hacker @ 2022-09-05 7:46 UTC (permalink / raw) To: xmzyshypnc Cc: alex000young, security, dri-devel, tvrtko.ursulin, airlied, Greg KH, intel-gfx, linux-kernel, rodrigo.vivi, intel-gvt-dev, zhi.a.wang I rewrote the letter. Hope it works. There is a double-free security bug in split_2MB_gtt_entry. Here is a calling chain : ppgtt_populate_spt->ppgtt_populate_shadow_entry->split_2MB_gtt_entry. If intel_gvt_dma_map_guest_page failed, it will call ppgtt_invalidate_spt, which will finally call ppgtt_free_spt and kfree(spt). But the caller does not notice that, and it will call ppgtt_free_spt again in error path. Fix this by returning the result of ppgtt_invalidate_spt to split_2MB_gtt_entry. Signed-off-by: Zheng Wang --- drivers/gpu/drm/i915/gvt/gtt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/gvt/gtt.c b/drivers/gpu/drm/i915/gvt/gtt.c index ce0eb03709c3..9f14fded8c0c 100644 --- a/drivers/gpu/drm/i915/gvt/gtt.c +++ b/drivers/gpu/drm/i915/gvt/gtt.c @@ -1215,7 +1215,7 @@ static int split_2MB_gtt_entry(struct intel_vgpu *vgpu, ret = intel_gvt_dma_map_guest_page(vgpu, start_gfn + sub_index, PAGE_SIZE, &dma_addr); if (ret) { - ppgtt_invalidate_spt(spt); + ret = ppgtt_invalidate_spt(spt); return ret; } sub_se.val64 = se->val64; -- 2.25.1 ^ permalink raw reply related [flat|nested] 50+ messages in thread
* Re: [PATCH] drm/i915/gvt: fix double-free bug in split_2MB_gtt_entry. 2022-09-05 7:46 ` Zheng Hacker @ 2022-09-05 8:04 ` Greg KH 2022-09-05 8:53 ` Alex Young 2022-09-06 11:36 ` Zheng Hacker 0 siblings, 2 replies; 50+ messages in thread From: Greg KH @ 2022-09-05 8:04 UTC (permalink / raw) To: Zheng Hacker Cc: alex000young, security, dri-devel, tvrtko.ursulin, airlied, intel-gfx, linux-kernel, xmzyshypnc, rodrigo.vivi, intel-gvt-dev, zhi.a.wang On Mon, Sep 05, 2022 at 03:46:09PM +0800, Zheng Hacker wrote: > I rewrote the letter. Hope it works. > > There is a double-free security bug in split_2MB_gtt_entry. > > Here is a calling chain : > ppgtt_populate_spt->ppgtt_populate_shadow_entry->split_2MB_gtt_entry. > If intel_gvt_dma_map_guest_page failed, it will call > ppgtt_invalidate_spt, which will finally call ppgtt_free_spt and > kfree(spt). But the caller does not notice that, and it will call > ppgtt_free_spt again in error path. > > Fix this by returning the result of ppgtt_invalidate_spt to split_2MB_gtt_entry. > > Signed-off-by: Zheng Wang > > --- > drivers/gpu/drm/i915/gvt/gtt.c | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > > diff --git a/drivers/gpu/drm/i915/gvt/gtt.c b/drivers/gpu/drm/i915/gvt/gtt.c > index ce0eb03709c3..9f14fded8c0c 100644 > --- a/drivers/gpu/drm/i915/gvt/gtt.c > +++ b/drivers/gpu/drm/i915/gvt/gtt.c > @@ -1215,7 +1215,7 @@ static int split_2MB_gtt_entry(struct intel_vgpu *vgpu, > ret = intel_gvt_dma_map_guest_page(vgpu, start_gfn + sub_index, > PAGE_SIZE, &dma_addr); > if (ret) { > - ppgtt_invalidate_spt(spt); > + ret = ppgtt_invalidate_spt(spt); > return ret; But now you just lost the original error, shouldn't this succeed even if intel_gvt_dma_map_guest_page() failed? And how are you causing intel_gvt_dma_map_guest_page() to fail in a real system? thanks, greg k-h ^ permalink raw reply [flat|nested] 50+ messages in thread
* Re: [PATCH] drm/i915/gvt: fix double-free bug in split_2MB_gtt_entry. 2022-09-05 8:04 ` Greg KH @ 2022-09-05 8:53 ` Alex Young 2022-09-06 11:36 ` Zheng Hacker 1 sibling, 0 replies; 50+ messages in thread From: Alex Young @ 2022-09-05 8:53 UTC (permalink / raw) To: Greg KH Cc: tvrtko.ursulin, security, dri-devel, airlied, intel-gfx, Zheng Hacker, linux-kernel, xmzyshypnc, rodrigo.vivi, intel-gvt-dev, zhi.a.wang Thanks for your reply. We think that when intel_gvt_dma_map_guest_page() fails, ppgtt_invalidate_spt is called to handle this error. If the ppgtt_invalidate_spt is successful to kfree the spt object, then in the ppgtt_populate_spt function there is no need to kfree the spt again. And if the ppgtt_invalidate_spt failed, then in the ppgtt_populate_spt function there is need to kfree the spt for error handling. This is our fix, if it's not right, we are glad to discuss with you. Greg KH <gregkh@linuxfoundation.org> 于2022年9月5日周一 16:04写道: > > On Mon, Sep 05, 2022 at 03:46:09PM +0800, Zheng Hacker wrote: > > I rewrote the letter. Hope it works. > > > > There is a double-free security bug in split_2MB_gtt_entry. > > > > Here is a calling chain : > > ppgtt_populate_spt->ppgtt_populate_shadow_entry->split_2MB_gtt_entry. > > If intel_gvt_dma_map_guest_page failed, it will call > > ppgtt_invalidate_spt, which will finally call ppgtt_free_spt and > > kfree(spt). But the caller does not notice that, and it will call > > ppgtt_free_spt again in error path. > > > > Fix this by returning the result of ppgtt_invalidate_spt to split_2MB_gtt_entry. > > > > Signed-off-by: Zheng Wang > > > > --- > > drivers/gpu/drm/i915/gvt/gtt.c | 2 +- > > 1 file changed, 1 insertion(+), 1 deletion(-) > > > > diff --git a/drivers/gpu/drm/i915/gvt/gtt.c b/drivers/gpu/drm/i915/gvt/gtt.c > > index ce0eb03709c3..9f14fded8c0c 100644 > > --- a/drivers/gpu/drm/i915/gvt/gtt.c > > +++ b/drivers/gpu/drm/i915/gvt/gtt.c > > @@ -1215,7 +1215,7 @@ static int split_2MB_gtt_entry(struct intel_vgpu *vgpu, > > ret = intel_gvt_dma_map_guest_page(vgpu, start_gfn + sub_index, > > PAGE_SIZE, &dma_addr); > > if (ret) { > > - ppgtt_invalidate_spt(spt); > > + ret = ppgtt_invalidate_spt(spt); > > return ret; > > But now you just lost the original error, shouldn't this succeed even if > intel_gvt_dma_map_guest_page() failed? > > And how are you causing intel_gvt_dma_map_guest_page() to fail in a real > system? > > thanks, > > greg k-h ^ permalink raw reply [flat|nested] 50+ messages in thread
* Re: [PATCH] drm/i915/gvt: fix double-free bug in split_2MB_gtt_entry. 2022-09-05 8:04 ` Greg KH 2022-09-05 8:53 ` Alex Young @ 2022-09-06 11:36 ` Zheng Hacker 2022-09-07 3:07 ` Zhenyu Wang 1 sibling, 1 reply; 50+ messages in thread From: Zheng Hacker @ 2022-09-06 11:36 UTC (permalink / raw) To: Greg KH Cc: alex000young, security, dri-devel, tvrtko.ursulin, airlied, intel-gfx, linux-kernel, xmzyshypnc, rodrigo.vivi, intel-gvt-dev, zhi.a.wang Hi Greg, Alex has explained how we figured out the patch. We did analyze the code and found it possible to reach the vulnerability code. But we have no physical device in hand to test the driver. So we'd like to discuss with developers to see if the issue exists or not. Best regards, Zheng Wang. Greg KH <gregkh@linuxfoundation.org> 于2022年9月5日周一 16:04写道: > > On Mon, Sep 05, 2022 at 03:46:09PM +0800, Zheng Hacker wrote: > > I rewrote the letter. Hope it works. > > > > There is a double-free security bug in split_2MB_gtt_entry. > > > > Here is a calling chain : > > ppgtt_populate_spt->ppgtt_populate_shadow_entry->split_2MB_gtt_entry. > > If intel_gvt_dma_map_guest_page failed, it will call > > ppgtt_invalidate_spt, which will finally call ppgtt_free_spt and > > kfree(spt). But the caller does not notice that, and it will call > > ppgtt_free_spt again in error path. > > > > Fix this by returning the result of ppgtt_invalidate_spt to split_2MB_gtt_entry. > > > > Signed-off-by: Zheng Wang > > > > --- > > drivers/gpu/drm/i915/gvt/gtt.c | 2 +- > > 1 file changed, 1 insertion(+), 1 deletion(-) > > > > diff --git a/drivers/gpu/drm/i915/gvt/gtt.c b/drivers/gpu/drm/i915/gvt/gtt.c > > index ce0eb03709c3..9f14fded8c0c 100644 > > --- a/drivers/gpu/drm/i915/gvt/gtt.c > > +++ b/drivers/gpu/drm/i915/gvt/gtt.c > > @@ -1215,7 +1215,7 @@ static int split_2MB_gtt_entry(struct intel_vgpu *vgpu, > > ret = intel_gvt_dma_map_guest_page(vgpu, start_gfn + sub_index, > > PAGE_SIZE, &dma_addr); > > if (ret) { > > - ppgtt_invalidate_spt(spt); > > + ret = ppgtt_invalidate_spt(spt); > > return ret; > > But now you just lost the original error, shouldn't this succeed even if > intel_gvt_dma_map_guest_page() failed? > > And how are you causing intel_gvt_dma_map_guest_page() to fail in a real > system? > > thanks, > > greg k-h ^ permalink raw reply [flat|nested] 50+ messages in thread
* Re: [PATCH] drm/i915/gvt: fix double-free bug in split_2MB_gtt_entry. 2022-09-06 11:36 ` Zheng Hacker @ 2022-09-07 3:07 ` Zhenyu Wang 2022-09-07 6:47 ` Zheng Hacker 2022-09-08 9:09 ` Zheng Hacker 0 siblings, 2 replies; 50+ messages in thread From: Zhenyu Wang @ 2022-09-07 3:07 UTC (permalink / raw) To: Zheng Hacker Cc: tvrtko.ursulin, security, alex000young, airlied, Greg KH, intel-gfx, linux-kernel, dri-devel, xmzyshypnc, rodrigo.vivi, intel-gvt-dev, zhi.a.wang [-- Attachment #1: Type: text/plain, Size: 2737 bytes --] On 2022.09.06 19:36:56 +0800, Zheng Hacker wrote: > Hi Greg, > > Alex has explained how we figured out the patch. We did analyze the > code and found it possible to reach the vulnerability code. But we > have no physical device in hand to test the driver. So we'd like to > discuss with developers to see if the issue exists or not. > > Best regards, > Zheng Wang. > > Greg KH <gregkh@linuxfoundation.org> ???2022???9???5????????? 16:04????????? > > > > On Mon, Sep 05, 2022 at 03:46:09PM +0800, Zheng Hacker wrote: > > > I rewrote the letter. Hope it works. > > > > > > There is a double-free security bug in split_2MB_gtt_entry. > > > > > > Here is a calling chain : > > > ppgtt_populate_spt->ppgtt_populate_shadow_entry->split_2MB_gtt_entry. > > > If intel_gvt_dma_map_guest_page failed, it will call > > > ppgtt_invalidate_spt, which will finally call ppgtt_free_spt and > > > kfree(spt). But the caller does not notice that, and it will call > > > ppgtt_free_spt again in error path. > > > It's a little mess in code so in theory it might be possible but intel_gvt_dma_map_guest_page won't fail in practise... > > > Fix this by returning the result of ppgtt_invalidate_spt to split_2MB_gtt_entry. > > > I don't see why changing ret value can fix this issue, as it doesn't change any behavior e.g caller of ppgtt_populate_spt to handle possible different error return. As current code looks assuming that ppgtt_invalidate_spt would free spt in good case, I think the real cleanup should split that assumption and handle free in error case properly. > > > Signed-off-by: Zheng Wang This misses proper email address. thanks > > > > > > --- > > > drivers/gpu/drm/i915/gvt/gtt.c | 2 +- > > > 1 file changed, 1 insertion(+), 1 deletion(-) > > > > > > diff --git a/drivers/gpu/drm/i915/gvt/gtt.c b/drivers/gpu/drm/i915/gvt/gtt.c > > > index ce0eb03709c3..9f14fded8c0c 100644 > > > --- a/drivers/gpu/drm/i915/gvt/gtt.c > > > +++ b/drivers/gpu/drm/i915/gvt/gtt.c > > > @@ -1215,7 +1215,7 @@ static int split_2MB_gtt_entry(struct intel_vgpu *vgpu, > > > ret = intel_gvt_dma_map_guest_page(vgpu, start_gfn + sub_index, > > > PAGE_SIZE, &dma_addr); > > > if (ret) { > > > - ppgtt_invalidate_spt(spt); > > > + ret = ppgtt_invalidate_spt(spt); > > > return ret; > > > > But now you just lost the original error, shouldn't this succeed even if > > intel_gvt_dma_map_guest_page() failed? > > > > And how are you causing intel_gvt_dma_map_guest_page() to fail in a real > > system? > > > > thanks, > > > > greg k-h [-- Attachment #2: signature.asc --] [-- Type: application/pgp-signature, Size: 195 bytes --] ^ permalink raw reply [flat|nested] 50+ messages in thread
* Re: [PATCH] drm/i915/gvt: fix double-free bug in split_2MB_gtt_entry. 2022-09-07 3:07 ` Zhenyu Wang @ 2022-09-07 6:47 ` Zheng Hacker 2022-09-08 9:09 ` Zheng Hacker 1 sibling, 0 replies; 50+ messages in thread From: Zheng Hacker @ 2022-09-07 6:47 UTC (permalink / raw) To: Zhenyu Wang Cc: tvrtko.ursulin, security, alex000young, airlied, Greg KH, intel-gfx, linux-kernel, dri-devel, xmzyshypnc, rodrigo.vivi, intel-gvt-dev, zhi.a.wang Hi Zhenyu, Very glad for your reply. I agree that the bug is hard to trigger in userspace. But it is possible to happen in some specific scene. For example, if calling pfn_valid failed, the bug will be triggered. And it did happened as the [1] commit description illustrates. As for the patch, I think your plan is the best. We need to free the spt only in bad case. [1] https://github.com/torvalds/linux/commit/39b4cbadb9a95bf3f13ea102d6ec841940916ee2 Regards, Zheng Wang Zhenyu Wang <zhenyuw@linux.intel.com> 于2022年9月7日周三 11:33写道: > > On 2022.09.06 19:36:56 +0800, Zheng Hacker wrote: > > Hi Greg, > > > > Alex has explained how we figured out the patch. We did analyze the > > code and found it possible to reach the vulnerability code. But we > > have no physical device in hand to test the driver. So we'd like to > > discuss with developers to see if the issue exists or not. > > > > Best regards, > > Zheng Wang. > > > > Greg KH <gregkh@linuxfoundation.org> ???2022???9???5????????? 16:04????????? > > > > > > On Mon, Sep 05, 2022 at 03:46:09PM +0800, Zheng Hacker wrote: > > > > I rewrote the letter. Hope it works. > > > > > > > > There is a double-free security bug in split_2MB_gtt_entry. > > > > > > > > Here is a calling chain : > > > > ppgtt_populate_spt->ppgtt_populate_shadow_entry->split_2MB_gtt_entry. > > > > If intel_gvt_dma_map_guest_page failed, it will call > > > > ppgtt_invalidate_spt, which will finally call ppgtt_free_spt and > > > > kfree(spt). But the caller does not notice that, and it will call > > > > ppgtt_free_spt again in error path. > > > > > > It's a little mess in code so in theory it might be possible but > intel_gvt_dma_map_guest_page won't fail in practise... > > > > > Fix this by returning the result of ppgtt_invalidate_spt to split_2MB_gtt_entry. > > > > > > I don't see why changing ret value can fix this issue, as it doesn't change > any behavior e.g caller of ppgtt_populate_spt to handle possible different error return. > > As current code looks assuming that ppgtt_invalidate_spt would free spt in good case, > I think the real cleanup should split that assumption and handle free in error case properly. > > > > > Signed-off-by: Zheng Wang > > This misses proper email address. > > thanks > > > > > > > > > --- > > > > drivers/gpu/drm/i915/gvt/gtt.c | 2 +- > > > > 1 file changed, 1 insertion(+), 1 deletion(-) > > > > > > > > diff --git a/drivers/gpu/drm/i915/gvt/gtt.c b/drivers/gpu/drm/i915/gvt/gtt.c > > > > index ce0eb03709c3..9f14fded8c0c 100644 > > > > --- a/drivers/gpu/drm/i915/gvt/gtt.c > > > > +++ b/drivers/gpu/drm/i915/gvt/gtt.c > > > > @@ -1215,7 +1215,7 @@ static int split_2MB_gtt_entry(struct intel_vgpu *vgpu, > > > > ret = intel_gvt_dma_map_guest_page(vgpu, start_gfn + sub_index, > > > > PAGE_SIZE, &dma_addr); > > > > if (ret) { > > > > - ppgtt_invalidate_spt(spt); > > > > + ret = ppgtt_invalidate_spt(spt); > > > > return ret; > > > > > > But now you just lost the original error, shouldn't this succeed even if > > > intel_gvt_dma_map_guest_page() failed? > > > > > > And how are you causing intel_gvt_dma_map_guest_page() to fail in a real > > > system? > > > > > > thanks, > > > > > > greg k-h ^ permalink raw reply [flat|nested] 50+ messages in thread
* Re: [PATCH] drm/i915/gvt: fix double-free bug in split_2MB_gtt_entry. 2022-09-07 3:07 ` Zhenyu Wang 2022-09-07 6:47 ` Zheng Hacker @ 2022-09-08 9:09 ` Zheng Hacker 2022-09-08 9:19 ` Greg KH 1 sibling, 1 reply; 50+ messages in thread From: Zheng Hacker @ 2022-09-08 9:09 UTC (permalink / raw) To: Zhenyu Wang Cc: tvrtko.ursulin, security, alex000young, airlied, Greg KH, intel-gfx, linux-kernel, dri-devel, xmzyshypnc, rodrigo.vivi, intel-gvt-dev, zhi.a.wang Hi Zhenyu, This issue has been open for a few days. Could you plz write a patch for that :) I'm not familiar with the logical code here. Regards, Zheng Wang Zhenyu Wang <zhenyuw@linux.intel.com> 于2022年9月7日周三 11:33写道: > > On 2022.09.06 19:36:56 +0800, Zheng Hacker wrote: > > Hi Greg, > > > > Alex has explained how we figured out the patch. We did analyze the > > code and found it possible to reach the vulnerability code. But we > > have no physical device in hand to test the driver. So we'd like to > > discuss with developers to see if the issue exists or not. > > > > Best regards, > > Zheng Wang. > > > > Greg KH <gregkh@linuxfoundation.org> ???2022???9???5????????? 16:04????????? > > > > > > On Mon, Sep 05, 2022 at 03:46:09PM +0800, Zheng Hacker wrote: > > > > I rewrote the letter. Hope it works. > > > > > > > > There is a double-free security bug in split_2MB_gtt_entry. > > > > > > > > Here is a calling chain : > > > > ppgtt_populate_spt->ppgtt_populate_shadow_entry->split_2MB_gtt_entry. > > > > If intel_gvt_dma_map_guest_page failed, it will call > > > > ppgtt_invalidate_spt, which will finally call ppgtt_free_spt and > > > > kfree(spt). But the caller does not notice that, and it will call > > > > ppgtt_free_spt again in error path. > > > > > > It's a little mess in code so in theory it might be possible but > intel_gvt_dma_map_guest_page won't fail in practise... > > > > > Fix this by returning the result of ppgtt_invalidate_spt to split_2MB_gtt_entry. > > > > > > I don't see why changing ret value can fix this issue, as it doesn't change > any behavior e.g caller of ppgtt_populate_spt to handle possible different error return. > > As current code looks assuming that ppgtt_invalidate_spt would free spt in good case, > I think the real cleanup should split that assumption and handle free in error case properly. > > > > > Signed-off-by: Zheng Wang > > This misses proper email address. > > thanks > > > > > > > > > --- > > > > drivers/gpu/drm/i915/gvt/gtt.c | 2 +- > > > > 1 file changed, 1 insertion(+), 1 deletion(-) > > > > > > > > diff --git a/drivers/gpu/drm/i915/gvt/gtt.c b/drivers/gpu/drm/i915/gvt/gtt.c > > > > index ce0eb03709c3..9f14fded8c0c 100644 > > > > --- a/drivers/gpu/drm/i915/gvt/gtt.c > > > > +++ b/drivers/gpu/drm/i915/gvt/gtt.c > > > > @@ -1215,7 +1215,7 @@ static int split_2MB_gtt_entry(struct intel_vgpu *vgpu, > > > > ret = intel_gvt_dma_map_guest_page(vgpu, start_gfn + sub_index, > > > > PAGE_SIZE, &dma_addr); > > > > if (ret) { > > > > - ppgtt_invalidate_spt(spt); > > > > + ret = ppgtt_invalidate_spt(spt); > > > > return ret; > > > > > > But now you just lost the original error, shouldn't this succeed even if > > > intel_gvt_dma_map_guest_page() failed? > > > > > > And how are you causing intel_gvt_dma_map_guest_page() to fail in a real > > > system? > > > > > > thanks, > > > > > > greg k-h ^ permalink raw reply [flat|nested] 50+ messages in thread
* Re: [PATCH] drm/i915/gvt: fix double-free bug in split_2MB_gtt_entry. 2022-09-08 9:09 ` Zheng Hacker @ 2022-09-08 9:19 ` Greg KH 2022-09-08 11:59 ` Zheng Hacker 0 siblings, 1 reply; 50+ messages in thread From: Greg KH @ 2022-09-08 9:19 UTC (permalink / raw) To: Zheng Hacker Cc: alex000young, security, tvrtko.ursulin, airlied, intel-gfx, linux-kernel, dri-devel, xmzyshypnc, rodrigo.vivi, intel-gvt-dev, zhi.a.wang On Thu, Sep 08, 2022 at 05:09:40PM +0800, Zheng Hacker wrote: > Hi Zhenyu, > > This issue has been open for a few days. Could you plz write a patch > for that :) I'm not familiar with the logical code here. As this is only able to be hit in a theoretical system, it isn't that high of a priority, if any priority at all. Why not try to write a patch for it yourself to help resolve the issue faster? thanks, greg k-h ^ permalink raw reply [flat|nested] 50+ messages in thread
* Re: [PATCH] drm/i915/gvt: fix double-free bug in split_2MB_gtt_entry. 2022-09-08 9:19 ` Greg KH @ 2022-09-08 11:59 ` Zheng Hacker 2022-09-16 6:39 ` Zheng Hacker 0 siblings, 1 reply; 50+ messages in thread From: Zheng Hacker @ 2022-09-08 11:59 UTC (permalink / raw) To: Greg KH Cc: alex000young, security, tvrtko.ursulin, airlied, intel-gfx, linux-kernel, dri-devel, xmzyshypnc, rodrigo.vivi, intel-gvt-dev, zhi.a.wang [-- Attachment #1: Type: text/plain, Size: 710 bytes --] Hi Greg, I got it, Greg. Mid-Autumn Festival is coming and I will have a couple of days off. I'll see what I can do after holiday :) Regards, Zheng Wang 在 2022年9月8日星期四,Greg KH <gregkh@linuxfoundation.org> 写道: > On Thu, Sep 08, 2022 at 05:09:40PM +0800, Zheng Hacker wrote: > > Hi Zhenyu, > > > > This issue has been open for a few days. Could you plz write a patch > > for that :) I'm not familiar with the logical code here. > > As this is only able to be hit in a theoretical system, it isn't that > high of a priority, if any priority at all. Why not try to write a > patch for it yourself to help resolve the issue faster? > > thanks, > > greg k-h > [-- Attachment #2: Type: text/html, Size: 955 bytes --] ^ permalink raw reply [flat|nested] 50+ messages in thread
* Re: [PATCH] drm/i915/gvt: fix double-free bug in split_2MB_gtt_entry. 2022-09-08 11:59 ` Zheng Hacker @ 2022-09-16 6:39 ` Zheng Hacker 2022-09-16 6:40 ` Zheng Hacker 2022-09-16 8:25 ` Greg KH 0 siblings, 2 replies; 50+ messages in thread From: Zheng Hacker @ 2022-09-16 6:39 UTC (permalink / raw) To: Greg KH Cc: alex000young, security, tvrtko.ursulin, airlied, intel-gfx, linux-kernel, dri-devel, xmzyshypnc, rodrigo.vivi, intel-gvt-dev, zhi.a.wang From 8d95c1399e3ff345500a575e21254a73b0c89144 Mon Sep 17 00:00:00 2001 From: xmzyshypnc <1002992920@qq.com> Date: Fri, 16 Sep 2022 14:37:48 +0800 Subject: [PATCH] drm/i915/gvt: fix double-free bug in split_2MB_gtt_entry There is a double-free security bug in split_2MB_gtt_entry. Here is a calling chain : ppgtt_populate_spt->ppgtt_populate_shadow_entry->split_2MB_gtt_entry. If intel_gvt_dma_map_guest_page failed, it will call ppgtt_invalidate_spt, which will finally call ppgtt_free_spt and kfree(spt). But the caller does not notice that, and it will call ppgtt_free_spt again in error path. Fix this by only freeing spt in ppgtt_invalidate_spt in good case. Signed-off-by: xmzyshypnc <1002992920@qq.com> --- drivers/gpu/drm/i915/gvt/gtt.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/i915/gvt/gtt.c b/drivers/gpu/drm/i915/gvt/gtt.c index 9f14fded8c0c..31d2a8d56384 100644 --- a/drivers/gpu/drm/i915/gvt/gtt.c +++ b/drivers/gpu/drm/i915/gvt/gtt.c @@ -959,7 +959,7 @@ static inline int ppgtt_put_spt(struct intel_vgpu_ppgtt_spt *spt) return atomic_dec_return(&spt->refcount); } -static int ppgtt_invalidate_spt(struct intel_vgpu_ppgtt_spt *spt); +static int ppgtt_invalidate_spt(struct intel_vgpu_ppgtt_spt *sptm, int is_error); static int ppgtt_invalidate_spt_by_shadow_entry(struct intel_vgpu *vgpu, struct intel_gvt_gtt_entry *e) @@ -995,7 +995,7 @@ static int ppgtt_invalidate_spt_by_shadow_entry(struct intel_vgpu *vgpu, ops->get_pfn(e)); return -ENXIO; } - return ppgtt_invalidate_spt(s); + return ppgtt_invalidate_spt(s, 0); } static inline void ppgtt_invalidate_pte(struct intel_vgpu_ppgtt_spt *spt, @@ -1016,7 +1016,7 @@ static inline void ppgtt_invalidate_pte(struct intel_vgpu_ppgtt_spt *spt, intel_gvt_dma_unmap_guest_page(vgpu, pfn << PAGE_SHIFT); } -static int ppgtt_invalidate_spt(struct intel_vgpu_ppgtt_spt *spt) +static int ppgtt_invalidate_spt(struct intel_vgpu_ppgtt_spt *spt, int is_error) { struct intel_vgpu *vgpu = spt->vgpu; struct intel_gvt_gtt_entry e; @@ -1059,9 +1059,11 @@ static int ppgtt_invalidate_spt(struct intel_vgpu_ppgtt_spt *spt) } } - trace_spt_change(spt->vgpu->id, "release", spt, + if (!is_error) { + trace_spt_change(spt->vgpu->id, "release", spt, spt->guest_page.gfn, spt->shadow_page.type); - ppgtt_free_spt(spt); + ppgtt_free_spt(spt); + } return 0; fail: gvt_vgpu_err("fail: shadow page %p shadow entry 0x%llx type %d\n", @@ -1215,7 +1217,7 @@ static int split_2MB_gtt_entry(struct intel_vgpu *vgpu, ret = intel_gvt_dma_map_guest_page(vgpu, start_gfn + sub_index, PAGE_SIZE, &dma_addr); if (ret) { - ret = ppgtt_invalidate_spt(spt); + ret = ppgtt_invalidate_spt(spt, 1); return ret; } sub_se.val64 = se->val64; @@ -1393,7 +1395,7 @@ static int ppgtt_handle_guest_entry_removal(struct intel_vgpu_ppgtt_spt *spt, ret = -ENXIO; goto fail; } - ret = ppgtt_invalidate_spt(s); + ret = ppgtt_invalidate_spt(s, 0); if (ret) goto fail; } else { -- 2.25.1 Zheng Hacker <hackerzheng666@gmail.com> 于2022年9月8日周四 19:59写道: > > Hi Greg, > > I got it, Greg. > > Mid-Autumn Festival is coming and I will have a couple of days off. > I'll see what I can do after holiday :) > > Regards, > > Zheng Wang > > 在 2022年9月8日星期四,Greg KH <gregkh@linuxfoundation.org> 写道: >> >> On Thu, Sep 08, 2022 at 05:09:40PM +0800, Zheng Hacker wrote: >> > Hi Zhenyu, >> > >> > This issue has been open for a few days. Could you plz write a patch >> > for that :) I'm not familiar with the logical code here. >> >> As this is only able to be hit in a theoretical system, it isn't that >> high of a priority, if any priority at all. Why not try to write a >> patch for it yourself to help resolve the issue faster? >> >> thanks, >> >> greg k-h ^ permalink raw reply related [flat|nested] 50+ messages in thread
* Re: [PATCH] drm/i915/gvt: fix double-free bug in split_2MB_gtt_entry. 2022-09-16 6:39 ` Zheng Hacker @ 2022-09-16 6:40 ` Zheng Hacker 2022-09-16 8:25 ` Greg KH 1 sibling, 0 replies; 50+ messages in thread From: Zheng Hacker @ 2022-09-16 6:40 UTC (permalink / raw) To: Greg KH Cc: alex000young, security, tvrtko.ursulin, airlied, intel-gfx, linux-kernel, dri-devel, xmzyshypnc, rodrigo.vivi, intel-gvt-dev, zhi.a.wang Here I introduced is_error to judge if the ppgtt_invalidate_spt is called from good case or not. Only free spt in good case, leave it to handle for the error path of caller. Zheng Hacker <hackerzheng666@gmail.com> 于2022年9月16日周五 14:39写道: > > From 8d95c1399e3ff345500a575e21254a73b0c89144 Mon Sep 17 00:00:00 2001 > From: xmzyshypnc <1002992920@qq.com> > Date: Fri, 16 Sep 2022 14:37:48 +0800 > Subject: [PATCH] drm/i915/gvt: fix double-free bug in split_2MB_gtt_entry > > There is a double-free security bug in split_2MB_gtt_entry. > > Here is a calling chain : > ppgtt_populate_spt->ppgtt_populate_shadow_entry->split_2MB_gtt_entry. > If intel_gvt_dma_map_guest_page failed, it will call > ppgtt_invalidate_spt, which will finally call ppgtt_free_spt and > kfree(spt). But the caller does not notice that, and it will call > ppgtt_free_spt again in error path. > > Fix this by only freeing spt in ppgtt_invalidate_spt in good case. > > Signed-off-by: xmzyshypnc <1002992920@qq.com> > --- > drivers/gpu/drm/i915/gvt/gtt.c | 16 +++++++++------- > 1 file changed, 9 insertions(+), 7 deletions(-) > > diff --git a/drivers/gpu/drm/i915/gvt/gtt.c b/drivers/gpu/drm/i915/gvt/gtt.c > index 9f14fded8c0c..31d2a8d56384 100644 > --- a/drivers/gpu/drm/i915/gvt/gtt.c > +++ b/drivers/gpu/drm/i915/gvt/gtt.c > @@ -959,7 +959,7 @@ static inline int ppgtt_put_spt(struct > intel_vgpu_ppgtt_spt *spt) > return atomic_dec_return(&spt->refcount); > } > > -static int ppgtt_invalidate_spt(struct intel_vgpu_ppgtt_spt *spt); > +static int ppgtt_invalidate_spt(struct intel_vgpu_ppgtt_spt *sptm, > int is_error); > > static int ppgtt_invalidate_spt_by_shadow_entry(struct intel_vgpu *vgpu, > struct intel_gvt_gtt_entry *e) > @@ -995,7 +995,7 @@ static int > ppgtt_invalidate_spt_by_shadow_entry(struct intel_vgpu *vgpu, > ops->get_pfn(e)); > return -ENXIO; > } > - return ppgtt_invalidate_spt(s); > + return ppgtt_invalidate_spt(s, 0); > } > > static inline void ppgtt_invalidate_pte(struct intel_vgpu_ppgtt_spt *spt, > @@ -1016,7 +1016,7 @@ static inline void ppgtt_invalidate_pte(struct > intel_vgpu_ppgtt_spt *spt, > intel_gvt_dma_unmap_guest_page(vgpu, pfn << PAGE_SHIFT); > } > > -static int ppgtt_invalidate_spt(struct intel_vgpu_ppgtt_spt *spt) > +static int ppgtt_invalidate_spt(struct intel_vgpu_ppgtt_spt *spt, int is_error) > { > struct intel_vgpu *vgpu = spt->vgpu; > struct intel_gvt_gtt_entry e; > @@ -1059,9 +1059,11 @@ static int ppgtt_invalidate_spt(struct > intel_vgpu_ppgtt_spt *spt) > } > } > > - trace_spt_change(spt->vgpu->id, "release", spt, > + if (!is_error) { > + trace_spt_change(spt->vgpu->id, "release", spt, > spt->guest_page.gfn, spt->shadow_page.type); > - ppgtt_free_spt(spt); > + ppgtt_free_spt(spt); > + } > return 0; > fail: > gvt_vgpu_err("fail: shadow page %p shadow entry 0x%llx type %d\n", > @@ -1215,7 +1217,7 @@ static int split_2MB_gtt_entry(struct intel_vgpu *vgpu, > ret = intel_gvt_dma_map_guest_page(vgpu, start_gfn + sub_index, > PAGE_SIZE, &dma_addr); > if (ret) { > - ret = ppgtt_invalidate_spt(spt); > + ret = ppgtt_invalidate_spt(spt, 1); > return ret; > } > sub_se.val64 = se->val64; > @@ -1393,7 +1395,7 @@ static int > ppgtt_handle_guest_entry_removal(struct intel_vgpu_ppgtt_spt *spt, > ret = -ENXIO; > goto fail; > } > - ret = ppgtt_invalidate_spt(s); > + ret = ppgtt_invalidate_spt(s, 0); > if (ret) > goto fail; > } else { > -- > 2.25.1 > > Zheng Hacker <hackerzheng666@gmail.com> 于2022年9月8日周四 19:59写道: > > > > Hi Greg, > > > > I got it, Greg. > > > > Mid-Autumn Festival is coming and I will have a couple of days off. > > I'll see what I can do after holiday :) > > > > Regards, > > > > Zheng Wang > > > > 在 2022年9月8日星期四,Greg KH <gregkh@linuxfoundation.org> 写道: > >> > >> On Thu, Sep 08, 2022 at 05:09:40PM +0800, Zheng Hacker wrote: > >> > Hi Zhenyu, > >> > > >> > This issue has been open for a few days. Could you plz write a patch > >> > for that :) I'm not familiar with the logical code here. > >> > >> As this is only able to be hit in a theoretical system, it isn't that > >> high of a priority, if any priority at all. Why not try to write a > >> patch for it yourself to help resolve the issue faster? > >> > >> thanks, > >> > >> greg k-h ^ permalink raw reply [flat|nested] 50+ messages in thread
* Re: [PATCH] drm/i915/gvt: fix double-free bug in split_2MB_gtt_entry. 2022-09-16 6:39 ` Zheng Hacker 2022-09-16 6:40 ` Zheng Hacker @ 2022-09-16 8:25 ` Greg KH 2022-09-16 15:21 ` Zheng Hacker 2022-09-16 15:54 ` Zheng Hacker 1 sibling, 2 replies; 50+ messages in thread From: Greg KH @ 2022-09-16 8:25 UTC (permalink / raw) To: Zheng Hacker Cc: alex000young, security, tvrtko.ursulin, airlied, intel-gfx, linux-kernel, dri-devel, xmzyshypnc, rodrigo.vivi, intel-gvt-dev, zhi.a.wang On Fri, Sep 16, 2022 at 02:39:21PM +0800, Zheng Hacker wrote: > >From 8d95c1399e3ff345500a575e21254a73b0c89144 Mon Sep 17 00:00:00 2001 > From: xmzyshypnc <1002992920@qq.com> > Date: Fri, 16 Sep 2022 14:37:48 +0800 > Subject: [PATCH] drm/i915/gvt: fix double-free bug in split_2MB_gtt_entry > > There is a double-free security bug in split_2MB_gtt_entry. > > Here is a calling chain : > ppgtt_populate_spt->ppgtt_populate_shadow_entry->split_2MB_gtt_entry. > If intel_gvt_dma_map_guest_page failed, it will call > ppgtt_invalidate_spt, which will finally call ppgtt_free_spt and > kfree(spt). But the caller does not notice that, and it will call > ppgtt_free_spt again in error path. > > Fix this by only freeing spt in ppgtt_invalidate_spt in good case. > > Signed-off-by: xmzyshypnc <1002992920@qq.com> > --- > drivers/gpu/drm/i915/gvt/gtt.c | 16 +++++++++------- > 1 file changed, 9 insertions(+), 7 deletions(-) > > diff --git a/drivers/gpu/drm/i915/gvt/gtt.c b/drivers/gpu/drm/i915/gvt/gtt.c > index 9f14fded8c0c..31d2a8d56384 100644 > --- a/drivers/gpu/drm/i915/gvt/gtt.c > +++ b/drivers/gpu/drm/i915/gvt/gtt.c > @@ -959,7 +959,7 @@ static inline int ppgtt_put_spt(struct > intel_vgpu_ppgtt_spt *spt) > return atomic_dec_return(&spt->refcount); > } > > -static int ppgtt_invalidate_spt(struct intel_vgpu_ppgtt_spt *spt); > +static int ppgtt_invalidate_spt(struct intel_vgpu_ppgtt_spt *sptm, > int is_error); Your patch is whitespace damaged and linewrapped and can not be applied, and can only barely read :( Please fix up your email client to not do this so that the change can be properly reviewed and accepted if correct. thanks, greg k-h ^ permalink raw reply [flat|nested] 50+ messages in thread
* Re: [PATCH] drm/i915/gvt: fix double-free bug in split_2MB_gtt_entry. 2022-09-16 8:25 ` Greg KH @ 2022-09-16 15:21 ` Zheng Hacker 2022-09-16 15:54 ` Zheng Hacker 1 sibling, 0 replies; 50+ messages in thread From: Zheng Hacker @ 2022-09-16 15:21 UTC (permalink / raw) To: Greg KH Cc: alex000young, security, tvrtko.ursulin, airlied, intel-gfx, linux-kernel, dri-devel, xmzyshypnc, rodrigo.vivi, intel-gvt-dev, zhi.a.wang Hi greg, Thanks for pointing that out. Working on it now :) Best wishes, Zheng Wang Greg KH <gregkh@linuxfoundation.org> 于2022年9月16日周五 16:25写道: > > On Fri, Sep 16, 2022 at 02:39:21PM +0800, Zheng Hacker wrote: > > >From 8d95c1399e3ff345500a575e21254a73b0c89144 Mon Sep 17 00:00:00 2001 > > From: xmzyshypnc <1002992920@qq.com> > > Date: Fri, 16 Sep 2022 14:37:48 +0800 > > Subject: [PATCH] drm/i915/gvt: fix double-free bug in split_2MB_gtt_entry > > > > There is a double-free security bug in split_2MB_gtt_entry. > > > > Here is a calling chain : > > ppgtt_populate_spt->ppgtt_populate_shadow_entry->split_2MB_gtt_entry. > > If intel_gvt_dma_map_guest_page failed, it will call > > ppgtt_invalidate_spt, which will finally call ppgtt_free_spt and > > kfree(spt). But the caller does not notice that, and it will call > > ppgtt_free_spt again in error path. > > > > Fix this by only freeing spt in ppgtt_invalidate_spt in good case. > > > > Signed-off-by: xmzyshypnc <1002992920@qq.com> > > --- > > drivers/gpu/drm/i915/gvt/gtt.c | 16 +++++++++------- > > 1 file changed, 9 insertions(+), 7 deletions(-) > > > > diff --git a/drivers/gpu/drm/i915/gvt/gtt.c b/drivers/gpu/drm/i915/gvt/gtt.c > > index 9f14fded8c0c..31d2a8d56384 100644 > > --- a/drivers/gpu/drm/i915/gvt/gtt.c > > +++ b/drivers/gpu/drm/i915/gvt/gtt.c > > @@ -959,7 +959,7 @@ static inline int ppgtt_put_spt(struct > > intel_vgpu_ppgtt_spt *spt) > > return atomic_dec_return(&spt->refcount); > > } > > > > -static int ppgtt_invalidate_spt(struct intel_vgpu_ppgtt_spt *spt); > > +static int ppgtt_invalidate_spt(struct intel_vgpu_ppgtt_spt *sptm, > > int is_error); > > Your patch is whitespace damaged and linewrapped and can not be applied, > and can only barely read :( > > Please fix up your email client to not do this so that the change can be > properly reviewed and accepted if correct. > > thanks, > > greg k-h ^ permalink raw reply [flat|nested] 50+ messages in thread
* Re: [PATCH] drm/i915/gvt: fix double-free bug in split_2MB_gtt_entry. 2022-09-16 8:25 ` Greg KH 2022-09-16 15:21 ` Zheng Hacker @ 2022-09-16 15:54 ` Zheng Hacker 2022-09-17 9:08 ` Greg KH 1 sibling, 1 reply; 50+ messages in thread From: Zheng Hacker @ 2022-09-16 15:54 UTC (permalink / raw) To: Greg KH Cc: alex000young, security, tvrtko.ursulin, airlied, intel-gfx, linux-kernel, dri-devel, xmzyshypnc, rodrigo.vivi, intel-gvt-dev, zhi.a.wang From afe79848cb74cc8e45ab426d13fa2394c87e0422 Mon Sep 17 00:00:00 2001 From: xmzyshypnc <1002992920@qq.com> Date: Fri, 16 Sep 2022 23:48:23 +0800 Subject: [PATCH] drm/i915/gvt: fix double-free bug in split_2MB_gtt_entry There is a double-free security bug in split_2MB_gtt_entry. Here is a calling chain : ppgtt_populate_spt->ppgtt_populate_shadow_entry->split_2MB_gtt_entry. If intel_gvt_dma_map_guest_page failed, it will call ppgtt_invalidate_spt, which will finally call ppgtt_free_spt and kfree(spt). But the caller does not notice that, and it will call ppgtt_free_spt again in error path. Fix this by only freeing spt in ppgtt_invalidate_spt in good case. Signed-off-by: Zheng Wang <hackerzheng666@gmail.com> --- drivers/gpu/drm/i915/gvt/gtt.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/i915/gvt/gtt.c b/drivers/gpu/drm/i915/gvt/gtt.c index ce0eb03709c3..550519f0acca 100644 --- a/drivers/gpu/drm/i915/gvt/gtt.c +++ b/drivers/gpu/drm/i915/gvt/gtt.c @@ -959,7 +959,7 @@ static inline int ppgtt_put_spt(struct intel_vgpu_ppgtt_spt *spt) return atomic_dec_return(&spt->refcount); } -static int ppgtt_invalidate_spt(struct intel_vgpu_ppgtt_spt *spt); +static int ppgtt_invalidate_spt(struct intel_vgpu_ppgtt_spt *spt, int is_error); static int ppgtt_invalidate_spt_by_shadow_entry(struct intel_vgpu *vgpu, struct intel_gvt_gtt_entry *e) @@ -995,7 +995,7 @@ static int ppgtt_invalidate_spt_by_shadow_entry(struct intel_vgpu *vgpu, ops->get_pfn(e)); return -ENXIO; } - return ppgtt_invalidate_spt(s); + return ppgtt_invalidate_spt(s, 0); } static inline void ppgtt_invalidate_pte(struct intel_vgpu_ppgtt_spt *spt, @@ -1016,7 +1016,7 @@ static inline void ppgtt_invalidate_pte(struct intel_vgpu_ppgtt_spt *spt, intel_gvt_dma_unmap_guest_page(vgpu, pfn << PAGE_SHIFT); } -static int ppgtt_invalidate_spt(struct intel_vgpu_ppgtt_spt *spt) +static int ppgtt_invalidate_spt(struct intel_vgpu_ppgtt_spt *spt, int is_error) { struct intel_vgpu *vgpu = spt->vgpu; struct intel_gvt_gtt_entry e; @@ -1059,9 +1059,11 @@ static int ppgtt_invalidate_spt(struct intel_vgpu_ppgtt_spt *spt) } } - trace_spt_change(spt->vgpu->id, "release", spt, + if (!is_error) { + trace_spt_change(spt->vgpu->id, "release", spt, spt->guest_page.gfn, spt->shadow_page.type); - ppgtt_free_spt(spt); + ppgtt_free_spt(spt); + } return 0; fail: gvt_vgpu_err("fail: shadow page %p shadow entry 0x%llx type %d\n", @@ -1215,7 +1217,7 @@ static int split_2MB_gtt_entry(struct intel_vgpu *vgpu, ret = intel_gvt_dma_map_guest_page(vgpu, start_gfn + sub_index, PAGE_SIZE, &dma_addr); if (ret) { - ppgtt_invalidate_spt(spt); + ppgtt_invalidate_spt(spt, 1); return ret; } sub_se.val64 = se->val64; @@ -1393,7 +1395,7 @@ static int ppgtt_handle_guest_entry_removal(struct intel_vgpu_ppgtt_spt *spt, ret = -ENXIO; goto fail; } - ret = ppgtt_invalidate_spt(s); + ret = ppgtt_invalidate_spt(s, 0); if (ret) goto fail; } else { -- 2.25.1 ^ permalink raw reply related [flat|nested] 50+ messages in thread
* Re: [PATCH] drm/i915/gvt: fix double-free bug in split_2MB_gtt_entry. 2022-09-16 15:54 ` Zheng Hacker @ 2022-09-17 9:08 ` Greg KH 2022-09-17 9:10 ` Zheng Hacker ` (2 more replies) 0 siblings, 3 replies; 50+ messages in thread From: Greg KH @ 2022-09-17 9:08 UTC (permalink / raw) To: Zheng Hacker Cc: alex000young, security, tvrtko.ursulin, airlied, intel-gfx, linux-kernel, dri-devel, xmzyshypnc, rodrigo.vivi, intel-gvt-dev, zhi.a.wang On Fri, Sep 16, 2022 at 11:54:42PM +0800, Zheng Hacker wrote: > >From afe79848cb74cc8e45ab426d13fa2394c87e0422 Mon Sep 17 00:00:00 2001 > From: xmzyshypnc <1002992920@qq.com> > Date: Fri, 16 Sep 2022 23:48:23 +0800 > Subject: [PATCH] drm/i915/gvt: fix double-free bug in split_2MB_gtt_entry > > There is a double-free security bug in split_2MB_gtt_entry. > > Here is a calling chain : > ppgtt_populate_spt->ppgtt_populate_shadow_entry->split_2MB_gtt_entry. > > If intel_gvt_dma_map_guest_page failed, it will call > ppgtt_invalidate_spt, which will finally call ppgtt_free_spt and > kfree(spt). But the caller does not notice that, and it will call > ppgtt_free_spt again in error path. > > Fix this by only freeing spt in ppgtt_invalidate_spt in good case. > > Signed-off-by: Zheng Wang <hackerzheng666@gmail.com> > --- > drivers/gpu/drm/i915/gvt/gtt.c | 16 +++++++++------- > 1 file changed, 9 insertions(+), 7 deletions(-) > > diff --git a/drivers/gpu/drm/i915/gvt/gtt.c b/drivers/gpu/drm/i915/gvt/gtt.c > index ce0eb03709c3..550519f0acca 100644 > --- a/drivers/gpu/drm/i915/gvt/gtt.c > +++ b/drivers/gpu/drm/i915/gvt/gtt.c > @@ -959,7 +959,7 @@ static inline int ppgtt_put_spt(struct > intel_vgpu_ppgtt_spt *spt) > return atomic_dec_return(&spt->refcount); > } > > -static int ppgtt_invalidate_spt(struct intel_vgpu_ppgtt_spt *spt); > +static int ppgtt_invalidate_spt(struct intel_vgpu_ppgtt_spt *spt, int > is_error); > > static int ppgtt_invalidate_spt_by_shadow_entry(struct intel_vgpu *vgpu, > struct intel_gvt_gtt_entry *e) > @@ -995,7 +995,7 @@ static int > ppgtt_invalidate_spt_by_shadow_entry(struct intel_vgpu *vgpu, Still line-wrapped and whitespace broken :( ^ permalink raw reply [flat|nested] 50+ messages in thread
* Re: [PATCH] drm/i915/gvt: fix double-free bug in split_2MB_gtt_entry. 2022-09-17 9:08 ` Greg KH @ 2022-09-17 9:10 ` Zheng Hacker 2022-09-18 17:08 ` =?gb18030?B?s68=?= 2022-09-18 17:17 ` Zheng Hacker 2 siblings, 0 replies; 50+ messages in thread From: Zheng Hacker @ 2022-09-17 9:10 UTC (permalink / raw) To: Greg KH Cc: alex000young, security, tvrtko.ursulin, airlied, intel-gfx, linux-kernel, dri-devel, xmzyshypnc, rodrigo.vivi, intel-gvt-dev, zhi.a.wang [-- Attachment #1: Type: text/plain, Size: 1992 bytes --] Hi Greg, Sorry for that. I’ll write another one. Regards, Zheng Wang 在 2022年9月17日星期六,Greg KH <gregkh@linuxfoundation.org> 写道: > On Fri, Sep 16, 2022 at 11:54:42PM +0800, Zheng Hacker wrote: > > >From afe79848cb74cc8e45ab426d13fa2394c87e0422 Mon Sep 17 00:00:00 2001 > > From: xmzyshypnc <1002992920@qq.com> > > Date: Fri, 16 Sep 2022 23:48:23 +0800 > > Subject: [PATCH] drm/i915/gvt: fix double-free bug in split_2MB_gtt_entry > > > > There is a double-free security bug in split_2MB_gtt_entry. > > > > Here is a calling chain : > > ppgtt_populate_spt->ppgtt_populate_shadow_entry->split_2MB_gtt_entry. > > > > If intel_gvt_dma_map_guest_page failed, it will call > > ppgtt_invalidate_spt, which will finally call ppgtt_free_spt and > > kfree(spt). But the caller does not notice that, and it will call > > ppgtt_free_spt again in error path. > > > > Fix this by only freeing spt in ppgtt_invalidate_spt in good case. > > > > Signed-off-by: Zheng Wang <hackerzheng666@gmail.com> > > --- > > drivers/gpu/drm/i915/gvt/gtt.c | 16 +++++++++------- > > 1 file changed, 9 insertions(+), 7 deletions(-) > > > > diff --git a/drivers/gpu/drm/i915/gvt/gtt.c b/drivers/gpu/drm/i915/gvt/ > gtt.c > > index ce0eb03709c3..550519f0acca 100644 > > --- a/drivers/gpu/drm/i915/gvt/gtt.c > > +++ b/drivers/gpu/drm/i915/gvt/gtt.c > > @@ -959,7 +959,7 @@ static inline int ppgtt_put_spt(struct > > intel_vgpu_ppgtt_spt *spt) > > return atomic_dec_return(&spt->refcount); > > } > > > > -static int ppgtt_invalidate_spt(struct intel_vgpu_ppgtt_spt *spt); > > +static int ppgtt_invalidate_spt(struct intel_vgpu_ppgtt_spt *spt, int > > is_error); > > > > static int ppgtt_invalidate_spt_by_shadow_entry(struct intel_vgpu > *vgpu, > > struct intel_gvt_gtt_entry *e) > > @@ -995,7 +995,7 @@ static int > > ppgtt_invalidate_spt_by_shadow_entry(struct intel_vgpu *vgpu, > > Still line-wrapped and whitespace broken :( > > [-- Attachment #2: Type: text/html, Size: 2598 bytes --] ^ permalink raw reply [flat|nested] 50+ messages in thread
* Re: [PATCH] drm/i915/gvt: fix double-free bug in split_2MB_gtt_entry. 2022-09-17 9:08 ` Greg KH 2022-09-17 9:10 ` Zheng Hacker @ 2022-09-18 17:08 ` =?gb18030?B?s68=?= 2022-09-18 17:17 ` Zheng Hacker 2 siblings, 0 replies; 50+ messages in thread From: =?gb18030?B?s68=?= @ 2022-09-18 17:08 UTC (permalink / raw) To: =?gb18030?B?R3JlZyBLSA==?=, =?gb18030?B?WmhlbmcgSGFja2Vy?= Cc: =?gb18030?B?YWxleDAwMHlvdW5nQGdtYWlsLmNvbQ==?=, =?gb18030?B?c2VjdXJpdHlAa2VybmVsLm9yZw==?=, =?gb18030?B?dHZydGtvLnVyc3VsaW5AbGludXguaW50ZWwuY29t?=, =?gb18030?B?YWlybGllZEBsaW51eC5pZQ==?=, =?gb18030?B?aW50ZWwtZ2Z4QGxpc3RzLmZyZWVkZXNrdG9wLm9yZw==?=, =?gb18030?B?bGludXgta2VybmVsQHZnZXIua2VybmVsLm9yZw==?=, =?gb18030?B?ZHJpLWRldmVsQGxpc3RzLmZyZWVkZXNrdG9wLm9yZw==?=, =?gb18030?B?cm9kcmlnby52aXZpQGludGVsLmNvbQ==?=, =?gb18030?B?aW50ZWwtZ3Z0LWRldkBsaXN0cy5mcmVlZGVza3RvcC5vcmc=?=, =?gb18030?B?emhpLmEud2FuZ0BpbnRlbC5jb20=?= [-- Warning: decoded text below may be mangled, UTF-8 assumed --] [-- Attachment #1: Type: text/plain; charset="gb18030", Size: 3114 bytes --] From afe79848cb74cc8e45ab426d13fa2394c87e0422 Mon Sep 17 00:00:00 2001 From: xmzyshypnc <1002992920@qq.com> Date: Fri, 16 Sep 2022 23:48:23 +0800 Subject: [PATCH] drm/i915/gvt: fix double-free bug in split_2MB_gtt_entry There is a double-free security bug in split_2MB_gtt_entry. Here is a calling chain : ppgtt_populate_spt->ppgtt_populate_shadow_entry->split_2MB_gtt_entry. If intel_gvt_dma_map_guest_page failed, it will call ppgtt_invalidate_spt, which will finally call ppgtt_free_spt and kfree(spt). But the caller does not notice that, and it will call ppgtt_free_spt again in error path. Fix this by only freeing spt in ppgtt_invalidate_spt in good case. Signed-off-by: xmzyshypnc <1002992920@qq.com> --- drivers/gpu/drm/i915/gvt/gtt.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/i915/gvt/gtt.c b/drivers/gpu/drm/i915/gvt/gtt.c index ce0eb03709c3..550519f0acca 100644 --- a/drivers/gpu/drm/i915/gvt/gtt.c +++ b/drivers/gpu/drm/i915/gvt/gtt.c @@ -959,7 +959,7 @@ static inline int ppgtt_put_spt(struct intel_vgpu_ppgtt_spt *spt) return atomic_dec_return(&spt->refcount); } -static int ppgtt_invalidate_spt(struct intel_vgpu_ppgtt_spt *spt); +static int ppgtt_invalidate_spt(struct intel_vgpu_ppgtt_spt *spt, int is_error); static int ppgtt_invalidate_spt_by_shadow_entry(struct intel_vgpu *vgpu, struct intel_gvt_gtt_entry *e) @@ -995,7 +995,7 @@ static int ppgtt_invalidate_spt_by_shadow_entry(struct intel_vgpu *vgpu, ops->get_pfn(e)); return -ENXIO; } - return ppgtt_invalidate_spt(s); + return ppgtt_invalidate_spt(s, 0); } static inline void ppgtt_invalidate_pte(struct intel_vgpu_ppgtt_spt *spt, @@ -1016,7 +1016,7 @@ static inline void ppgtt_invalidate_pte(struct intel_vgpu_ppgtt_spt *spt, intel_gvt_dma_unmap_guest_page(vgpu, pfn << PAGE_SHIFT); } -static int ppgtt_invalidate_spt(struct intel_vgpu_ppgtt_spt *spt) +static int ppgtt_invalidate_spt(struct intel_vgpu_ppgtt_spt *spt, int is_error) { struct intel_vgpu *vgpu = spt->vgpu; struct intel_gvt_gtt_entry e; @@ -1059,9 +1059,11 @@ static int ppgtt_invalidate_spt(struct intel_vgpu_ppgtt_spt *spt) } } - trace_spt_change(spt->vgpu->id, "release", spt, + if (!is_error) { + trace_spt_change(spt->vgpu->id, "release", spt, spt->guest_page.gfn, spt->shadow_page.type); - ppgtt_free_spt(spt); + ppgtt_free_spt(spt); + } return 0; fail: gvt_vgpu_err("fail: shadow page %p shadow entry 0x%llx type %d\n", @@ -1215,7 +1217,7 @@ static int split_2MB_gtt_entry(struct intel_vgpu *vgpu, ret = intel_gvt_dma_map_guest_page(vgpu, start_gfn + sub_index, PAGE_SIZE, &dma_addr); if (ret) { - ppgtt_invalidate_spt(spt); + ppgtt_invalidate_spt(spt, 1); return ret; } sub_se.val64 = se->val64; @@ -1393,7 +1395,7 @@ static int ppgtt_handle_guest_entry_removal(struct intel_vgpu_ppgtt_spt *spt, ret = -ENXIO; goto fail; } - ret = ppgtt_invalidate_spt(s); + ret = ppgtt_invalidate_spt(s, 0); if (ret) goto fail; } else { -- 2.25.1 ^ permalink raw reply related [flat|nested] 50+ messages in thread
* Re: [PATCH] drm/i915/gvt: fix double-free bug in split_2MB_gtt_entry. 2022-09-17 9:08 ` Greg KH 2022-09-17 9:10 ` Zheng Hacker 2022-09-18 17:08 ` =?gb18030?B?s68=?= @ 2022-09-18 17:17 ` Zheng Hacker 2 siblings, 0 replies; 50+ messages in thread From: Zheng Hacker @ 2022-09-18 17:17 UTC (permalink / raw) To: Greg KH Cc: alex000young, security, tvrtko.ursulin, airlied, intel-gfx, linux-kernel, dri-devel, xmzyshypnc, rodrigo.vivi, intel-gvt-dev, zhi.a.wang I'll try using another mail client like Mutt later. :) Regards, Zheng Wang Greg KH <gregkh@linuxfoundation.org> 于2022年9月17日周六 17:07写道: > > On Fri, Sep 16, 2022 at 11:54:42PM +0800, Zheng Hacker wrote: > > >From afe79848cb74cc8e45ab426d13fa2394c87e0422 Mon Sep 17 00:00:00 2001 > > From: xmzyshypnc <1002992920@qq.com> > > Date: Fri, 16 Sep 2022 23:48:23 +0800 > > Subject: [PATCH] drm/i915/gvt: fix double-free bug in split_2MB_gtt_entry > > > > There is a double-free security bug in split_2MB_gtt_entry. > > > > Here is a calling chain : > > ppgtt_populate_spt->ppgtt_populate_shadow_entry->split_2MB_gtt_entry. > > > > If intel_gvt_dma_map_guest_page failed, it will call > > ppgtt_invalidate_spt, which will finally call ppgtt_free_spt and > > kfree(spt). But the caller does not notice that, and it will call > > ppgtt_free_spt again in error path. > > > > Fix this by only freeing spt in ppgtt_invalidate_spt in good case. > > > > Signed-off-by: Zheng Wang <hackerzheng666@gmail.com> > > --- > > drivers/gpu/drm/i915/gvt/gtt.c | 16 +++++++++------- > > 1 file changed, 9 insertions(+), 7 deletions(-) > > > > diff --git a/drivers/gpu/drm/i915/gvt/gtt.c b/drivers/gpu/drm/i915/gvt/gtt.c > > index ce0eb03709c3..550519f0acca 100644 > > --- a/drivers/gpu/drm/i915/gvt/gtt.c > > +++ b/drivers/gpu/drm/i915/gvt/gtt.c > > @@ -959,7 +959,7 @@ static inline int ppgtt_put_spt(struct > > intel_vgpu_ppgtt_spt *spt) > > return atomic_dec_return(&spt->refcount); > > } > > > > -static int ppgtt_invalidate_spt(struct intel_vgpu_ppgtt_spt *spt); > > +static int ppgtt_invalidate_spt(struct intel_vgpu_ppgtt_spt *spt, int > > is_error); > > > > static int ppgtt_invalidate_spt_by_shadow_entry(struct intel_vgpu *vgpu, > > struct intel_gvt_gtt_entry *e) > > @@ -995,7 +995,7 @@ static int > > ppgtt_invalidate_spt_by_shadow_entry(struct intel_vgpu *vgpu, > > Still line-wrapped and whitespace broken :( > ^ permalink raw reply [flat|nested] 50+ messages in thread
end of thread, other threads:[~2022-12-29 16:57 UTC | newest] Thread overview: 50+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2022-09-18 19:24 [PATCH] drm/i915/gvt: fix double-free bug in split_2MB_gtt_entry Zheng Wang 2022-09-19 9:30 ` Jani Nikula 2022-09-19 9:55 ` Zheng Hacker 2022-09-21 9:13 ` Zheng Hacker 2022-09-28 3:33 ` [PATCH] drm/i915/gvt: fix double free " Zheng Wang 2022-10-02 14:18 ` Greg KH 2022-10-03 4:36 ` Zheng Hacker 2022-10-06 16:58 ` [PATCH v2] " Zheng Wang 2022-10-06 19:23 ` Greg KH 2022-10-07 0:39 ` Zheng Hacker 2022-10-07 1:37 ` [PATCH v3] " Zheng Wang 2022-10-27 0:01 ` Dave Airlie 2022-10-27 3:26 ` Zheng Hacker 2022-10-27 5:12 ` Dave Airlie 2022-10-30 15:10 ` Zheng Hacker 2022-12-15 10:47 ` Joonas Lahtinen 2022-12-15 11:33 ` Wang, Zhi A 2022-12-15 13:26 ` Zheng Hacker 2022-12-19 7:57 ` [Intel-gfx] " Zheng Wang 2022-12-19 8:22 ` Wang, Zhi A 2022-12-19 9:21 ` Zheng Wang 2022-12-19 12:46 ` [PATCH v4] [PATCH v4] " Zheng Wang 2022-12-19 12:52 ` [RESEND PATCH " Zheng Wang 2022-12-20 8:22 ` Zhenyu Wang 2022-12-20 9:03 ` Zheng Hacker 2022-12-20 9:40 ` [PATCH v5] " Zheng Wang 2022-12-21 2:58 ` Zhenyu Wang 2022-12-21 5:01 ` Zheng Hacker 2022-12-29 16:56 ` [PATCH v6] " Zheng Wang [not found] <tencent_E1BBF05904DFB73C478DCD592740AAE0780A@qq.com> 2022-09-05 4:47 ` [PATCH] drm/i915/gvt: fix double-free " Zheng Hacker 2022-09-05 6:11 ` Zheng Hacker 2022-09-05 7:35 ` Zheng Hacker 2022-09-05 7:46 ` Zheng Hacker 2022-09-05 8:04 ` Greg KH 2022-09-05 8:53 ` Alex Young 2022-09-06 11:36 ` Zheng Hacker 2022-09-07 3:07 ` Zhenyu Wang 2022-09-07 6:47 ` Zheng Hacker 2022-09-08 9:09 ` Zheng Hacker 2022-09-08 9:19 ` Greg KH 2022-09-08 11:59 ` Zheng Hacker 2022-09-16 6:39 ` Zheng Hacker 2022-09-16 6:40 ` Zheng Hacker 2022-09-16 8:25 ` Greg KH 2022-09-16 15:21 ` Zheng Hacker 2022-09-16 15:54 ` Zheng Hacker 2022-09-17 9:08 ` Greg KH 2022-09-17 9:10 ` Zheng Hacker 2022-09-18 17:08 ` =?gb18030?B?s68=?= 2022-09-18 17:17 ` Zheng Hacker
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).