From 4e05047d3e0099c9b802eb643a5de0c60feccf17 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Wed, 12 Sep 2018 21:04:43 +0300 Subject: [PATCH] drm/i915: Fix a potential integer overflow with framebuffers extending past 4 GiB MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit If we have framebuffers that are >= 4GiB in size we will overflow the fb size check in intel_fill_fb_info(). Currently that is only possible with NV12 and CCS as offsets[1] may be anything between 0 and 0xffffffff. offsets[0] is currently required to be 0 so we can't hit the overflow with any single plane format (thanks to max fb size of 8kx8k and max stride of 32 KiB). In the future we may allow almost any framebuffer to exceed 4GiB in size so we really should fix the overflow. Not that the overflow is particularly dangerous. It's mostly just a sanity check against insane userspace. The display engine can't write to memory anyway so I suppose in the worst case we might anger the hw by attempting scanout past the end of the ggtt, or we might scan out some data that we're not supposed to see from other parts of the ggtt. Note that triggering this overflow depends on the driver aligning the fb height to the next tile boundary to push the calculated size above 4GiB. With linear buffers the effective tile height is one so that never happens, and the core already has a check for 32bit overflow of offsets[]+pitches[]*height. v2: Drop the unnecessary cast (Chris) Testcase: igt/kms_big_fb/x-tiled-addfb-size-offset-overflow Testcase: igt/kms_big_fb/y-tiled-addfb-size-offset-overflow Signed-off-by: Ville Syrjälä Reviewed-by: Chris Wilson Link: https://patchwork.freedesktop.org/patch/msgid/20180912180443.28649-1-ville.syrjala@linux.intel.com --- drivers/gpu/drm/i915/intel_display.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 807784d8f5e2..7e206e5e60cd 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -2639,9 +2639,9 @@ intel_fill_fb_info(struct drm_i915_private *dev_priv, max_size = max(max_size, offset + size); } - if (max_size * tile_size > obj->base.size) { - DRM_DEBUG_KMS("fb too big for bo (need %u bytes, have %zu bytes)\n", - max_size * tile_size, obj->base.size); + if (mul_u32_u32(max_size, tile_size) > obj->base.size) { + DRM_DEBUG_KMS("fb too big for bo (need %llu bytes, have %zu bytes)\n", + mul_u32_u32(max_size, tile_size), obj->base.size); return -EINVAL; } -- 2.30.2