]> rtime.felk.cvut.cz Git - lisovros/linux_canprio.git/commitdiff
Merge branch 'drm-intel-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/ickle...
authorLinus Torvalds <torvalds@linux-foundation.org>
Mon, 4 Oct 2010 18:10:26 +0000 (11:10 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Mon, 4 Oct 2010 18:10:26 +0000 (11:10 -0700)
* 'drm-intel-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/ickle/drm-intel:
  drm/i915: Rephrase pwrite bounds checking to avoid any potential overflow
  drm/i915: Sanity check pread/pwrite
  drm/i915: Use pipe state to tell when pipe is off
  drm/i915: vblank status not valid while training display port
  drivers/gpu/drm/i915/i915_gem.c: Add missing error handling code
  drm/i915: Fix refleak during eviction.
  drm/i915: fix GMCH power reporting

1  2 
drivers/gpu/drm/i915/i915_gem.c

index 2a0025f3e98e79201e16e25c3541dd99f6b03f7a,aa959c4a1836238354d7674cdaa52b3a195013d5..90b1d6753b9d493d3ed8d2c45153bf2047b54d8f
@@@ -136,12 -136,14 +136,12 @@@ i915_gem_create_ioctl(struct drm_devic
                return -ENOMEM;
  
        ret = drm_gem_handle_create(file_priv, obj, &handle);
 +      /* drop reference from allocate - handle holds it now */
 +      drm_gem_object_unreference_unlocked(obj);
        if (ret) {
 -              drm_gem_object_unreference_unlocked(obj);
                return ret;
        }
  
 -      /* Sink the floating reference from kref_init(handlecount) */
 -      drm_gem_object_handle_unreference_unlocked(obj);
 -
        args->handle = handle;
        return 0;
  }
@@@ -469,14 -471,17 +469,17 @@@ i915_gem_pread_ioctl(struct drm_device 
                return -ENOENT;
        obj_priv = to_intel_bo(obj);
  
-       /* Bounds check source.
-        *
-        * XXX: This could use review for overflow issues...
-        */
-       if (args->offset > obj->size || args->size > obj->size ||
-           args->offset + args->size > obj->size) {
-               drm_gem_object_unreference_unlocked(obj);
-               return -EINVAL;
+       /* Bounds check source.  */
+       if (args->offset > obj->size || args->size > obj->size - args->offset) {
+               ret = -EINVAL;
+               goto err;
+       }
+       if (!access_ok(VERIFY_WRITE,
+                      (char __user *)(uintptr_t)args->data_ptr,
+                      args->size)) {
+               ret = -EFAULT;
+               goto err;
        }
  
        if (i915_gem_object_needs_bit17_swizzle(obj)) {
                                                        file_priv);
        }
  
+ err:
        drm_gem_object_unreference_unlocked(obj);
        return ret;
  }
  
@@@ -578,8 -583,6 +581,6 @@@ i915_gem_gtt_pwrite_fast(struct drm_dev
  
        user_data = (char __user *) (uintptr_t) args->data_ptr;
        remain = args->size;
-       if (!access_ok(VERIFY_READ, user_data, remain))
-               return -EFAULT;
  
  
        mutex_lock(&dev->struct_mutex);
@@@ -932,14 -935,17 +933,17 @@@ i915_gem_pwrite_ioctl(struct drm_devic
                return -ENOENT;
        obj_priv = to_intel_bo(obj);
  
-       /* Bounds check destination.
-        *
-        * XXX: This could use review for overflow issues...
-        */
-       if (args->offset > obj->size || args->size > obj->size ||
-           args->offset + args->size > obj->size) {
-               drm_gem_object_unreference_unlocked(obj);
-               return -EINVAL;
+       /* Bounds check destination. */
+       if (args->offset > obj->size || args->size > obj->size - args->offset) {
+               ret = -EINVAL;
+               goto err;
+       }
+       if (!access_ok(VERIFY_READ,
+                      (char __user *)(uintptr_t)args->data_ptr,
+                      args->size)) {
+               ret = -EFAULT;
+               goto err;
        }
  
        /* We can only do the GTT pwrite on untiled buffers, as otherwise
                DRM_INFO("pwrite failed %d\n", ret);
  #endif
  
+ err:
        drm_gem_object_unreference_unlocked(obj);
        return ret;
  }
  
@@@ -3256,6 -3262,8 +3260,8 @@@ i915_gem_object_pin_and_relocate(struc
                                  (int) reloc->offset,
                                  reloc->read_domains,
                                  reloc->write_domain);
+                       drm_gem_object_unreference(target_obj);
+                       i915_gem_object_unpin(obj);
                        return -EINVAL;
                }
                if (reloc->write_domain & I915_GEM_DOMAIN_CPU ||