drm/i915/fb: Check that the clear color fits within the BO
authorVille Syrjälä <ville.syrjala@linux.intel.com>
Fri, 29 Nov 2024 06:50:13 +0000 (08:50 +0200)
committerVille Syrjälä <ville.syrjala@linux.intel.com>
Mon, 13 Jan 2025 16:37:02 +0000 (18:37 +0200)
Make sure the user supplied offset[] for the clear color plane
fits within the actual BO. Note that we use tile units to track
the size here. All the other color/aux planes are already
being checked correctly.

Cc: Sagar Ghuge <sagar.ghuge@intel.com>
Cc: Nanley Chery <nanley.g.chery@intel.com>
Cc: Xi Ruoyao <xry111@xry111.site>
Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20241129065014.8363-4-ville.syrjala@linux.intel.com
Reviewed-by: José Roberto de Souza <jose.souza@intel.com>
drivers/gpu/drm/i915/display/intel_fb.c

index e478d412785e3d4f8a644539f4c86a9634080675..9f7f1b9f32750d1967b2a2e6c9fb6d5e2b968bb8 100644 (file)
@@ -1694,6 +1694,8 @@ int intel_fill_fb_info(struct drm_i915_private *i915, struct intel_framebuffer *
                 * arithmetic related to alignment and offset calculation.
                 */
                if (is_gen12_ccs_cc_plane(&fb->base, i)) {
+                       unsigned int end;
+
                        if (!IS_ALIGNED(fb->base.offsets[i], 64)) {
                                drm_dbg_kms(&i915->drm,
                                            "fb misaligned clear color plane %d offset (0x%x)\n",
@@ -1701,6 +1703,14 @@ int intel_fill_fb_info(struct drm_i915_private *i915, struct intel_framebuffer *
                                return -EINVAL;
                        }
 
+                       if (check_add_overflow(fb->base.offsets[i], 64, &end)) {
+                               drm_dbg_kms(&i915->drm,
+                                           "fb bad clear color plane %d offset (0x%x)\n",
+                                           i, fb->base.offsets[i]);
+                               return -EINVAL;
+                       }
+
+                       max_size = max(max_size, DIV_ROUND_UP(end, tile_size));
                        continue;
                }