Message ID | 20230208180050.2093426-1-zack@kde.org (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | drm/vmwgfx: Stop accessing buffer objects which failed init | expand |
On 2/8/23 10:00, Zack Rusin wrote: > From: Zack Rusin <zackr@vmware.com> > > ttm_bo_init_reserved on failure puts the buffer object back which > causes it to be deleted, but kfree was still being called on the same > buffer in vmw_bo_create leading to a double free. > > After the double free the vmw_gem_object_create_with_handle was > setting the gem function objects before checking the return status > of vmw_bo_create leading to null pointer access. > > Fix the entire path by relaying on ttm_bo_init_reserved to delete the > buffer objects on failure and making sure the return status is checked > before setting the gem function objects on the buffer object. > > Signed-off-by: Zack Rusin <zackr@vmware.com> > Fixes: 8afa13a0583f ("drm/vmwgfx: Implement DRIVER_GEM") > Cc: <stable@vger.kernel.org> # v5.17+ > --- > drivers/gpu/drm/vmwgfx/vmwgfx_bo.c | 4 +++- > drivers/gpu/drm/vmwgfx/vmwgfx_gem.c | 4 ++-- > 2 files changed, 5 insertions(+), 3 deletions(-) > > diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_bo.c b/drivers/gpu/drm/vmwgfx/vmwgfx_bo.c > index 63486802c8fd..43ffa5c7acbd 100644 > --- a/drivers/gpu/drm/vmwgfx/vmwgfx_bo.c > +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_bo.c > @@ -431,13 +431,15 @@ int vmw_bo_create(struct vmw_private *vmw, > return -ENOMEM; > } > > + /* > + * vmw_bo_init will delete the *p_bo object if it fails > + */ > ret = vmw_bo_init(vmw, *p_bo, params, vmw_bo_free); > if (unlikely(ret != 0)) > goto out_error; > > return ret; > out_error: > - kfree(*p_bo); > *p_bo = NULL; > return ret; > } > diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_gem.c b/drivers/gpu/drm/vmwgfx/vmwgfx_gem.c > index f042e22b8b59..51bd1f8c5cc4 100644 > --- a/drivers/gpu/drm/vmwgfx/vmwgfx_gem.c > +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_gem.c > @@ -127,11 +127,11 @@ int vmw_gem_object_create_with_handle(struct vmw_private *dev_priv, > }; > > ret = vmw_bo_create(dev_priv, ¶ms, p_vbo); > - > - (*p_vbo)->tbo.base.funcs = &vmw_gem_object_funcs; > if (ret != 0) > goto out_no_bo; > > + (*p_vbo)->tbo.base.funcs = &vmw_gem_object_funcs; > + > ret = drm_gem_handle_create(filp, &(*p_vbo)->tbo.base, handle); > /* drop reference from allocate - handle holds it now */ > drm_gem_object_put(&(*p_vbo)->tbo.base); LGTM! Reviewed-by: Maaz Mombasawala <mombasawalam@vmware.com>
From: Martin Krastev <krastevm@vmware.com> Much nicer now. Reviewed-by: Martin Krastev <krastevm@vmware.com> Regards, Martin On 8.02.23 г. 20:00 ч., Zack Rusin wrote: > From: Zack Rusin <zackr@vmware.com> > > ttm_bo_init_reserved on failure puts the buffer object back which > causes it to be deleted, but kfree was still being called on the same > buffer in vmw_bo_create leading to a double free. > > After the double free the vmw_gem_object_create_with_handle was > setting the gem function objects before checking the return status > of vmw_bo_create leading to null pointer access. > > Fix the entire path by relaying on ttm_bo_init_reserved to delete the > buffer objects on failure and making sure the return status is checked > before setting the gem function objects on the buffer object. > > Signed-off-by: Zack Rusin <zackr@vmware.com> > Fixes: 8afa13a0583f ("drm/vmwgfx: Implement DRIVER_GEM") > Cc: <stable@vger.kernel.org> # v5.17+ > --- > drivers/gpu/drm/vmwgfx/vmwgfx_bo.c | 4 +++- > drivers/gpu/drm/vmwgfx/vmwgfx_gem.c | 4 ++-- > 2 files changed, 5 insertions(+), 3 deletions(-) > > diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_bo.c b/drivers/gpu/drm/vmwgfx/vmwgfx_bo.c > index 63486802c8fd..43ffa5c7acbd 100644 > --- a/drivers/gpu/drm/vmwgfx/vmwgfx_bo.c > +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_bo.c > @@ -431,13 +431,15 @@ int vmw_bo_create(struct vmw_private *vmw, > return -ENOMEM; > } > > + /* > + * vmw_bo_init will delete the *p_bo object if it fails > + */ > ret = vmw_bo_init(vmw, *p_bo, params, vmw_bo_free); > if (unlikely(ret != 0)) > goto out_error; > > return ret; > out_error: > - kfree(*p_bo); > *p_bo = NULL; > return ret; > } > diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_gem.c b/drivers/gpu/drm/vmwgfx/vmwgfx_gem.c > index f042e22b8b59..51bd1f8c5cc4 100644 > --- a/drivers/gpu/drm/vmwgfx/vmwgfx_gem.c > +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_gem.c > @@ -127,11 +127,11 @@ int vmw_gem_object_create_with_handle(struct vmw_private *dev_priv, > }; > > ret = vmw_bo_create(dev_priv, ¶ms, p_vbo); > - > - (*p_vbo)->tbo.base.funcs = &vmw_gem_object_funcs; > if (ret != 0) > goto out_no_bo; > > + (*p_vbo)->tbo.base.funcs = &vmw_gem_object_funcs; > + > ret = drm_gem_handle_create(filp, &(*p_vbo)->tbo.base, handle); > /* drop reference from allocate - handle holds it now */ > drm_gem_object_put(&(*p_vbo)->tbo.base);
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_bo.c b/drivers/gpu/drm/vmwgfx/vmwgfx_bo.c index 63486802c8fd..43ffa5c7acbd 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_bo.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_bo.c @@ -431,13 +431,15 @@ int vmw_bo_create(struct vmw_private *vmw, return -ENOMEM; } + /* + * vmw_bo_init will delete the *p_bo object if it fails + */ ret = vmw_bo_init(vmw, *p_bo, params, vmw_bo_free); if (unlikely(ret != 0)) goto out_error; return ret; out_error: - kfree(*p_bo); *p_bo = NULL; return ret; } diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_gem.c b/drivers/gpu/drm/vmwgfx/vmwgfx_gem.c index f042e22b8b59..51bd1f8c5cc4 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_gem.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_gem.c @@ -127,11 +127,11 @@ int vmw_gem_object_create_with_handle(struct vmw_private *dev_priv, }; ret = vmw_bo_create(dev_priv, ¶ms, p_vbo); - - (*p_vbo)->tbo.base.funcs = &vmw_gem_object_funcs; if (ret != 0) goto out_no_bo; + (*p_vbo)->tbo.base.funcs = &vmw_gem_object_funcs; + ret = drm_gem_handle_create(filp, &(*p_vbo)->tbo.base, handle); /* drop reference from allocate - handle holds it now */ drm_gem_object_put(&(*p_vbo)->tbo.base);