diff options
author | Xi Wang <xi.wang@gmail.com> | 2011-11-28 12:25:43 +0100 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2011-12-02 10:49:41 +0000 |
commit | bab9efc206ba89766c53a9042eb771e87e68c42b (patch) | |
tree | 7413fe6517587d631fca96960ec806d5e8b7e61a /drivers | |
parent | f3a71df05082c84d1408129084736c5f742a6165 (diff) |
vmwgfx: integer overflow in vmw_kms_update_layout_ioctl()
There are two issues in vmw_kms_update_layout_ioctl(). First, the
for loop forgets to index rects and only checks the first element.
Second, there is a potential integer overflow if userspace passes
in a large arg->num_outputs. The call to kzalloc() would allocate
a small buffer, leading to out-of-bounds read.
Reported-by: Haogang Chen <haogangchen@gmail.com>
Signed-off-by: Xi Wang <xi.wang@gmail.com>
Signed-off-by: Thomas Hellstrom <thellstrom@vmware.com>
Signed-off-by: Dave Airlie <airlied@redhat.com>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/gpu/drm/vmwgfx/vmwgfx_kms.c | 11 |
1 files changed, 6 insertions, 5 deletions
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c index 880e285d7578..37d40545ed77 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c @@ -1809,7 +1809,8 @@ int vmw_kms_update_layout_ioctl(struct drm_device *dev, void *data, } rects_size = arg->num_outputs * sizeof(struct drm_vmw_rect); - rects = kzalloc(rects_size, GFP_KERNEL); + rects = kcalloc(arg->num_outputs, sizeof(struct drm_vmw_rect), + GFP_KERNEL); if (unlikely(!rects)) { ret = -ENOMEM; goto out_unlock; @@ -1824,10 +1825,10 @@ int vmw_kms_update_layout_ioctl(struct drm_device *dev, void *data, } for (i = 0; i < arg->num_outputs; ++i) { - if (rects->x < 0 || - rects->y < 0 || - rects->x + rects->w > mode_config->max_width || - rects->y + rects->h > mode_config->max_height) { + if (rects[i].x < 0 || + rects[i].y < 0 || + rects[i].x + rects[i].w > mode_config->max_width || + rects[i].y + rects[i].h > mode_config->max_height) { DRM_ERROR("Invalid GUI layout.\n"); ret = -EINVAL; goto out_free; |