Security fix on via: Checking that the specified context belongs to the
authorThomas Hellstrom <unichrome@shipmail.org>
Wed, 10 Aug 2005 19:46:46 +0000 (19:46 +0000)
committerThomas Hellstrom <unichrome@shipmail.org>
Wed, 10 Aug 2005 19:46:46 +0000 (19:46 +0000)
    caller on fb / agp memory alloc and free. Otherwise malicious clients
    can register allocations on other clients or free memory used by other
    clients which will lead to severe memory manager inconsistensies.

linux-core/drmP.h
linux-core/drm_context.c
shared-core/via_drv.h
shared-core/via_mm.c

index 2b4dbcf..8fed5e7 100644 (file)
@@ -838,6 +838,7 @@ extern int drm_context_switch_complete(drm_device_t * dev, int new);
 extern int drm_ctxbitmap_init(drm_device_t * dev);
 extern void drm_ctxbitmap_cleanup(drm_device_t * dev);
 extern void drm_ctxbitmap_free(drm_device_t * dev, int ctx_handle);
+extern int drm_check_context(drm_file_t *priv, drm_context_t handle);
 
 extern int drm_setsareactx(struct inode *inode, struct file *filp,
                           unsigned int cmd, unsigned long arg);
index baa8437..2f94719 100644 (file)
@@ -576,4 +576,34 @@ int drm_rmctx(struct inode *inode, struct file *filp,
        return 0;
 }
 
+/**
+ * Check that a context is registered for a caller.
+ *
+ * \param priv file pointer private structure.
+ * \param handle context handle.
+ * \param arg user argument pointing to a drm_ctx structure.
+ * \return one if the context is registered with the file pointer. Zero otherwise.
+ */
+
+int drm_check_context(drm_file_t *priv, drm_context_t handle)
+{
+       drm_device_t *dev = priv->head->dev;
+       int ret = 0;
+
+       down(&dev->ctxlist_sem);
+       if (dev->ctxlist && !list_empty(&dev->ctxlist->head)) {
+               drm_ctx_list_t *pos, *n;
+
+               list_for_each_entry_safe(pos, n, &dev->ctxlist->head, head) {
+                       if (pos->handle == handle) {
+                               ret = (pos->tag == priv);
+                               break;
+                       }
+               }
+       }
+       up(&dev->ctxlist_sem);
+       return ret;
+}
+       
+
 /*@}*/
index c76674e..95af8b9 100644 (file)
 
 #define DRIVER_NAME            "via"
 #define DRIVER_DESC            "VIA Unichrome / Pro"
-#define DRIVER_DATE            "20050715"
+#define DRIVER_DATE            "20050810"
 
 #define DRIVER_MAJOR           2
 #define DRIVER_MINOR           6
-#define DRIVER_PATCHLEVEL      4
+#define DRIVER_PATCHLEVEL      5
 
 #include "via_verifier.h"
 
index 13921f3..89d762f 100644 (file)
@@ -192,11 +192,16 @@ int via_final_context(struct drm_device *dev, int context)
 
 int via_mem_alloc(DRM_IOCTL_ARGS)
 {
+       drm_file_t *priv = filp->private_data;
        drm_via_mem_t mem;
 
        DRM_COPY_FROM_USER_IOCTL(mem, (drm_via_mem_t __user *) data,
                                 sizeof(mem));
 
+       if (!drm_check_context(priv, mem.context)) {
+               return DRM_ERR(EINVAL);
+       }
+
        switch (mem.type) {
        case VIDEO:
                if (via_fb_alloc(&mem) < 0)
@@ -289,11 +294,16 @@ static int via_agp_alloc(drm_via_mem_t * mem)
 
 int via_mem_free(DRM_IOCTL_ARGS)
 {
+       drm_file_t *priv = filp->private_data;
        drm_via_mem_t mem;
 
        DRM_COPY_FROM_USER_IOCTL(mem, (drm_via_mem_t __user *) data,
                                 sizeof(mem));
 
+       if (!drm_check_context(priv, mem.context)) {
+               return DRM_ERR(EINVAL);
+       }
+
        switch (mem.type) {
 
        case VIDEO: