]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
drm: prevent integer overflows in dumb buffer creation helpers
authorRajat Gupta <rajat.gupta@oss.qualcomm.com>
Thu, 21 May 2026 05:11:21 +0000 (22:11 -0700)
committerThomas Zimmermann <tzimmermann@suse.de>
Fri, 29 May 2026 06:30:47 +0000 (08:30 +0200)
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>
drivers/gpu/drm/drm_dumb_buffers.c

index e2b62e5fb891ba4eb420516282413219f17a3e71..cc99681a9ed0bcab598ca99ca8d5ce95290dd998 100644 (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;