diff options
Diffstat (limited to 'drivers/gpu/drm/i915/i915_gem.c')
-rw-r--r-- | drivers/gpu/drm/i915/i915_gem.c | 46 |
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 | ||
494 | err: | ||
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 | ||
980 | err: | ||
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 || |