[PATCH v2 2/2] drm/i915: fix integer overflow in i915_gem_do_execbuffer()

2012-04-23 Thread Xi Wang
On 32-bit systems, a large args->num_cliprects from userspace via ioctl
may overflow the allocation size, leading to out-of-bounds access.

This vulnerability was introduced in commit 432e58ed ("drm/i915: Avoid
allocation for execbuffer object list").

Signed-off-by: Xi Wang 
Cc: Chris Wilson 
Cc: stable at vger.kernel.org
---
 drivers/gpu/drm/i915/i915_gem_execbuffer.c |5 +
 1 files changed, 5 insertions(+), 0 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c 
b/drivers/gpu/drm/i915/i915_gem_execbuffer.c
index 7c50e58..de43194 100644
--- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c
+++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c
@@ -1133,6 +1133,11 @@ i915_gem_do_execbuffer(struct drm_device *dev, void 
*data,
return -EINVAL;
}

+   if (args->num_cliprects > UINT_MAX / sizeof(*cliprects)) {
+   DRM_DEBUG("execbuf with %u cliprects\n",
+ args->num_cliprects);
+   return -EINVAL;
+   }
cliprects = kmalloc(args->num_cliprects * sizeof(*cliprects),
GFP_KERNEL);
if (cliprects == NULL) {
-- 
1.7.5.4



[PATCH v2 1/2] drm/i915: fix integer overflow in i915_gem_execbuffer2()

2012-04-23 Thread Xi Wang
On 32-bit systems, a large args->buffer_count from userspace via ioctl
may overflow the allocation size, leading to out-of-bounds access.

This vulnerability was introduced in commit 8408c282 ("drm/i915:
First try a normal large kmalloc for the temporary exec buffers").

Signed-off-by: Xi Wang 
Cc: Chris Wilson 
Cc: stable at vger.kernel.org
---
 drivers/gpu/drm/i915/i915_gem_execbuffer.c |3 ++-
 1 files changed, 2 insertions(+), 1 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c 
b/drivers/gpu/drm/i915/i915_gem_execbuffer.c
index f51a696..7c50e58 100644
--- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c
+++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c
@@ -1404,7 +1404,8 @@ i915_gem_execbuffer2(struct drm_device *dev, void *data,
struct drm_i915_gem_exec_object2 *exec2_list = NULL;
int ret;

-   if (args->buffer_count < 1) {
+   if (args->buffer_count < 1 ||
+   args->buffer_count > UINT_MAX / sizeof(*exec2_list)) {
DRM_DEBUG("execbuf2 with %d buffers\n", args->buffer_count);
return -EINVAL;
}
-- 
1.7.5.4



[PATCH v2 1/2] drm/i915: fix integer overflow in i915_gem_execbuffer2()

2012-04-23 Thread Xi Wang
On 32-bit systems, a large args-buffer_count from userspace via ioctl
may overflow the allocation size, leading to out-of-bounds access.

This vulnerability was introduced in commit 8408c282 (drm/i915:
First try a normal large kmalloc for the temporary exec buffers).

Signed-off-by: Xi Wang xi.w...@gmail.com
Cc: Chris Wilson ch...@chris-wilson.co.uk
Cc: sta...@vger.kernel.org
---
 drivers/gpu/drm/i915/i915_gem_execbuffer.c |3 ++-
 1 files changed, 2 insertions(+), 1 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c 
b/drivers/gpu/drm/i915/i915_gem_execbuffer.c
index f51a696..7c50e58 100644
--- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c
+++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c
@@ -1404,7 +1404,8 @@ i915_gem_execbuffer2(struct drm_device *dev, void *data,
struct drm_i915_gem_exec_object2 *exec2_list = NULL;
int ret;
 
-   if (args-buffer_count  1) {
+   if (args-buffer_count  1 ||
+   args-buffer_count  UINT_MAX / sizeof(*exec2_list)) {
DRM_DEBUG(execbuf2 with %d buffers\n, args-buffer_count);
return -EINVAL;
}
-- 
1.7.5.4

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v2 2/2] drm/i915: fix integer overflow in i915_gem_do_execbuffer()

2012-04-23 Thread Xi Wang
On 32-bit systems, a large args-num_cliprects from userspace via ioctl
may overflow the allocation size, leading to out-of-bounds access.

This vulnerability was introduced in commit 432e58ed (drm/i915: Avoid
allocation for execbuffer object list).

Signed-off-by: Xi Wang xi.w...@gmail.com
Cc: Chris Wilson ch...@chris-wilson.co.uk
Cc: sta...@vger.kernel.org
---
 drivers/gpu/drm/i915/i915_gem_execbuffer.c |5 +
 1 files changed, 5 insertions(+), 0 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c 
b/drivers/gpu/drm/i915/i915_gem_execbuffer.c
index 7c50e58..de43194 100644
--- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c
+++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c
@@ -1133,6 +1133,11 @@ i915_gem_do_execbuffer(struct drm_device *dev, void 
*data,
return -EINVAL;
}
 
+   if (args-num_cliprects  UINT_MAX / sizeof(*cliprects)) {
+   DRM_DEBUG(execbuf with %u cliprects\n,
+ args-num_cliprects);
+   return -EINVAL;
+   }
cliprects = kmalloc(args-num_cliprects * sizeof(*cliprects),
GFP_KERNEL);
if (cliprects == NULL) {
-- 
1.7.5.4

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH] drm/savage: fix integer overflows in savage_bci_cmdbuf()

2012-04-06 Thread Xi Wang
Since cmdbuf->size and cmdbuf->nbox are from userspace, a large value
would overflow the allocation size, leading to out-of-bounds access.

Signed-off-by: Xi Wang 
---
 drivers/gpu/drm/savage/savage_state.c |6 +++---
 1 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/savage/savage_state.c 
b/drivers/gpu/drm/savage/savage_state.c
index 031aaaf..b6d8608 100644
--- a/drivers/gpu/drm/savage/savage_state.c
+++ b/drivers/gpu/drm/savage/savage_state.c
@@ -988,7 +988,7 @@ int savage_bci_cmdbuf(struct drm_device *dev, void *data, 
struct drm_file *file_
 * for locking on FreeBSD.
 */
if (cmdbuf->size) {
-   kcmd_addr = kmalloc(cmdbuf->size * 8, GFP_KERNEL);
+   kcmd_addr = kmalloc_array(cmdbuf->size, 8, GFP_KERNEL);
if (kcmd_addr == NULL)
return -ENOMEM;

@@ -1015,8 +1015,8 @@ int savage_bci_cmdbuf(struct drm_device *dev, void *data, 
struct drm_file *file_
cmdbuf->vb_addr = kvb_addr;
}
if (cmdbuf->nbox) {
-   kbox_addr = kmalloc(cmdbuf->nbox * sizeof(struct drm_clip_rect),
-   GFP_KERNEL);
+   kbox_addr = kmalloc_array(cmdbuf->nbox, sizeof(struct 
drm_clip_rect),
+ GFP_KERNEL);
if (kbox_addr == NULL) {
ret = -ENOMEM;
goto done;
-- 
1.7.5.4



[PATCH 1/2] drm/i915: fix integer overflow in i915_gem_execbuffer2()

2012-04-06 Thread Xi Wang
On Apr 6, 2012, at 3:40 PM, Chris Wilson wrote:
> On Fri, 6 Apr 2012 14:17:41 -0400, Xi Wang  wrote:
>> 
>> Why an attempt to vmalloc?  The overflow check in drm_malloc_ab()
>> will simply return NULL and fail the ioctl with -ENOMEM.
> 
> It's an invalid value for the ioctl and should be treated as such, not
> making ENOMEM more ambiguous.

We could copy and paste the overflow check so as to return -EINVAL.
I just doubt how much that would help --- you can find existing usages
in other functions, for example, in i915_gem_execbuffer():

  /* Copy in the exec list from userland */
  exec_list = drm_malloc_ab(sizeof(*exec_list), args->buffer_count);
  exec2_list = drm_malloc_ab(sizeof(*exec2_list), args->buffer_count);
  if (exec_list == NULL || exec2_list == NULL) {
  DRM_DEBUG("Failed to allocate exec list for %d buffers\n",
args->buffer_count);
  drm_free_large(exec_list);
  drm_free_large(exec2_list);
  return -ENOMEM;
  }

Should we fix all these as well by repeating the checks and returning
-EINVAL?  I am worried about the code bloat / readability price you
would pay for getting a different error code.

BTW, I've also seen code using E2BIG.  Any documented guideline?

- xi



[PATCH 1/2] drm/i915: fix integer overflow in i915_gem_execbuffer2()

2012-04-06 Thread Xi Wang
On Apr 6, 2012, at 10:44 AM, Chris Wilson wrote:

> That I agreed with, I just disagree with how you chose to handle it.
> Rather than continue on and attempt to vmalloc a large array we should
> just fail the ioctl with EINVAL.

Why an attempt to vmalloc?  The overflow check in drm_malloc_ab()
will simply return NULL and fail the ioctl with -ENOMEM.

- xi



[PATCH 1/2] drm/i915: fix integer overflow in i915_gem_execbuffer2()

2012-04-06 Thread Xi Wang
On Apr 6, 2012, at 9:54 AM, Chris Wilson wrote:

> On Fri, 6 Apr 2012 09:46:46 -0400, Xi Wang  wrote:
>> On Apr 6, 2012, at 9:36 AM, Chris Wilson wrote:
>> 
>>> On Fri,  6 Apr 2012 08:58:18 -0400, Xi Wang  wrote:
>>>> A large args->buffer_count from userspace may overflow the allocation
>>>> size, leading to out-of-bounds access.
>>>> 
>>>> Use kmalloc_array() to avoid that.
>>> 
>>> I can safely say that exec list larger than 4GiB is going to be an
>>> illegal operation and would rather the ioctl failed outright with
>>> EINVAL.
>> 
>> On 32-bit platform?
> 
> On any platform. The largest it can legally be is a few tens of megabytes.

IDGI.  First we come to i915_gem_execbuffer2() from ioctl:

  exec2_list = kmalloc(sizeof(*exec2_list)*args->buffer_count, ...);

args->buffer_count is passed from userspace so it can be any value.
Let it overflow the 32-bit multiplication and turn the call to:

  exec2_list = kmalloc(0, ...);

Then the subsequent call to i915_gem_do_execbuffer(..., exec2_list)
may read exec2_list, which is out of bounds.

- xi



[PATCH 1/2] drm/i915: fix integer overflow in i915_gem_execbuffer2()

2012-04-06 Thread Xi Wang
On Apr 6, 2012, at 9:36 AM, Chris Wilson wrote:

> On Fri,  6 Apr 2012 08:58:18 -0400, Xi Wang  wrote:
>> A large args->buffer_count from userspace may overflow the allocation
>> size, leading to out-of-bounds access.
>> 
>> Use kmalloc_array() to avoid that.
> 
> I can safely say that exec list larger than 4GiB is going to be an
> illegal operation and would rather the ioctl failed outright with
> EINVAL.

On 32-bit platform?

- xi


[PATCH 2/2] drm/i915: fix integer overflow in i915_gem_do_execbuffer()

2012-04-06 Thread Xi Wang
A large args->num_cliprects from userspace may overflow the allocation
size, leading to out-of-bounds access.

| i915_gem_do_execbuffer()
| i915_gem_execbuffer()

Use kmalloc_array() to avoid that.

Signed-off-by: Xi Wang 
---
 drivers/gpu/drm/i915/i915_gem_execbuffer.c |4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c 
b/drivers/gpu/drm/i915/i915_gem_execbuffer.c
index 19962bd..607be3d 100644
--- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c
+++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c
@@ -1133,8 +1133,8 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data,
return -EINVAL;
}

-   cliprects = kmalloc(args->num_cliprects * sizeof(*cliprects),
-   GFP_KERNEL);
+   cliprects = kmalloc_array(args->num_cliprects, 
sizeof(*cliprects),
+ GFP_KERNEL);
if (cliprects == NULL) {
ret = -ENOMEM;
goto pre_mutex_err;
-- 
1.7.5.4



[PATCH 1/2] drm/i915: fix integer overflow in i915_gem_execbuffer2()

2012-04-06 Thread Xi Wang
A large args->buffer_count from userspace may overflow the allocation
size, leading to out-of-bounds access.

Use kmalloc_array() to avoid that.

Signed-off-by: Xi Wang 
---
 drivers/gpu/drm/i915/i915_gem_execbuffer.c |4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c 
b/drivers/gpu/drm/i915/i915_gem_execbuffer.c
index f51a696..19962bd 100644
--- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c
+++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c
@@ -1409,8 +1409,8 @@ i915_gem_execbuffer2(struct drm_device *dev, void *data,
return -EINVAL;
}

-   exec2_list = kmalloc(sizeof(*exec2_list)*args->buffer_count,
-GFP_KERNEL | __GFP_NOWARN | __GFP_NORETRY);
+   exec2_list = kmalloc_array(args->buffer_count, sizeof(*exec2_list),
+  GFP_KERNEL | __GFP_NOWARN | __GFP_NORETRY);
if (exec2_list == NULL)
exec2_list = drm_malloc_ab(sizeof(*exec2_list),
   args->buffer_count);
-- 
1.7.5.4



[PATCH 1/2] drm/i915: fix integer overflow in i915_gem_execbuffer2()

2012-04-06 Thread Xi Wang
A large args-buffer_count from userspace may overflow the allocation
size, leading to out-of-bounds access.

Use kmalloc_array() to avoid that.

Signed-off-by: Xi Wang xi.w...@gmail.com
---
 drivers/gpu/drm/i915/i915_gem_execbuffer.c |4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c 
b/drivers/gpu/drm/i915/i915_gem_execbuffer.c
index f51a696..19962bd 100644
--- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c
+++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c
@@ -1409,8 +1409,8 @@ i915_gem_execbuffer2(struct drm_device *dev, void *data,
return -EINVAL;
}
 
-   exec2_list = kmalloc(sizeof(*exec2_list)*args-buffer_count,
-GFP_KERNEL | __GFP_NOWARN | __GFP_NORETRY);
+   exec2_list = kmalloc_array(args-buffer_count, sizeof(*exec2_list),
+  GFP_KERNEL | __GFP_NOWARN | __GFP_NORETRY);
if (exec2_list == NULL)
exec2_list = drm_malloc_ab(sizeof(*exec2_list),
   args-buffer_count);
-- 
1.7.5.4

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH 2/2] drm/i915: fix integer overflow in i915_gem_do_execbuffer()

2012-04-06 Thread Xi Wang
A large args-num_cliprects from userspace may overflow the allocation
size, leading to out-of-bounds access.

| i915_gem_do_execbuffer()
| i915_gem_execbuffer()

Use kmalloc_array() to avoid that.

Signed-off-by: Xi Wang xi.w...@gmail.com
---
 drivers/gpu/drm/i915/i915_gem_execbuffer.c |4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c 
b/drivers/gpu/drm/i915/i915_gem_execbuffer.c
index 19962bd..607be3d 100644
--- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c
+++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c
@@ -1133,8 +1133,8 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data,
return -EINVAL;
}
 
-   cliprects = kmalloc(args-num_cliprects * sizeof(*cliprects),
-   GFP_KERNEL);
+   cliprects = kmalloc_array(args-num_cliprects, 
sizeof(*cliprects),
+ GFP_KERNEL);
if (cliprects == NULL) {
ret = -ENOMEM;
goto pre_mutex_err;
-- 
1.7.5.4

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: [PATCH 1/2] drm/i915: fix integer overflow in i915_gem_execbuffer2()

2012-04-06 Thread Xi Wang
On Apr 6, 2012, at 10:44 AM, Chris Wilson wrote:

 That I agreed with, I just disagree with how you chose to handle it.
 Rather than continue on and attempt to vmalloc a large array we should
 just fail the ioctl with EINVAL.

Why an attempt to vmalloc?  The overflow check in drm_malloc_ab()
will simply return NULL and fail the ioctl with -ENOMEM.

- xi

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: [PATCH 1/2] drm/i915: fix integer overflow in i915_gem_execbuffer2()

2012-04-06 Thread Xi Wang
On Apr 6, 2012, at 3:40 PM, Chris Wilson wrote:
 On Fri, 6 Apr 2012 14:17:41 -0400, Xi Wang xi.w...@gmail.com wrote:
 
 Why an attempt to vmalloc?  The overflow check in drm_malloc_ab()
 will simply return NULL and fail the ioctl with -ENOMEM.
 
 It's an invalid value for the ioctl and should be treated as such, not
 making ENOMEM more ambiguous.

We could copy and paste the overflow check so as to return -EINVAL.
I just doubt how much that would help --- you can find existing usages
in other functions, for example, in i915_gem_execbuffer():

  /* Copy in the exec list from userland */
  exec_list = drm_malloc_ab(sizeof(*exec_list), args-buffer_count);
  exec2_list = drm_malloc_ab(sizeof(*exec2_list), args-buffer_count);
  if (exec_list == NULL || exec2_list == NULL) {
  DRM_DEBUG(Failed to allocate exec list for %d buffers\n,
args-buffer_count);
  drm_free_large(exec_list);
  drm_free_large(exec2_list);
  return -ENOMEM;
  }

Should we fix all these as well by repeating the checks and returning
-EINVAL?  I am worried about the code bloat / readability price you
would pay for getting a different error code.

BTW, I've also seen code using E2BIG.  Any documented guideline?

- xi

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH] drm/savage: fix integer overflows in savage_bci_cmdbuf()

2012-04-06 Thread Xi Wang
Since cmdbuf-size and cmdbuf-nbox are from userspace, a large value
would overflow the allocation size, leading to out-of-bounds access.

Signed-off-by: Xi Wang xi.w...@gmail.com
---
 drivers/gpu/drm/savage/savage_state.c |6 +++---
 1 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/savage/savage_state.c 
b/drivers/gpu/drm/savage/savage_state.c
index 031aaaf..b6d8608 100644
--- a/drivers/gpu/drm/savage/savage_state.c
+++ b/drivers/gpu/drm/savage/savage_state.c
@@ -988,7 +988,7 @@ int savage_bci_cmdbuf(struct drm_device *dev, void *data, 
struct drm_file *file_
 * for locking on FreeBSD.
 */
if (cmdbuf-size) {
-   kcmd_addr = kmalloc(cmdbuf-size * 8, GFP_KERNEL);
+   kcmd_addr = kmalloc_array(cmdbuf-size, 8, GFP_KERNEL);
if (kcmd_addr == NULL)
return -ENOMEM;
 
@@ -1015,8 +1015,8 @@ int savage_bci_cmdbuf(struct drm_device *dev, void *data, 
struct drm_file *file_
cmdbuf-vb_addr = kvb_addr;
}
if (cmdbuf-nbox) {
-   kbox_addr = kmalloc(cmdbuf-nbox * sizeof(struct drm_clip_rect),
-   GFP_KERNEL);
+   kbox_addr = kmalloc_array(cmdbuf-nbox, sizeof(struct 
drm_clip_rect),
+ GFP_KERNEL);
if (kbox_addr == NULL) {
ret = -ENOMEM;
goto done;
-- 
1.7.5.4

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH -fixes] vmwgfx: fix incorrect VRAM size check in vmw_kms_fb_create()

2011-12-21 Thread Xi Wang
Commit e133e737 didn't correctly fix the integer overflow issue.

-   unsigned int required_size;
+   u64 required_size;
...
required_size = mode_cmd->pitch * mode_cmd->height;
-   if (unlikely(required_size > dev_priv->vram_size)) {
+   if (unlikely(required_size > (u64) dev_priv->vram_size)) {

Note that both pitch and height are u32.  Their product is still u32 and
would overflow before being assigned to required_size.  A correct way is
to convert pitch and height to u64 before the multiplication.

required_size = (u64)mode_cmd->pitch * (u64)mode_cmd->height;

This patch calls the existing vmw_kms_validate_mode_vram() for
validation.

Signed-off-by: Xi Wang 
---
 drivers/gpu/drm/vmwgfx/vmwgfx_kms.c |6 +++---
 1 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c 
b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
index 8aa1dbb..f94b33a 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
@@ -1093,7 +1093,6 @@ static struct drm_framebuffer *vmw_kms_fb_create(struct 
drm_device *dev,
struct vmw_surface *surface = NULL;
struct vmw_dma_buffer *bo = NULL;
struct ttm_base_object *user_obj;
-   u64 required_size;
int ret;

/**
@@ -1102,8 +1101,9 @@ static struct drm_framebuffer *vmw_kms_fb_create(struct 
drm_device *dev,
 * requested framebuffer.
 */

-   required_size = mode_cmd->pitch * mode_cmd->height;
-   if (unlikely(required_size > (u64) dev_priv->vram_size)) {
+   if (!vmw_kms_validate_mode_vram(dev_priv,
+   mode_cmd->pitch,
+   mode_cmd->height)) {
DRM_ERROR("VRAM size is too small for requested mode.\n");
return ERR_PTR(-ENOMEM);
}
-- 
1.7.5.4



[PATCH RESEND] vmwgfx: fix incorrect vram size check in vmw_kms_fb_create()

2011-12-21 Thread Xi Wang
On Dec 21, 2011, at 4:30 AM, David Airlie wrote:
> 
> This patch doesn't apply with git am, please regenerate it,
> 
> Thomas, can you ack as well please?
> 
> Is this for -fixes or -next?

Sorry this patch is for vmwgfx.git.  I will redo a version that can be applied 
to the mainline kernel.

- xi


[PATCH RESEND] vmwgfx: fix incorrect vram size check in vmw_kms_fb_create()

2011-12-21 Thread Xi Wang
The previous commit didn't correctly fix the integer overflow issue.

http://git.kernel.org/linus/e133e737

-   unsigned int required_size;
+   u64 required_size;
...
required_size = mode_cmd-pitch * mode_cmd-height;
-   if (unlikely(required_size  dev_priv-vram_size)) {
+   if (unlikely(required_size  (u64) dev_priv-vram_size)) {

Note that both pitch and height are u32, their product is still u32 and
would overflow before being assigned to required_size. A correct way is
to convert pitch and height to u64 before the multiplication.

required_size = (u64)mode_cmd-pitch * (u64)mode_cmd-height;

This patch calls an existing function vmw_kms_validate_mode_vram()
for validation.

Signed-off-by: Xi Wang xi.w...@gmail.com
---
 vmwgfx_kms.c |6 +++---
 1 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/vmwgfx_kms.c b/vmwgfx_kms.c
index b87afdf..6b8857e 100644
--- a/vmwgfx_kms.c
+++ b/vmwgfx_kms.c
@@ -1101,7 +1101,6 @@ static struct drm_framebuffer *vmw_kms_fb_create(struct 
drm_device *dev,
struct vmw_surface *surface = NULL;
struct vmw_dma_buffer *bo = NULL;
struct ttm_base_object *user_obj;
-   u64 required_size;
int ret;
 
/**
@@ -1110,8 +1109,9 @@ static struct drm_framebuffer *vmw_kms_fb_create(struct 
drm_device *dev,
 * requested framebuffer.
 */
 
-   required_size = mode_cmd-pitch * mode_cmd-height;
-   if (unlikely(required_size  (u64) dev_priv-vram_size)) {
+   if (!vmw_kms_validate_mode_vram(dev_priv,
+   mode_cmd-pitch,
+   mode_cmd-height)) {
DRM_ERROR(VRAM size is too small for requested mode.\n);
return ERR_PTR(-ENOMEM);
}
-- 
1.7.5.4

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: [PATCH RESEND] vmwgfx: fix incorrect vram size check in vmw_kms_fb_create()

2011-12-21 Thread Xi Wang
On Dec 21, 2011, at 4:30 AM, David Airlie wrote:
 
 This patch doesn't apply with git am, please regenerate it,
 
 Thomas, can you ack as well please?
 
 Is this for -fixes or -next?

Sorry this patch is for vmwgfx.git.  I will redo a version that can be applied 
to the mainline kernel.

- xi
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH -fixes] vmwgfx: fix incorrect VRAM size check in vmw_kms_fb_create()

2011-12-21 Thread Xi Wang
Commit e133e737 didn't correctly fix the integer overflow issue.

-   unsigned int required_size;
+   u64 required_size;
...
required_size = mode_cmd-pitch * mode_cmd-height;
-   if (unlikely(required_size  dev_priv-vram_size)) {
+   if (unlikely(required_size  (u64) dev_priv-vram_size)) {

Note that both pitch and height are u32.  Their product is still u32 and
would overflow before being assigned to required_size.  A correct way is
to convert pitch and height to u64 before the multiplication.

required_size = (u64)mode_cmd-pitch * (u64)mode_cmd-height;

This patch calls the existing vmw_kms_validate_mode_vram() for
validation.

Signed-off-by: Xi Wang xi.w...@gmail.com
---
 drivers/gpu/drm/vmwgfx/vmwgfx_kms.c |6 +++---
 1 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c 
b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
index 8aa1dbb..f94b33a 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
@@ -1093,7 +1093,6 @@ static struct drm_framebuffer *vmw_kms_fb_create(struct 
drm_device *dev,
struct vmw_surface *surface = NULL;
struct vmw_dma_buffer *bo = NULL;
struct ttm_base_object *user_obj;
-   u64 required_size;
int ret;
 
/**
@@ -1102,8 +1101,9 @@ static struct drm_framebuffer *vmw_kms_fb_create(struct 
drm_device *dev,
 * requested framebuffer.
 */
 
-   required_size = mode_cmd-pitch * mode_cmd-height;
-   if (unlikely(required_size  (u64) dev_priv-vram_size)) {
+   if (!vmw_kms_validate_mode_vram(dev_priv,
+   mode_cmd-pitch,
+   mode_cmd-height)) {
DRM_ERROR(VRAM size is too small for requested mode.\n);
return ERR_PTR(-ENOMEM);
}
-- 
1.7.5.4

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH RESEND] vmwgfx: fix incorrect vram size check in vmw_kms_fb_create()

2011-12-20 Thread Xi Wang
The previous commit didn't correctly fix the integer overflow issue.

http://git.kernel.org/linus/e133e737

-   unsigned int required_size;
+   u64 required_size;
...
required_size = mode_cmd->pitch * mode_cmd->height;
-   if (unlikely(required_size > dev_priv->vram_size)) {
+   if (unlikely(required_size > (u64) dev_priv->vram_size)) {

Note that both pitch and height are u32, their product is still u32 and
would overflow before being assigned to required_size. A correct way is
to convert pitch and height to u64 before the multiplication.

required_size = (u64)mode_cmd->pitch * (u64)mode_cmd->height;

This patch calls an existing function vmw_kms_validate_mode_vram()
for validation.

Signed-off-by: Xi Wang 
---
 vmwgfx_kms.c |6 +++---
 1 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/vmwgfx_kms.c b/vmwgfx_kms.c
index b87afdf..6b8857e 100644
--- a/vmwgfx_kms.c
+++ b/vmwgfx_kms.c
@@ -1101,7 +1101,6 @@ static struct drm_framebuffer *vmw_kms_fb_create(struct 
drm_device *dev,
struct vmw_surface *surface = NULL;
struct vmw_dma_buffer *bo = NULL;
struct ttm_base_object *user_obj;
-   u64 required_size;
int ret;

/**
@@ -1110,8 +1109,9 @@ static struct drm_framebuffer *vmw_kms_fb_create(struct 
drm_device *dev,
 * requested framebuffer.
 */

-   required_size = mode_cmd->pitch * mode_cmd->height;
-   if (unlikely(required_size > (u64) dev_priv->vram_size)) {
+   if (!vmw_kms_validate_mode_vram(dev_priv,
+   mode_cmd->pitch,
+   mode_cmd->height)) {
DRM_ERROR("VRAM size is too small for requested mode.\n");
return ERR_PTR(-ENOMEM);
}
-- 
1.7.5.4



[PATCH] drm/vmwgfx: fix incorrect VRAM size check in vmw_kms_fb_create()

2011-12-10 Thread Xi Wang
The commit e133e737 didn't correctly fix the overflow issue.

-   unsigned int required_size;
+   u64 required_size;
...
required_size = mode_cmd-pitch * mode_cmd-height;
-   if (unlikely(required_size  dev_priv-vram_size)) {
+   if (unlikely(required_size  (u64) dev_priv-vram_size)) {

Since pitch and height are u32, their product is still 32-bit and
would overflow.  Converting the result to u64 cannot help.  A correct
way is to convert pitch and height to u64 before the multiplication.

required_size = (u64)mode_cmd-pitch * (u64)mode_cmd-height;

This fix calls vmw_kms_validate_mode_vram() for validation.

Signed-off-by: Xi Wang xi.w...@gmail.com
Cc: Thomas Hellstrom thellst...@vmware.com
Cc: Dave Airlie airl...@redhat.com
---
 drivers/gpu/drm/vmwgfx/vmwgfx_kms.c |6 +++---
 1 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c 
b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
index 37d4054..582a4d7 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
@@ -1003,7 +1003,6 @@ static struct drm_framebuffer *vmw_kms_fb_create(struct 
drm_device *dev,
struct vmw_surface *surface = NULL;
struct vmw_dma_buffer *bo = NULL;
struct ttm_base_object *user_obj;
-   u64 required_size;
int ret;
 
/**
@@ -1012,8 +1011,9 @@ static struct drm_framebuffer *vmw_kms_fb_create(struct 
drm_device *dev,
 * requested framebuffer.
 */
 
-   required_size = mode_cmd-pitch * mode_cmd-height;
-   if (unlikely(required_size  (u64) dev_priv-vram_size)) {
+   if (!vmw_kms_validate_mode_vram(dev_priv,
+   mode_cmd-pitch,
+   mode_cmd-height)) {
DRM_ERROR(VRAM size is too small for requested mode.\n);
return ERR_PTR(-ENOMEM);
}
-- 
1.7.5.4

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH] drm/vmwgfx: fix incorrect VRAM size check in vmw_kms_fb_create()

2011-12-08 Thread Xi Wang
The commit e133e737 didn't correctly fix the overflow issue.

-   unsigned int required_size;
+   u64 required_size;
...
required_size = mode_cmd->pitch * mode_cmd->height;
-   if (unlikely(required_size > dev_priv->vram_size)) {
+   if (unlikely(required_size > (u64) dev_priv->vram_size)) {

Since pitch and height are u32, their product is still 32-bit and
would overflow.  Converting the result to u64 cannot help.  A correct
way is to convert pitch and height to u64 before the multiplication.

required_size = (u64)mode_cmd->pitch * (u64)mode_cmd->height;

This fix calls vmw_kms_validate_mode_vram() for validation.

Signed-off-by: Xi Wang 
Cc: Thomas Hellstrom 
Cc: Dave Airlie 
---
 drivers/gpu/drm/vmwgfx/vmwgfx_kms.c |6 +++---
 1 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c 
b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
index 37d4054..582a4d7 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
@@ -1003,7 +1003,6 @@ static struct drm_framebuffer *vmw_kms_fb_create(struct 
drm_device *dev,
struct vmw_surface *surface = NULL;
struct vmw_dma_buffer *bo = NULL;
struct ttm_base_object *user_obj;
-   u64 required_size;
int ret;

/**
@@ -1012,8 +1011,9 @@ static struct drm_framebuffer *vmw_kms_fb_create(struct 
drm_device *dev,
 * requested framebuffer.
 */

-   required_size = mode_cmd->pitch * mode_cmd->height;
-   if (unlikely(required_size > (u64) dev_priv->vram_size)) {
+   if (!vmw_kms_validate_mode_vram(dev_priv,
+   mode_cmd->pitch,
+   mode_cmd->height)) {
DRM_ERROR("VRAM size is too small for requested mode.\n");
return ERR_PTR(-ENOMEM);
}
-- 
1.7.5.4



vmwgfx: strange loop in vmw_kms_update_layout_ioctl()

2011-11-24 Thread Xi Wang
Hi,

I came across this code snippet at vmwgfx_kms.c:2000.  The loop variable i is 
never used and rects is checked again and again.  Should it be something like 
rects[i].x instead of rects->x?  Thanks.

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) {
DRM_ERROR("Invalid GUI layout.\n");
ret = -EINVAL;
goto out_free;
}
}

- xi


vmwgfx: strange loop in vmw_kms_update_layout_ioctl()

2011-11-24 Thread Xi Wang
Hi,

I came across this code snippet at vmwgfx_kms.c:2000.  The loop variable i is 
never used and rects is checked again and again.  Should it be something like 
rects[i].x instead of rects-x?  Thanks.

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) {
DRM_ERROR(Invalid GUI layout.\n);
ret = -EINVAL;
goto out_free;
}
}

- xi
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH] drm: integer overflow in drm_mode_dirtyfb_ioctl()

2011-11-23 Thread Xi Wang
There is a potential integer overflow in drm_mode_dirtyfb_ioctl()
if userspace passes in a large num_clips.  The call to kmalloc would
allocate a small buffer, and the call to fb->funcs->dirty may result
in a memory corruption.

Reported-by: Haogang Chen 
Signed-off-by: Xi Wang 
---
 drivers/gpu/drm/drm_crtc.c |4 
 include/drm/drm_mode.h |2 ++
 2 files changed, 6 insertions(+), 0 deletions(-)

diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
index 405c63b..8323fc3 100644
--- a/drivers/gpu/drm/drm_crtc.c
+++ b/drivers/gpu/drm/drm_crtc.c
@@ -1873,6 +1873,10 @@ int drm_mode_dirtyfb_ioctl(struct drm_device *dev,
}

if (num_clips && clips_ptr) {
+   if (num_clips < 0 || num_clips > DRM_MODE_FB_DIRTY_MAX_CLIPS) {
+   ret = -EINVAL;
+   goto out_err1;
+   }
clips = kzalloc(num_clips * sizeof(*clips), GFP_KERNEL);
if (!clips) {
ret = -ENOMEM;
diff --git a/include/drm/drm_mode.h b/include/drm/drm_mode.h
index d30bedf..ddd46db 100644
--- a/include/drm/drm_mode.h
+++ b/include/drm/drm_mode.h
@@ -235,6 +235,8 @@ struct drm_mode_fb_cmd {
 #define DRM_MODE_FB_DIRTY_ANNOTATE_FILL 0x02
 #define DRM_MODE_FB_DIRTY_FLAGS 0x03

+#define DRM_MODE_FB_DIRTY_MAX_CLIPS 256
+
 /*
  * Mark a region of a framebuffer as dirty.
  *
-- 
1.7.5.4



[PATCH] drm: integer overflow in drm_mode_dirtyfb_ioctl()

2011-11-22 Thread Xi Wang
There is a potential integer overflow in drm_mode_dirtyfb_ioctl()
if userspace passes in a large num_clips.  The call to kmalloc would
allocate a small buffer, and the call to fb-funcs-dirty may result
in a memory corruption.

Reported-by: Haogang Chen haogangc...@gmail.com
Signed-off-by: Xi Wang xi.w...@gmail.com
---
 drivers/gpu/drm/drm_crtc.c |4 
 include/drm/drm_mode.h |2 ++
 2 files changed, 6 insertions(+), 0 deletions(-)

diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
index 405c63b..8323fc3 100644
--- a/drivers/gpu/drm/drm_crtc.c
+++ b/drivers/gpu/drm/drm_crtc.c
@@ -1873,6 +1873,10 @@ int drm_mode_dirtyfb_ioctl(struct drm_device *dev,
}
 
if (num_clips  clips_ptr) {
+   if (num_clips  0 || num_clips  DRM_MODE_FB_DIRTY_MAX_CLIPS) {
+   ret = -EINVAL;
+   goto out_err1;
+   }
clips = kzalloc(num_clips * sizeof(*clips), GFP_KERNEL);
if (!clips) {
ret = -ENOMEM;
diff --git a/include/drm/drm_mode.h b/include/drm/drm_mode.h
index d30bedf..ddd46db 100644
--- a/include/drm/drm_mode.h
+++ b/include/drm/drm_mode.h
@@ -235,6 +235,8 @@ struct drm_mode_fb_cmd {
 #define DRM_MODE_FB_DIRTY_ANNOTATE_FILL 0x02
 #define DRM_MODE_FB_DIRTY_FLAGS 0x03
 
+#define DRM_MODE_FB_DIRTY_MAX_CLIPS 256
+
 /*
  * Mark a region of a framebuffer as dirty.
  *
-- 
1.7.5.4

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel