Currently, userspace fail to obtain the SAREA mapping (among others) because
they pass SAREA_MAX to drmAddMap without aligning it to the page size. This
breaks for example on PowerPC with 64K pages and radeon despite the kernel
radeon actually doing the right rouding in the first place.

The way SAREA_MAX is defined with a bunch of ifdef's and duplicated between
libdrm and the X server is gross, ultimately it should be retrieved by
userspace from the kernel, but in the meantime, we have plenty of existing
userspace built with bad values that need to work.

This works around it by rounding the requested size in drm_addmap_core() of
any SHM map to the page size. Since those maps backing memory is allocated
within addmap_core, there is no security issue involved, the only side effect
is that drivers that previous tries to create or access SHM maps using
a size < PAGE_SIZE and would have failed (-EINVAL) will no succeed at the
cost of a little bit more memory used if that happens to be when the map is
created.

Signed-off-by: Benjamin Herrenschmidt <b...@kernel.crashing.org>
---

That replaces my previous attempt. This is safer and cleaner and still
fixes the radeon problem. Other drivers having other type of maps with
incorrect sizes will need proper fixes but they did anyway.

Index: linux-work/drivers/gpu/drm/drm_bufs.c
===================================================================
--- linux-work.orig/drivers/gpu/drm/drm_bufs.c  2009-05-18 10:50:04.000000000 
+1000
+++ linux-work/drivers/gpu/drm/drm_bufs.c       2009-05-18 11:47:25.000000000 
+1000
@@ -170,6 +170,14 @@ static int drm_addmap_core(struct drm_de
        }
        DRM_DEBUG("offset = 0x%08llx, size = 0x%08lx, type = %d\n",
                  (unsigned long long)map->offset, map->size, map->type);
+
+       /* page-align _DRM_SHM maps. They are allocated here so there is no 
security
+        * hole created by that and it works around various broken drivers that 
use
+        * a non-aligned quantity to map the SAREA. --BenH
+        */
+       if (map->type == _DRM_SHM)
+               map->size = PAGE_ALIGN(map->size);
+
        if ((map->offset & (~(resource_size_t)PAGE_MASK)) || (map->size & 
(~PAGE_MASK))) {
                drm_free(map, sizeof(*map), DRM_MEM_MAPS);
                return -EINVAL;



------------------------------------------------------------------------------
Crystal Reports - New Free Runtime and 30 Day Trial
Check out the new simplified licensing option that enables 
unlimited royalty-free distribution of the report engine 
for externally facing server and web deployment. 
http://p.sf.net/sfu/businessobjects
--
_______________________________________________
Dri-devel mailing list
Dri-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/dri-devel

Reply via email to