Message ID | 1498145294-7974-3-git-send-email-stefan.bader@canonical.com |
---|---|
State | New |
Headers | show |
On 22/06/17 16:28, Stefan Bader wrote: > From: Sinclair Yeh <syeh@vmware.com> > > When vmw_gb_surface_define_ioctl() is called with an existing buffer, > we end up returning an uninitialized variable in the backup_handle. > > The fix is to first initialize backup_handle to 0 just to be sure, and > second, when a user-provided buffer is found, we will use the > req->buffer_handle as the backup_handle. > > Cc: <stable@vger.kernel.org> > Reported-by: Murray McAllister <murray.mcallister@insomniasec.com> > Signed-off-by: Sinclair Yeh <syeh@vmware.com> > Reviewed-by: Deepak Rawat <drawat@vmware.com> > > CVE-2017-9605 > > (cherry picked from commit 07678eca2cf9c9a18584e546c2b2a0d0c9a3150c) > Signed-off-by: Stefan Bader <stefan.bader@canonical.com> > --- > drivers/gpu/drm/vmwgfx/vmwgfx_surface.c | 18 +++++++++++------- > 1 file changed, 11 insertions(+), 7 deletions(-) > > diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c b/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c > index baf03d4..834bb10 100644 > --- a/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c > +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c > @@ -1274,7 +1274,7 @@ int vmw_gb_surface_define_ioctl(struct drm_device *dev, void *data, > struct ttm_object_file *tfile = vmw_fpriv(file_priv)->tfile; > int ret; > uint32_t size; > - uint32_t backup_handle; > + uint32_t backup_handle = 0; > > if (req->multisample_count != 0) > return -EINVAL; > @@ -1317,12 +1317,16 @@ int vmw_gb_surface_define_ioctl(struct drm_device *dev, void *data, > ret = vmw_user_dmabuf_lookup(tfile, req->buffer_handle, > &res->backup, > &user_srf->backup_base); > - if (ret == 0 && res->backup->base.num_pages * PAGE_SIZE < > - res->backup_size) { > - DRM_ERROR("Surface backup buffer is too small.\n"); > - vmw_dmabuf_unreference(&res->backup); > - ret = -EINVAL; > - goto out_unlock; > + if (ret == 0) { > + if (res->backup->base.num_pages * PAGE_SIZE < > + res->backup_size) { > + DRM_ERROR("Surface backup buffer is too small.\n"); > + vmw_dmabuf_unreference(&res->backup); > + ret = -EINVAL; > + goto out_unlock; > + } else { > + backup_handle = req->buffer_handle; > + } > } > } else if (req->drm_surface_flags & drm_vmw_surface_flag_create_buffer) > ret = vmw_user_dmabuf_alloc(dev_priv, tfile, > Cherry pick, looks good to me. Acked-by: Colin Ian King <colin.king@canonical.com>
On Thu, Jun 22, 2017 at 11:28 PM, Stefan Bader <stefan.bader@canonical.com> wrote: > From: Sinclair Yeh <syeh@vmware.com> > > When vmw_gb_surface_define_ioctl() is called with an existing buffer, > we end up returning an uninitialized variable in the backup_handle. > > The fix is to first initialize backup_handle to 0 just to be sure, and > second, when a user-provided buffer is found, we will use the > req->buffer_handle as the backup_handle. > > Cc: <stable@vger.kernel.org> > Reported-by: Murray McAllister <murray.mcallister@insomniasec.com> > Signed-off-by: Sinclair Yeh <syeh@vmware.com> > Reviewed-by: Deepak Rawat <drawat@vmware.com> > > CVE-2017-9605 > > (cherry picked from commit 07678eca2cf9c9a18584e546c2b2a0d0c9a3150c) > Signed-off-by: Stefan Bader <stefan.bader@canonical.com> +1 Acked-by: Po-Hsu Lin <po-hsu.lin@canonical.com> > --- > drivers/gpu/drm/vmwgfx/vmwgfx_surface.c | 18 +++++++++++------- > 1 file changed, 11 insertions(+), 7 deletions(-) > > diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c b/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c > index baf03d4..834bb10 100644 > --- a/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c > +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c > @@ -1274,7 +1274,7 @@ int vmw_gb_surface_define_ioctl(struct drm_device *dev, void *data, > struct ttm_object_file *tfile = vmw_fpriv(file_priv)->tfile; > int ret; > uint32_t size; > - uint32_t backup_handle; > + uint32_t backup_handle = 0; > > if (req->multisample_count != 0) > return -EINVAL; > @@ -1317,12 +1317,16 @@ int vmw_gb_surface_define_ioctl(struct drm_device *dev, void *data, > ret = vmw_user_dmabuf_lookup(tfile, req->buffer_handle, > &res->backup, > &user_srf->backup_base); > - if (ret == 0 && res->backup->base.num_pages * PAGE_SIZE < > - res->backup_size) { > - DRM_ERROR("Surface backup buffer is too small.\n"); > - vmw_dmabuf_unreference(&res->backup); > - ret = -EINVAL; > - goto out_unlock; > + if (ret == 0) { > + if (res->backup->base.num_pages * PAGE_SIZE < > + res->backup_size) { > + DRM_ERROR("Surface backup buffer is too small.\n"); > + vmw_dmabuf_unreference(&res->backup); > + ret = -EINVAL; > + goto out_unlock; > + } else { > + backup_handle = req->buffer_handle; > + } > } > } else if (req->drm_surface_flags & drm_vmw_surface_flag_create_buffer) > ret = vmw_user_dmabuf_alloc(dev_priv, tfile, > -- > 2.7.4 > > > -- > kernel-team mailing list > kernel-team@lists.ubuntu.com > https://lists.ubuntu.com/mailman/listinfo/kernel-team
Applied to yakkety and zesty master-next branches. Thanks. Cascardo.
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c b/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c index baf03d4..834bb10 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c @@ -1274,7 +1274,7 @@ int vmw_gb_surface_define_ioctl(struct drm_device *dev, void *data, struct ttm_object_file *tfile = vmw_fpriv(file_priv)->tfile; int ret; uint32_t size; - uint32_t backup_handle; + uint32_t backup_handle = 0; if (req->multisample_count != 0) return -EINVAL; @@ -1317,12 +1317,16 @@ int vmw_gb_surface_define_ioctl(struct drm_device *dev, void *data, ret = vmw_user_dmabuf_lookup(tfile, req->buffer_handle, &res->backup, &user_srf->backup_base); - if (ret == 0 && res->backup->base.num_pages * PAGE_SIZE < - res->backup_size) { - DRM_ERROR("Surface backup buffer is too small.\n"); - vmw_dmabuf_unreference(&res->backup); - ret = -EINVAL; - goto out_unlock; + if (ret == 0) { + if (res->backup->base.num_pages * PAGE_SIZE < + res->backup_size) { + DRM_ERROR("Surface backup buffer is too small.\n"); + vmw_dmabuf_unreference(&res->backup); + ret = -EINVAL; + goto out_unlock; + } else { + backup_handle = req->buffer_handle; + } } } else if (req->drm_surface_flags & drm_vmw_surface_flag_create_buffer) ret = vmw_user_dmabuf_alloc(dev_priv, tfile,