|
@@ -732,6 +732,8 @@ validate_exec_list(struct drm_i915_gem_exec_object2 *exec,
|
|
|
int count)
|
|
|
{
|
|
|
int i;
|
|
|
+ int relocs_total = 0;
|
|
|
+ int relocs_max = INT_MAX / sizeof(struct drm_i915_gem_relocation_entry);
|
|
|
|
|
|
for (i = 0; i < count; i++) {
|
|
|
char __user *ptr = (char __user *)(uintptr_t)exec[i].relocs_ptr;
|
|
@@ -740,10 +742,13 @@ validate_exec_list(struct drm_i915_gem_exec_object2 *exec,
|
|
|
if (exec[i].flags & __EXEC_OBJECT_UNKNOWN_FLAGS)
|
|
|
return -EINVAL;
|
|
|
|
|
|
- /* First check for malicious input causing overflow */
|
|
|
- if (exec[i].relocation_count >
|
|
|
- INT_MAX / sizeof(struct drm_i915_gem_relocation_entry))
|
|
|
+ /* First check for malicious input causing overflow in
|
|
|
+ * the worst case where we need to allocate the entire
|
|
|
+ * relocation tree as a single array.
|
|
|
+ */
|
|
|
+ if (exec[i].relocation_count > relocs_max - relocs_total)
|
|
|
return -EINVAL;
|
|
|
+ relocs_total += exec[i].relocation_count;
|
|
|
|
|
|
length = exec[i].relocation_count *
|
|
|
sizeof(struct drm_i915_gem_relocation_entry);
|