There are two unsafe scenarios in that function:
1) drm_format_info_block_width/height() may return 0 and cause
division by 0 down the line. Return early if any of these values
are 0.
2) dma_addr calculations are carried out using 32-bit
arithmetic, which could cause a truncation of the values
before they are extended to 64 bits. Cast one of the operands
to dma_addr_t, so 64-bit arithmetic is used.
Fixes: 8c30eecc6769 ("drm/gem: rename struct drm_gem_dma_object.{paddr =>
dma_addr}")
Cc: Danilo Krummrich <[email protected]>
Cc: <[email protected]> # v6.1+
Signed-off-by: Krzysztof Karas <[email protected]>
---
drivers/gpu/drm/drm_fb_dma_helper.c | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/drm_fb_dma_helper.c
b/drivers/gpu/drm/drm_fb_dma_helper.c
index fd71969d2fb1..00aaad648a33 100644
--- a/drivers/gpu/drm/drm_fb_dma_helper.c
+++ b/drivers/gpu/drm/drm_fb_dma_helper.c
@@ -85,6 +85,9 @@ dma_addr_t drm_fb_dma_get_gem_addr(struct drm_framebuffer *fb,
u32 block_start_y;
u32 num_hblocks;
+ if (block_w == 0 || block_h == 0)
+ return 0;
+
obj = drm_fb_dma_get_gem_obj(fb, plane);
if (!obj)
return 0;
@@ -101,8 +104,8 @@ dma_addr_t drm_fb_dma_get_gem_addr(struct drm_framebuffer
*fb,
block_start_y = (sample_y / block_h) * block_h;
num_hblocks = sample_x / block_w;
- dma_addr += fb->pitches[plane] * block_start_y;
- dma_addr += block_size * num_hblocks;
+ dma_addr += (dma_addr_t)fb->pitches[plane] * block_start_y;
+ dma_addr += (dma_addr_t)block_size * num_hblocks;
return dma_addr;
}
--
2.34.1
--
Best Regards,
Krzysztof