aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/i915/i915_gem.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/i915/i915_gem.c')
-rw-r--r--drivers/gpu/drm/i915/i915_gem.c46
1 files changed, 26 insertions, 20 deletions
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index 2a0025f3e98e..90b1d6753b9d 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -469,14 +469,17 @@ i915_gem_pread_ioctl(struct drm_device *dev, void *data,
469 return -ENOENT; 469 return -ENOENT;
470 obj_priv = to_intel_bo(obj); 470 obj_priv = to_intel_bo(obj);
471 471
472 /* Bounds check source. 472 /* Bounds check source. */
473 * 473 if (args->offset > obj->size || args->size > obj->size - args->offset) {
474 * XXX: This could use review for overflow issues... 474 ret = -EINVAL;
475 */ 475 goto err;
476 if (args->offset > obj->size || args->size > obj->size || 476 }
477 args->offset + args->size > obj->size) { 477
478 drm_gem_object_unreference_unlocked(obj); 478 if (!access_ok(VERIFY_WRITE,
479 return -EINVAL; 479 (char __user *)(uintptr_t)args->data_ptr,
480 args->size)) {
481 ret = -EFAULT;
482 goto err;
480 } 483 }
481 484
482 if (i915_gem_object_needs_bit17_swizzle(obj)) { 485 if (i915_gem_object_needs_bit17_swizzle(obj)) {
@@ -488,8 +491,8 @@ i915_gem_pread_ioctl(struct drm_device *dev, void *data,
488 file_priv); 491 file_priv);
489 } 492 }
490 493
494err:
491 drm_gem_object_unreference_unlocked(obj); 495 drm_gem_object_unreference_unlocked(obj);
492
493 return ret; 496 return ret;
494} 497}
495 498
@@ -578,8 +581,6 @@ i915_gem_gtt_pwrite_fast(struct drm_device *dev, struct drm_gem_object *obj,
578 581
579 user_data = (char __user *) (uintptr_t) args->data_ptr; 582 user_data = (char __user *) (uintptr_t) args->data_ptr;
580 remain = args->size; 583 remain = args->size;
581 if (!access_ok(VERIFY_READ, user_data, remain))
582 return -EFAULT;
583 584
584 585
585 mutex_lock(&dev->struct_mutex); 586 mutex_lock(&dev->struct_mutex);
@@ -932,14 +933,17 @@ i915_gem_pwrite_ioctl(struct drm_device *dev, void *data,
932 return -ENOENT; 933 return -ENOENT;
933 obj_priv = to_intel_bo(obj); 934 obj_priv = to_intel_bo(obj);
934 935
935 /* Bounds check destination. 936 /* Bounds check destination. */
936 * 937 if (args->offset > obj->size || args->size > obj->size - args->offset) {
937 * XXX: This could use review for overflow issues... 938 ret = -EINVAL;
938 */ 939 goto err;
939 if (args->offset > obj->size || args->size > obj->size || 940 }
940 args->offset + args->size > obj->size) { 941
941 drm_gem_object_unreference_unlocked(obj); 942 if (!access_ok(VERIFY_READ,
942 return -EINVAL; 943 (char __user *)(uintptr_t)args->data_ptr,
944 args->size)) {
945 ret = -EFAULT;
946 goto err;
943 } 947 }
944 948
945 /* We can only do the GTT pwrite on untiled buffers, as otherwise 949 /* We can only do the GTT pwrite on untiled buffers, as otherwise
@@ -973,8 +977,8 @@ i915_gem_pwrite_ioctl(struct drm_device *dev, void *data,
973 DRM_INFO("pwrite failed %d\n", ret); 977 DRM_INFO("pwrite failed %d\n", ret);
974#endif 978#endif
975 979
980err:
976 drm_gem_object_unreference_unlocked(obj); 981 drm_gem_object_unreference_unlocked(obj);
977
978 return ret; 982 return ret;
979} 983}
980 984
@@ -3256,6 +3260,8 @@ i915_gem_object_pin_and_relocate(struct drm_gem_object *obj,
3256 (int) reloc->offset, 3260 (int) reloc->offset,
3257 reloc->read_domains, 3261 reloc->read_domains,
3258 reloc->write_domain); 3262 reloc->write_domain);
3263 drm_gem_object_unreference(target_obj);
3264 i915_gem_object_unpin(obj);
3259 return -EINVAL; 3265 return -EINVAL;
3260 } 3266 }
3261 if (reloc->write_domain & I915_GEM_DOMAIN_CPU || 3267 if (reloc->write_domain & I915_GEM_DOMAIN_CPU ||