diff options
Diffstat (limited to 'drivers/gpu/drm/i915/i915_gem.c')
-rw-r--r-- | drivers/gpu/drm/i915/i915_gem.c | 52 |
1 files changed, 28 insertions, 24 deletions
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index bced9b25c71e..90b1d6753b9d 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c | |||
@@ -136,14 +136,12 @@ i915_gem_create_ioctl(struct drm_device *dev, void *data, | |||
136 | return -ENOMEM; | 136 | return -ENOMEM; |
137 | 137 | ||
138 | ret = drm_gem_handle_create(file_priv, obj, &handle); | 138 | ret = drm_gem_handle_create(file_priv, obj, &handle); |
139 | /* drop reference from allocate - handle holds it now */ | ||
140 | drm_gem_object_unreference_unlocked(obj); | ||
139 | if (ret) { | 141 | if (ret) { |
140 | drm_gem_object_unreference_unlocked(obj); | ||
141 | return ret; | 142 | return ret; |
142 | } | 143 | } |
143 | 144 | ||
144 | /* Sink the floating reference from kref_init(handlecount) */ | ||
145 | drm_gem_object_handle_unreference_unlocked(obj); | ||
146 | |||
147 | args->handle = handle; | 145 | args->handle = handle; |
148 | return 0; | 146 | return 0; |
149 | } | 147 | } |
@@ -471,14 +469,17 @@ i915_gem_pread_ioctl(struct drm_device *dev, void *data, | |||
471 | return -ENOENT; | 469 | return -ENOENT; |
472 | obj_priv = to_intel_bo(obj); | 470 | obj_priv = to_intel_bo(obj); |
473 | 471 | ||
474 | /* Bounds check source. | 472 | /* Bounds check source. */ |
475 | * | 473 | if (args->offset > obj->size || args->size > obj->size - args->offset) { |
476 | * XXX: This could use review for overflow issues... | 474 | ret = -EINVAL; |
477 | */ | 475 | goto err; |
478 | if (args->offset > obj->size || args->size > obj->size || | 476 | } |
479 | args->offset + args->size > obj->size) { | 477 | |
480 | drm_gem_object_unreference_unlocked(obj); | 478 | if (!access_ok(VERIFY_WRITE, |
481 | return -EINVAL; | 479 | (char __user *)(uintptr_t)args->data_ptr, |
480 | args->size)) { | ||
481 | ret = -EFAULT; | ||
482 | goto err; | ||
482 | } | 483 | } |
483 | 484 | ||
484 | if (i915_gem_object_needs_bit17_swizzle(obj)) { | 485 | if (i915_gem_object_needs_bit17_swizzle(obj)) { |
@@ -490,8 +491,8 @@ i915_gem_pread_ioctl(struct drm_device *dev, void *data, | |||
490 | file_priv); | 491 | file_priv); |
491 | } | 492 | } |
492 | 493 | ||
494 | err: | ||
493 | drm_gem_object_unreference_unlocked(obj); | 495 | drm_gem_object_unreference_unlocked(obj); |
494 | |||
495 | return ret; | 496 | return ret; |
496 | } | 497 | } |
497 | 498 | ||
@@ -580,8 +581,6 @@ i915_gem_gtt_pwrite_fast(struct drm_device *dev, struct drm_gem_object *obj, | |||
580 | 581 | ||
581 | user_data = (char __user *) (uintptr_t) args->data_ptr; | 582 | user_data = (char __user *) (uintptr_t) args->data_ptr; |
582 | remain = args->size; | 583 | remain = args->size; |
583 | if (!access_ok(VERIFY_READ, user_data, remain)) | ||
584 | return -EFAULT; | ||
585 | 584 | ||
586 | 585 | ||
587 | mutex_lock(&dev->struct_mutex); | 586 | mutex_lock(&dev->struct_mutex); |
@@ -934,14 +933,17 @@ i915_gem_pwrite_ioctl(struct drm_device *dev, void *data, | |||
934 | return -ENOENT; | 933 | return -ENOENT; |
935 | obj_priv = to_intel_bo(obj); | 934 | obj_priv = to_intel_bo(obj); |
936 | 935 | ||
937 | /* Bounds check destination. | 936 | /* Bounds check destination. */ |
938 | * | 937 | if (args->offset > obj->size || args->size > obj->size - args->offset) { |
939 | * XXX: This could use review for overflow issues... | 938 | ret = -EINVAL; |
940 | */ | 939 | goto err; |
941 | if (args->offset > obj->size || args->size > obj->size || | 940 | } |
942 | args->offset + args->size > obj->size) { | 941 | |
943 | drm_gem_object_unreference_unlocked(obj); | 942 | if (!access_ok(VERIFY_READ, |
944 | return -EINVAL; | 943 | (char __user *)(uintptr_t)args->data_ptr, |
944 | args->size)) { | ||
945 | ret = -EFAULT; | ||
946 | goto err; | ||
945 | } | 947 | } |
946 | 948 | ||
947 | /* 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 |
@@ -975,8 +977,8 @@ i915_gem_pwrite_ioctl(struct drm_device *dev, void *data, | |||
975 | DRM_INFO("pwrite failed %d\n", ret); | 977 | DRM_INFO("pwrite failed %d\n", ret); |
976 | #endif | 978 | #endif |
977 | 979 | ||
980 | err: | ||
978 | drm_gem_object_unreference_unlocked(obj); | 981 | drm_gem_object_unreference_unlocked(obj); |
979 | |||
980 | return ret; | 982 | return ret; |
981 | } | 983 | } |
982 | 984 | ||
@@ -3258,6 +3260,8 @@ i915_gem_object_pin_and_relocate(struct drm_gem_object *obj, | |||
3258 | (int) reloc->offset, | 3260 | (int) reloc->offset, |
3259 | reloc->read_domains, | 3261 | reloc->read_domains, |
3260 | reloc->write_domain); | 3262 | reloc->write_domain); |
3263 | drm_gem_object_unreference(target_obj); | ||
3264 | i915_gem_object_unpin(obj); | ||
3261 | return -EINVAL; | 3265 | return -EINVAL; |
3262 | } | 3266 | } |
3263 | if (reloc->write_domain & I915_GEM_DOMAIN_CPU || | 3267 | if (reloc->write_domain & I915_GEM_DOMAIN_CPU || |