New version that protects r128 and radeon IOCTLs with root capablity
check. Please review this patch. We need everyone's eyes to make sure
there are no accidental security holes.

-- 
Jon Smirl
[EMAIL PROTECTED]


diff --git a/linux-core/drmP.h b/linux-core/drmP.h
--- a/linux-core/drmP.h
+++ b/linux-core/drmP.h
@@ -280,7 +280,7 @@ typedef int drm_ioctl_compat_t(struct fi
 typedef struct drm_ioctl_desc {
        drm_ioctl_t *func;
        int auth_needed;
-       int root_only;
+       int master;
 } drm_ioctl_desc_t;
 
 typedef struct drm_devstate {
@@ -375,6 +375,7 @@ typedef struct drm_buf_entry {
 /** File private data */
 typedef struct drm_file {
        int authenticated;
+       int master;
        int minor;
        pid_t pid;
        uid_t uid;
diff --git a/linux-core/drm_bufs.c b/linux-core/drm_bufs.c
--- a/linux-core/drm_bufs.c
+++ b/linux-core/drm_bufs.c
@@ -56,7 +56,8 @@ static drm_local_map_t *drm_find_matchin
        list_for_each(list, &dev->maplist->head) {
                drm_map_list_t *entry = list_entry(list, drm_map_list_t, head);
                if (entry->map && map->type == entry->map->type &&
-                   entry->map->offset == map->offset) {
+                   ((entry->map->offset == map->offset) ||
+                    (map->type == _DRM_SHM))) {
                        return entry->map;
                }
        }
@@ -163,6 +164,19 @@ int drm_addmap(drm_device_t * dev, unsig
                        map->handle = drm_ioremap(map->offset, map->size, dev);
                break;
        case _DRM_SHM:
+               found_map = drm_find_matching_map(dev, map);
+               if (found_map != NULL) {
+                       if (found_map->size != map->size) {
+                               DRM_DEBUG("Matching maps of type %d with "
+                                  "mismatched sizes, (%ld vs %ld)\n",
+                                   map->type, map->size, found_map->size);
+                               found_map->size = map->size;
+                       }
+
+                       drm_free(map, sizeof(*map), DRM_MEM_MAPS);
+                       *map_ptr = found_map;
+                       return 0;
+               }
                map->handle = vmalloc_32(map->size);
                DRM_DEBUG("%lu %d %p\n",
                          map->size, drm_order(map->size), map->handle);
@@ -181,15 +195,34 @@ int drm_addmap(drm_device_t * dev, unsig
                        dev->sigdata.lock = dev->lock.hw_lock = map->handle;    
/* Pointer to lock */
                }
                break;
-       case _DRM_AGP:
-               if (drm_core_has_AGP(dev)) {
+       case _DRM_AGP: {
+               drm_agp_mem_t *entry;
+               int valid = 0;
+
+               if (!drm_core_has_AGP(dev)) {
+                       drm_free(map, sizeof(*map), DRM_MEM_MAPS);
+                       return -EINVAL;
+               }
 #ifdef __alpha__
-                       map->offset += dev->hose->mem_space->start;
+               map->offset += dev->hose->mem_space->start;
 #endif
-                       map->offset += dev->agp->base;
-                       map->mtrr = dev->agp->agp_mtrr; /* for getmap */
+               map->offset += dev->agp->base;
+               map->mtrr = dev->agp->agp_mtrr; /* for getmap */
+
+               for (entry = dev->agp->memory; entry; entry = entry->next) {
+                       if ((map->offset >= entry->bound) &&
+                           (map->offset + map->offset <= entry->bound + 
entry->pages *
PAGE_SIZE)) {
+                               valid = 1;
+                               break;
+                       }
+               }
+               if (!valid) {
+                       drm_free(map, sizeof(*map), DRM_MEM_MAPS);
+                       return -EPERM;
                }
+               DRM_DEBUG("AGP offset = 0x%08lx, size = 0x%08lx\n", 
map->offset, map->size);
                break;
+       }
        case _DRM_SCATTER_GATHER:
                if (!dev->sg) {
                        drm_free(map, sizeof(*map), DRM_MEM_MAPS);
@@ -258,6 +291,9 @@ int drm_addmap_ioctl(struct inode *inode
                return -EFAULT;
        }
 
+       if (!(capable(CAP_SYS_ADMIN) || map.type == _DRM_AGP))
+               return -EPERM;
+
        err = drm_addmap( dev, map.offset, map.size, map.type, map.flags,
                          & map_ptr );
 
diff --git a/linux-core/drm_drv.c b/linux-core/drm_drv.c
--- a/linux-core/drm_drv.c
+++ b/linux-core/drm_drv.c
@@ -545,13 +545,14 @@ int drm_ioctl(struct inode *inode, struc
        if (!func) {
                DRM_DEBUG("no function\n");
                retcode = -EINVAL;
-       } else if ((ioctl->root_only && !capable(CAP_SYS_ADMIN)) ||
-                  (ioctl->auth_needed && !priv->authenticated)) {
+       } else if (((ioctl->master && !priv->master) ||
+                  (ioctl->auth_needed && !priv->authenticated)) &&
+                  (!capable(CAP_SYS_ADMIN))) {
                retcode = -EACCES;
        } else {
                retcode = func(inode, filp, cmd, arg);
        }
-      err_i1:
+err_i1:
        atomic_dec(&dev->ioctl_count);
        if (retcode)
                DRM_DEBUG("ret = %x\n", retcode);
diff --git a/linux-core/drm_fops.c b/linux-core/drm_fops.c
--- a/linux-core/drm_fops.c
+++ b/linux-core/drm_fops.c
@@ -34,18 +34,26 @@
  * OTHER DEALINGS IN THE SOFTWARE.
  */
 
-#include "drmP.h"
 #include <linux/poll.h>
 
+#include "drmP.h"
+#include "drm_sarea.h"
+
 static int drm_open_helper(struct inode *inode, struct file *filp,
drm_device_t * dev);
 
 static int drm_setup(drm_device_t * dev)
 {
+       drm_local_map_t *map;
        int i;
 
        if (dev->driver->presetup)
                dev->driver->presetup(dev);
 
+       /* prebuild the SAREA */
+       i = drm_addmap(dev, 0, SAREA_MAX, _DRM_SHM, _DRM_CONTAINS_LOCK, &map);
+       if (i != 0)
+               return i;
+
        atomic_set(&dev->ioctl_count, 0);
        atomic_set(&dev->vma_count, 0);
        dev->buf_use = 0;
@@ -72,7 +80,7 @@ static int drm_setup(drm_device_t * dev)
        INIT_LIST_HEAD(&dev->ctxlist->head);
 
        dev->vmalist = NULL;
-       dev->sigdata.lock = dev->lock.hw_lock = NULL;
+       dev->sigdata.lock = NULL;
        init_waitqueue_head(&dev->lock.lock_queue);
        dev->queue_count = 0;
        dev->queue_reserved = 0;
@@ -244,6 +252,7 @@ static int drm_open_helper(struct inode 
        priv->minor = minor;
        priv->head = drm_heads[minor];
        priv->ioctl_count = 0;
+       /* for compatibility root is always authenticated */
        priv->authenticated = capable(CAP_SYS_ADMIN);
        priv->lock_count = 0;
 
@@ -259,6 +268,9 @@ static int drm_open_helper(struct inode 
                priv->prev = NULL;
                dev->file_first = priv;
                dev->file_last = priv;
+               /* first opener automatically becomes master and authenticated 
*/
+               priv->master = 1;
+               priv->authenticated = 1;
        } else {
                priv->next = NULL;
                priv->prev = dev->file_last;
diff --git a/shared-core/drm.h b/shared-core/drm.h
--- a/shared-core/drm.h
+++ b/shared-core/drm.h
@@ -62,6 +62,12 @@
 #define __user
 #endif
 
+#ifdef __GNUC__
+# define DEPRECATED  __attribute__ ((deprecated))
+#else
+# define DEPRECATED
+#endif
+
 #if defined(__linux__)
 #if defined(__KERNEL__)
 #include <linux/config.h>
diff --git a/shared-core/r128_state.c b/shared-core/r128_state.c
--- a/shared-core/r128_state.c
+++ b/shared-core/r128_state.c
@@ -1576,6 +1576,9 @@ static int r128_cce_indirect(DRM_IOCTL_A
 
        LOCK_TEST_WITH_RETURN(dev, filp);
 
+       if (!(capable(CAP_SYS_ADMIN)))
+               return DRM_ERR(EPERM);
+
        if (!dev_priv) {
                DRM_ERROR("%s called with no initialization\n", __FUNCTION__);
                return DRM_ERR(EINVAL);
diff --git a/shared-core/radeon_cp.c b/shared-core/radeon_cp.c
--- a/shared-core/radeon_cp.c
+++ b/shared-core/radeon_cp.c
@@ -1245,7 +1245,7 @@ static void radeon_set_pciegart(drm_rade
        u32 tmp = RADEON_READ_PCIE(dev_priv, RADEON_PCIE_TX_GART_CNTL);
        if (on) {
 
-               DRM_DEBUG("programming pcie %08X %08lX %08X\n",
dev_priv->gart_vm_start, dev_priv->bus_pci_gart,dev_priv->gart_size);
+               DRM_DEBUG("programming pcie %08X %08X %08X\n",
dev_priv->gart_vm_start, dev_priv->bus_pci_gart,dev_priv->gart_size);
                RADEON_WRITE_PCIE(RADEON_PCIE_TX_DISCARD_RD_ADDR_LO,
dev_priv->gart_vm_start);
                RADEON_WRITE_PCIE(RADEON_PCIE_TX_GART_BASE, 
dev_priv->bus_pci_gart);
                RADEON_WRITE_PCIE(RADEON_PCIE_TX_GART_START_LO, 
dev_priv->gart_vm_start);
@@ -1398,8 +1398,6 @@ static int radeon_do_init_cp(drm_device_
 
        DRM_GETSAREA();
 
-       dev_priv->fb_offset = init->fb_offset;
-       dev_priv->mmio_offset = init->mmio_offset;
        dev_priv->ring_offset = init->ring_offset;
        dev_priv->ring_rptr_offset = init->ring_rptr_offset;
        dev_priv->buffers_offset = init->buffers_offset;
@@ -1411,12 +1409,6 @@ static int radeon_do_init_cp(drm_device_
                return DRM_ERR(EINVAL);
        }
 
-       dev_priv->mmio = drm_core_findmap(dev, init->mmio_offset);
-       if (!dev_priv->mmio) {
-               DRM_ERROR("could not find mmio region!\n");
-               radeon_do_cleanup_cp(dev);
-               return DRM_ERR(EINVAL);
-       }
        dev_priv->cp_ring = drm_core_findmap(dev, init->ring_offset);
        if (!dev_priv->cp_ring) {
                DRM_ERROR("could not find cp ring region!\n");
diff --git a/shared-core/radeon_drm.h b/shared-core/radeon_drm.h
--- a/shared-core/radeon_drm.h
+++ b/shared-core/radeon_drm.h
@@ -492,7 +492,7 @@ typedef struct drm_radeon_init {
                RADEON_INIT_R300_CP = 0x04
        } func;
        unsigned long sarea_priv_offset;
-       int is_pci;             /* not used, driver asks hardware */
+       int is_pci DEPRECATED;                  /* deprecated, driver asks 
hardware */
        int cp_mode;
        int gart_size;
        int ring_size;
@@ -504,8 +504,8 @@ typedef struct drm_radeon_init {
        unsigned int depth_bpp;
        unsigned int depth_offset, depth_pitch;
 
-       unsigned long fb_offset;
-       unsigned long mmio_offset;
+       unsigned long fb_offset DEPRECATED;     /* deprecated, driver asks 
hardware */
+       unsigned long mmio_offset DEPRECATED;   /* deprecated, driver asks 
hardware */
        unsigned long ring_offset;
        unsigned long ring_rptr_offset;
        unsigned long buffers_offset;
diff --git a/shared-core/radeon_drv.h b/shared-core/radeon_drv.h
--- a/shared-core/radeon_drv.h
+++ b/shared-core/radeon_drv.h
@@ -242,8 +242,6 @@ typedef struct drm_radeon_private {
 
        drm_radeon_depth_clear_t depth_clear;
 
-       unsigned long fb_offset;
-       unsigned long mmio_offset;
        unsigned long ring_offset;
        unsigned long ring_rptr_offset;
        unsigned long buffers_offset;
diff --git a/shared-core/radeon_state.c b/shared-core/radeon_state.c
--- a/shared-core/radeon_state.c
+++ b/shared-core/radeon_state.c
@@ -2330,6 +2330,9 @@ static int radeon_cp_indirect(DRM_IOCTL_
 
        LOCK_TEST_WITH_RETURN(dev, filp);
 
+       if (!(capable(CAP_SYS_ADMIN)))
+               return DRM_ERR(EPERM);
+
        if (!dev_priv) {
                DRM_ERROR("%s called with no initialization\n", __FUNCTION__);
                return DRM_ERR(EINVAL);
@@ -2917,7 +2920,7 @@ static int radeon_cp_getparam(DRM_IOCTL_
                value = dev_priv->gart_vm_start;
                break;
        case RADEON_PARAM_REGISTER_HANDLE:
-               value = dev_priv->mmio_offset;
+               value = dev_priv->mmio->offset;
                break;
        case RADEON_PARAM_STATUS_HANDLE:
                value = dev_priv->ring_rptr_offset;
diff --git a/linux-core/drmP.h b/linux-core/drmP.h
--- a/linux-core/drmP.h
+++ b/linux-core/drmP.h
@@ -280,7 +280,7 @@ typedef int drm_ioctl_compat_t(struct fi
 typedef struct drm_ioctl_desc {
 	drm_ioctl_t *func;
 	int auth_needed;
-	int root_only;
+	int master;
 } drm_ioctl_desc_t;
 
 typedef struct drm_devstate {
@@ -375,6 +375,7 @@ typedef struct drm_buf_entry {
 /** File private data */
 typedef struct drm_file {
 	int authenticated;
+	int master;
 	int minor;
 	pid_t pid;
 	uid_t uid;
diff --git a/linux-core/drm_bufs.c b/linux-core/drm_bufs.c
--- a/linux-core/drm_bufs.c
+++ b/linux-core/drm_bufs.c
@@ -56,7 +56,8 @@ static drm_local_map_t *drm_find_matchin
 	list_for_each(list, &dev->maplist->head) {
 		drm_map_list_t *entry = list_entry(list, drm_map_list_t, head);
 		if (entry->map && map->type == entry->map->type &&
-		    entry->map->offset == map->offset) {
+		    ((entry->map->offset == map->offset) ||
+		     (map->type == _DRM_SHM))) {
 			return entry->map;
 		}
 	}
@@ -163,6 +164,19 @@ int drm_addmap(drm_device_t * dev, unsig
 			map->handle = drm_ioremap(map->offset, map->size, dev);
 		break;
 	case _DRM_SHM:
+		found_map = drm_find_matching_map(dev, map);
+		if (found_map != NULL) {
+			if (found_map->size != map->size) {
+				DRM_DEBUG("Matching maps of type %d with "
+				   "mismatched sizes, (%ld vs %ld)\n",
+				    map->type, map->size, found_map->size);
+				found_map->size = map->size;
+			}
+
+			drm_free(map, sizeof(*map), DRM_MEM_MAPS);
+			*map_ptr = found_map;
+			return 0;
+		}
 		map->handle = vmalloc_32(map->size);
 		DRM_DEBUG("%lu %d %p\n",
 			  map->size, drm_order(map->size), map->handle);
@@ -181,15 +195,34 @@ int drm_addmap(drm_device_t * dev, unsig
 			dev->sigdata.lock = dev->lock.hw_lock = map->handle;	/* Pointer to lock */
 		}
 		break;
-	case _DRM_AGP:
-		if (drm_core_has_AGP(dev)) {
+	case _DRM_AGP: {
+		drm_agp_mem_t *entry;
+		int valid = 0;
+
+		if (!drm_core_has_AGP(dev)) {
+			drm_free(map, sizeof(*map), DRM_MEM_MAPS);
+			return -EINVAL;
+		}
 #ifdef __alpha__
-			map->offset += dev->hose->mem_space->start;
+		map->offset += dev->hose->mem_space->start;
 #endif
-			map->offset += dev->agp->base;
-			map->mtrr = dev->agp->agp_mtrr;	/* for getmap */
+		map->offset += dev->agp->base;
+		map->mtrr = dev->agp->agp_mtrr;	/* for getmap */
+
+		for (entry = dev->agp->memory; entry; entry = entry->next) {
+			if ((map->offset >= entry->bound) &&
+			    (map->offset + map->offset <= entry->bound + entry->pages * PAGE_SIZE)) {
+				valid = 1;
+				break;
+			}
+		}
+		if (!valid) {
+			drm_free(map, sizeof(*map), DRM_MEM_MAPS);
+			return -EPERM;
 		}
+		DRM_DEBUG("AGP offset = 0x%08lx, size = 0x%08lx\n", map->offset, map->size);
 		break;
+	}
 	case _DRM_SCATTER_GATHER:
 		if (!dev->sg) {
 			drm_free(map, sizeof(*map), DRM_MEM_MAPS);
@@ -258,6 +291,9 @@ int drm_addmap_ioctl(struct inode *inode
 		return -EFAULT;
 	}
 
+	if (!(capable(CAP_SYS_ADMIN) || map.type == _DRM_AGP))
+		return -EPERM;
+
 	err = drm_addmap( dev, map.offset, map.size, map.type, map.flags,
 			  & map_ptr );
 
diff --git a/linux-core/drm_drv.c b/linux-core/drm_drv.c
--- a/linux-core/drm_drv.c
+++ b/linux-core/drm_drv.c
@@ -545,13 +545,14 @@ int drm_ioctl(struct inode *inode, struc
 	if (!func) {
 		DRM_DEBUG("no function\n");
 		retcode = -EINVAL;
-	} else if ((ioctl->root_only && !capable(CAP_SYS_ADMIN)) ||
-		   (ioctl->auth_needed && !priv->authenticated)) {
+	} else if (((ioctl->master && !priv->master) ||
+		   (ioctl->auth_needed && !priv->authenticated)) &&
+		   (!capable(CAP_SYS_ADMIN))) {
 		retcode = -EACCES;
 	} else {
 		retcode = func(inode, filp, cmd, arg);
 	}
-      err_i1:
+err_i1:
 	atomic_dec(&dev->ioctl_count);
 	if (retcode)
 		DRM_DEBUG("ret = %x\n", retcode);
diff --git a/linux-core/drm_fops.c b/linux-core/drm_fops.c
--- a/linux-core/drm_fops.c
+++ b/linux-core/drm_fops.c
@@ -34,18 +34,26 @@
  * OTHER DEALINGS IN THE SOFTWARE.
  */
 
-#include "drmP.h"
 #include <linux/poll.h>
 
+#include "drmP.h"
+#include "drm_sarea.h"
+
 static int drm_open_helper(struct inode *inode, struct file *filp, drm_device_t * dev);
 
 static int drm_setup(drm_device_t * dev)
 {
+	drm_local_map_t *map;
 	int i;
 
 	if (dev->driver->presetup)
 		dev->driver->presetup(dev);
 
+	/* prebuild the SAREA */
+	i = drm_addmap(dev, 0, SAREA_MAX, _DRM_SHM, _DRM_CONTAINS_LOCK, &map);
+	if (i != 0)
+		return i;
+
 	atomic_set(&dev->ioctl_count, 0);
 	atomic_set(&dev->vma_count, 0);
 	dev->buf_use = 0;
@@ -72,7 +80,7 @@ static int drm_setup(drm_device_t * dev)
 	INIT_LIST_HEAD(&dev->ctxlist->head);
 
 	dev->vmalist = NULL;
-	dev->sigdata.lock = dev->lock.hw_lock = NULL;
+	dev->sigdata.lock = NULL;
 	init_waitqueue_head(&dev->lock.lock_queue);
 	dev->queue_count = 0;
 	dev->queue_reserved = 0;
@@ -244,6 +252,7 @@ static int drm_open_helper(struct inode 
 	priv->minor = minor;
 	priv->head = drm_heads[minor];
 	priv->ioctl_count = 0;
+	/* for compatibility root is always authenticated */
 	priv->authenticated = capable(CAP_SYS_ADMIN);
 	priv->lock_count = 0;
 
@@ -259,6 +268,9 @@ static int drm_open_helper(struct inode 
 		priv->prev = NULL;
 		dev->file_first = priv;
 		dev->file_last = priv;
+		/* first opener automatically becomes master and authenticated */
+		priv->master = 1;
+		priv->authenticated = 1;
 	} else {
 		priv->next = NULL;
 		priv->prev = dev->file_last;
diff --git a/shared-core/drm.h b/shared-core/drm.h
--- a/shared-core/drm.h
+++ b/shared-core/drm.h
@@ -62,6 +62,12 @@
 #define __user
 #endif
 
+#ifdef __GNUC__
+# define DEPRECATED  __attribute__ ((deprecated))
+#else
+# define DEPRECATED
+#endif
+
 #if defined(__linux__)
 #if defined(__KERNEL__)
 #include <linux/config.h>
diff --git a/shared-core/r128_state.c b/shared-core/r128_state.c
--- a/shared-core/r128_state.c
+++ b/shared-core/r128_state.c
@@ -1576,6 +1576,9 @@ static int r128_cce_indirect(DRM_IOCTL_A
 
 	LOCK_TEST_WITH_RETURN(dev, filp);
 
+	if (!(capable(CAP_SYS_ADMIN)))
+		return DRM_ERR(EPERM);
+
 	if (!dev_priv) {
 		DRM_ERROR("%s called with no initialization\n", __FUNCTION__);
 		return DRM_ERR(EINVAL);
diff --git a/shared-core/radeon_cp.c b/shared-core/radeon_cp.c
--- a/shared-core/radeon_cp.c
+++ b/shared-core/radeon_cp.c
@@ -1245,7 +1245,7 @@ static void radeon_set_pciegart(drm_rade
 	u32 tmp = RADEON_READ_PCIE(dev_priv, RADEON_PCIE_TX_GART_CNTL);
 	if (on) {
 
-		DRM_DEBUG("programming pcie %08X %08lX %08X\n", dev_priv->gart_vm_start, dev_priv->bus_pci_gart,dev_priv->gart_size);
+		DRM_DEBUG("programming pcie %08X %08X %08X\n", dev_priv->gart_vm_start, dev_priv->bus_pci_gart,dev_priv->gart_size);
 		RADEON_WRITE_PCIE(RADEON_PCIE_TX_DISCARD_RD_ADDR_LO, dev_priv->gart_vm_start);
 		RADEON_WRITE_PCIE(RADEON_PCIE_TX_GART_BASE, dev_priv->bus_pci_gart);
 		RADEON_WRITE_PCIE(RADEON_PCIE_TX_GART_START_LO, dev_priv->gart_vm_start);
@@ -1398,8 +1398,6 @@ static int radeon_do_init_cp(drm_device_
 
 	DRM_GETSAREA();
 
-	dev_priv->fb_offset = init->fb_offset;
-	dev_priv->mmio_offset = init->mmio_offset;
 	dev_priv->ring_offset = init->ring_offset;
 	dev_priv->ring_rptr_offset = init->ring_rptr_offset;
 	dev_priv->buffers_offset = init->buffers_offset;
@@ -1411,12 +1409,6 @@ static int radeon_do_init_cp(drm_device_
 		return DRM_ERR(EINVAL);
 	}
 
-	dev_priv->mmio = drm_core_findmap(dev, init->mmio_offset);
-	if (!dev_priv->mmio) {
-		DRM_ERROR("could not find mmio region!\n");
-		radeon_do_cleanup_cp(dev);
-		return DRM_ERR(EINVAL);
-	}
 	dev_priv->cp_ring = drm_core_findmap(dev, init->ring_offset);
 	if (!dev_priv->cp_ring) {
 		DRM_ERROR("could not find cp ring region!\n");
diff --git a/shared-core/radeon_drm.h b/shared-core/radeon_drm.h
--- a/shared-core/radeon_drm.h
+++ b/shared-core/radeon_drm.h
@@ -492,7 +492,7 @@ typedef struct drm_radeon_init {
 		RADEON_INIT_R300_CP = 0x04
 	} func;
 	unsigned long sarea_priv_offset;
-	int is_pci;		/* not used, driver asks hardware */
+	int is_pci DEPRECATED;			/* deprecated, driver asks hardware */
 	int cp_mode;
 	int gart_size;
 	int ring_size;
@@ -504,8 +504,8 @@ typedef struct drm_radeon_init {
 	unsigned int depth_bpp;
 	unsigned int depth_offset, depth_pitch;
 
-	unsigned long fb_offset;
-	unsigned long mmio_offset;
+	unsigned long fb_offset DEPRECATED;	/* deprecated, driver asks hardware */
+	unsigned long mmio_offset DEPRECATED;	/* deprecated, driver asks hardware */
 	unsigned long ring_offset;
 	unsigned long ring_rptr_offset;
 	unsigned long buffers_offset;
diff --git a/shared-core/radeon_drv.h b/shared-core/radeon_drv.h
--- a/shared-core/radeon_drv.h
+++ b/shared-core/radeon_drv.h
@@ -242,8 +242,6 @@ typedef struct drm_radeon_private {
 
 	drm_radeon_depth_clear_t depth_clear;
 
-	unsigned long fb_offset;
-	unsigned long mmio_offset;
 	unsigned long ring_offset;
 	unsigned long ring_rptr_offset;
 	unsigned long buffers_offset;
diff --git a/shared-core/radeon_state.c b/shared-core/radeon_state.c
--- a/shared-core/radeon_state.c
+++ b/shared-core/radeon_state.c
@@ -2330,6 +2330,9 @@ static int radeon_cp_indirect(DRM_IOCTL_
 
 	LOCK_TEST_WITH_RETURN(dev, filp);
 
+	if (!(capable(CAP_SYS_ADMIN)))
+		return DRM_ERR(EPERM);
+
 	if (!dev_priv) {
 		DRM_ERROR("%s called with no initialization\n", __FUNCTION__);
 		return DRM_ERR(EINVAL);
@@ -2917,7 +2920,7 @@ static int radeon_cp_getparam(DRM_IOCTL_
 		value = dev_priv->gart_vm_start;
 		break;
 	case RADEON_PARAM_REGISTER_HANDLE:
-		value = dev_priv->mmio_offset;
+		value = dev_priv->mmio->offset;
 		break;
 	case RADEON_PARAM_STATUS_HANDLE:
 		value = dev_priv->ring_rptr_offset;

Reply via email to