| From 8524757506a1f5f552a812de56d4e1811954dcdd Mon Sep 17 00:00:00 2001 |
| From: Daniel Vetter <daniel.vetter@ffwll.ch> |
| Date: Thu, 19 Sep 2013 14:00:11 +0200 |
| Subject: drm/i915: Use unsigned for overflow checks in execbuf |
| |
| There's actually no real risk since we already check for stricter |
| constraints earlier (using UINT_MAX / sizeof (struct |
| drm_i915_gem_exec_object2) as the limit). But in eb_create we use |
| signed integers, which steals a factor of 2. Luckily struct |
| drm_i915_gem_exec_object2 for this to not matter. |
| |
| Still, be consistent and use unsigned integers. |
| |
| Similar use unsinged integers when checking for overflows in the |
| relocation entry processing. |
| |
| I've also added a new subtests to igt/gem_reloc_overflow to also |
| test for overflowing args->buffer_count values. |
| |
| v2: Give the variables again tighter scope to make it clear that the |
| computation is purely local and doesn't leak out to the 2nd block. |
| Requested by Chris Wilson. |
| |
| Cc: Chris Wilson <chris@chris-wilson.co.uk> |
| Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk> |
| Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch> |
| (cherry picked from commit b205ca572159ab9a617fc96e4659bc138064ca8e) |
| Signed-off-by: Darren Hart <dvhart@linux.intel.com> |
| --- |
| drivers/gpu/drm/i915/i915_gem_execbuffer.c | 12 ++++++------ |
| 1 file changed, 6 insertions(+), 6 deletions(-) |
| |
| diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/i915_gem_execbuffer.c |
| index b87107e73c05..da23cfe3902b 100644 |
| --- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c |
| +++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c |
| @@ -48,15 +48,15 @@ eb_create(struct drm_i915_gem_execbuffer2 *args, struct i915_address_space *vm) |
| struct eb_vmas *eb = NULL; |
| |
| if (args->flags & I915_EXEC_HANDLE_LUT) { |
| - int size = args->buffer_count; |
| + unsigned size = args->buffer_count; |
| size *= sizeof(struct i915_vma *); |
| size += sizeof(struct eb_vmas); |
| eb = kmalloc(size, GFP_TEMPORARY | __GFP_NOWARN | __GFP_NORETRY); |
| } |
| |
| if (eb == NULL) { |
| - int size = args->buffer_count; |
| - int count = PAGE_SIZE / sizeof(struct hlist_head) / 2; |
| + unsigned size = args->buffer_count; |
| + unsigned count = PAGE_SIZE / sizeof(struct hlist_head) / 2; |
| BUILD_BUG_ON_NOT_POWER_OF_2(PAGE_SIZE / sizeof(struct hlist_head)); |
| while (count > 2*size) |
| count >>= 1; |
| @@ -667,7 +667,7 @@ i915_gem_execbuffer_relocate_slow(struct drm_device *dev, |
| bool need_relocs; |
| int *reloc_offset; |
| int i, total, ret; |
| - int count = args->buffer_count; |
| + unsigned count = args->buffer_count; |
| |
| if (WARN_ON(list_empty(&eb->vmas))) |
| return 0; |
| @@ -818,8 +818,8 @@ validate_exec_list(struct drm_i915_gem_exec_object2 *exec, |
| int count) |
| { |
| int i; |
| - int relocs_total = 0; |
| - int relocs_max = INT_MAX / sizeof(struct drm_i915_gem_relocation_entry); |
| + unsigned relocs_total = 0; |
| + unsigned relocs_max = UINT_MAX / sizeof(struct drm_i915_gem_relocation_entry); |
| |
| for (i = 0; i < count; i++) { |
| char __user *ptr = to_user_ptr(exec[i].relocs_ptr); |
| -- |
| 1.8.5.rc3 |
| |