drm: prevent integer overflows in dumb buffer creation helpers

Fix integer overflow issues in the dumb buffer creation path:

1. drm_mode_create_dumb() does not bound width, height, or bpp
   before passing them to driver callbacks.  Downstream helpers
   (e.g. drm_gem_dma_dumb_create_internal) perform pitch/size
   alignment in u32 arithmetic that can overflow for extreme
   values.  Add hard limits: width and height < 8192, bpp <= 32.
   No legitimate software rendering use case exceeds these.

2. drm_mode_align_dumb() uses roundup(pitch, hw_pitch_align)
   without checking for overflow.  If pitch is near U32_MAX,
   roundup() wraps to a small value, making subsequent
   check_mul_overflow() pass with a much smaller pitch than
   intended.  Add an overflow check after roundup.

3. drm_mode_align_dumb() uses ALIGN(size, hw_size_align) which
   only works correctly for power-of-two alignment values.
   Replace with roundup() which works for any alignment.

Suggested-by: Thomas Zimmermann <tzimmermann@suse.de>
Signed-off-by: Rajat Gupta <rajat.gupta@oss.qualcomm.com>
Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
This commit is contained in:
Rajat Gupta 2026-05-20 22:11:21 -07:00 committed by Thomas Zimmermann
parent ead6680f35
commit 5ab62dd368

View File

@ -70,8 +70,11 @@ static int drm_mode_align_dumb(struct drm_mode_create_dumb *args,
if (!pitch)
return -EINVAL;
if (hw_pitch_align)
if (hw_pitch_align) {
pitch = roundup(pitch, hw_pitch_align);
if (pitch < hw_pitch_align)
return -EINVAL;
}
if (!hw_size_align)
hw_size_align = PAGE_SIZE;
@ -80,7 +83,7 @@ static int drm_mode_align_dumb(struct drm_mode_create_dumb *args,
if (check_mul_overflow(args->height, pitch, &size))
return -EINVAL;
size = ALIGN(size, hw_size_align);
size = roundup(size, hw_size_align);
if (!size)
return -EINVAL;
@ -199,6 +202,13 @@ int drm_mode_create_dumb(struct drm_device *dev,
if (!args->width || !args->height || !args->bpp)
return -EINVAL;
/* Reject unreasonable inputs early. Dumb buffers are for software
* rendering; nothing legitimate needs more than 8192x8192 at 32bpp.
* This prevents overflows in downstream alignment helpers.
*/
if (args->width >= 8192 || args->height >= 8192 || args->bpp > 32)
return -EINVAL;
/* overflow checks for 32bit size calculations */
if (args->bpp > U32_MAX - 8)
return -EINVAL;