drm/i915: Fix vmap_batch page iterator overrun
authorMika Kuoppala <mika.kuoppala@linux.intel.com>
Fri, 13 Mar 2015 13:21:53 +0000 (15:21 +0200)
committerDaniel Vetter <daniel.vetter@ffwll.ch>
Tue, 17 Mar 2015 21:30:31 +0000 (22:30 +0100)
vmap_batch() calculates amount of needed pages for the mapping
we are going to create. And it uses this page count as an
argument for the for_each_sg_pages() macro. The macro takes the number
of sg list entities as an argument, not the page count. So we ended
up iterating through all the pages on the mapped object, corrupting
memory past the smaller pages[] array.

Fix this by bailing out when we have enough pages.

This regression has been introduced in

commit 17cabf571e50677d980e9ab2a43c5f11213003ae
Author: Chris Wilson <chris@chris-wilson.co.uk>
Date:   Wed Jan 14 11:20:57 2015 +0000

    drm/i915: Trim the command parser allocations

Cc: Chris Wilson <chris@chris-wilson.co.uk>
Signed-off-by: Mika Kuoppala <mika.kuoppala@intel.com>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
drivers/gpu/drm/i915/i915_cmd_parser.c

index 9a6da3536ae521a04158ef7fbfe5facf4f35ad51..61ae8ff4eaed990d0f21b57b6d0490ca8b3c83d1 100644 (file)
@@ -836,8 +836,11 @@ static u32 *vmap_batch(struct drm_i915_gem_object *obj,
        }
 
        i = 0;
-       for_each_sg_page(obj->pages->sgl, &sg_iter, npages, first_page)
+       for_each_sg_page(obj->pages->sgl, &sg_iter, obj->pages->nents, first_page) {
                pages[i++] = sg_page_iter_page(&sg_iter);
+               if (i == npages)
+                       break;
+       }
 
        addr = vmap(pages, i, 0, PAGE_KERNEL);
        if (addr == NULL) {