drm/amdgpu: fix integer overflow in amdgpu_gem_align_pitch()

amdgpu_gem_align_pitch() is passed u32 width and cpp from dumb buffer
creation but uses signed int internally.  The round-up add and the
aligned * cpp multiplication can overflow, returning zero or a negative
pitch.  A zero pitch propagates to a zero-sized GEM object allocation
that reaches userspace via DRM_IOCTL_MODE_CREATE_DUMB.

Switch the helper to unsigned int and use check_add_overflow() /
check_mul_overflow() so wraparound returns zero.  Reject a zero pitch
or size in amdgpu_mode_dumb_create() rather than allocating a zero-
byte BO.

Fixes: 8e911ab770 ("drm: amdgpu: Replace drm_fb_get_bpp_depth() with drm_format_plane_cpp()")
Signed-off-by: Werner Kasselman <werner@verivus.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
This commit is contained in:
Werner Kasselman 2026-04-14 05:08:42 +00:00 committed by Alex Deucher
parent ad0150fa2f
commit fc3659f178

View File

@ -27,6 +27,7 @@
*/
#include <linux/ktime.h>
#include <linux/module.h>
#include <linux/overflow.h>
#include <linux/pagemap.h>
#include <linux/pci.h>
#include <linux/dma-buf.h>
@ -1217,13 +1218,14 @@ int amdgpu_gem_list_handles_ioctl(struct drm_device *dev, void *data,
return ret;
}
static int amdgpu_gem_align_pitch(struct amdgpu_device *adev,
int width,
int cpp,
bool tiled)
static unsigned int amdgpu_gem_align_pitch(struct amdgpu_device *adev,
unsigned int width,
unsigned int cpp,
bool tiled)
{
int aligned = width;
int pitch_mask = 0;
unsigned int aligned = width;
unsigned int pitch_mask = 0;
unsigned int pitch;
switch (cpp) {
case 1:
@ -1238,9 +1240,12 @@ static int amdgpu_gem_align_pitch(struct amdgpu_device *adev,
break;
}
aligned += pitch_mask;
if (check_add_overflow(aligned, pitch_mask, &aligned))
return 0;
aligned &= ~pitch_mask;
return aligned * cpp;
if (check_mul_overflow(aligned, cpp, &pitch))
return 0;
return pitch;
}
int amdgpu_mode_dumb_create(struct drm_file *file_priv,
@ -1267,8 +1272,12 @@ int amdgpu_mode_dumb_create(struct drm_file *file_priv,
args->pitch = amdgpu_gem_align_pitch(adev, args->width,
DIV_ROUND_UP(args->bpp, 8), 0);
if (!args->pitch)
return -EINVAL;
args->size = (u64)args->pitch * args->height;
args->size = ALIGN(args->size, PAGE_SIZE);
if (!args->size)
return -EINVAL;
domain = amdgpu_bo_get_preferred_domain(adev,
amdgpu_display_supported_domains(adev, flags));
r = amdgpu_gem_object_create(adev, args->size, 0, domain, flags,