drm/i915: Sanity check pread/pwrite

Move the access control up from the fast paths, which are no longer
universally taken first, up into the caller. This then duplicates some
sanity checking along the slow paths, but is much simpler.
Tracked as CVE-2010-2962.

Reported-by: Kees Cook <kees@ubuntu.com>
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Cc: stable@kernel.org
This commit is contained in:
Chris Wilson 2010-09-26 20:50:05 +01:00
parent ab7ad7f645
commit ce9d419dbe

View file

@ -477,8 +477,15 @@ i915_gem_pread_ioctl(struct drm_device *dev, void *data,
*/
if (args->offset > obj->size || args->size > obj->size ||
args->offset + args->size > obj->size) {
drm_gem_object_unreference_unlocked(obj);
return -EINVAL;
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)) {
@ -490,8 +497,8 @@ i915_gem_pread_ioctl(struct drm_device *dev, void *data,
file_priv);
}
err:
drm_gem_object_unreference_unlocked(obj);
return ret;
}
@ -580,8 +587,6 @@ i915_gem_gtt_pwrite_fast(struct drm_device *dev, struct drm_gem_object *obj,
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);
@ -940,8 +945,15 @@ i915_gem_pwrite_ioctl(struct drm_device *dev, void *data,
*/
if (args->offset > obj->size || args->size > obj->size ||
args->offset + args->size > obj->size) {
drm_gem_object_unreference_unlocked(obj);
return -EINVAL;
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
@ -975,8 +987,8 @@ i915_gem_pwrite_ioctl(struct drm_device *dev, void *data,
DRM_INFO("pwrite failed %d\n", ret);
#endif
err:
drm_gem_object_unreference_unlocked(obj);
return ret;
}