Kinda unexpected, but DIV_ROUND_UP() can overflow if passed an argument bigger than UINT_MAX - DIVISOR. Fix this by testing for "!cpp" before using it in the following division.
Note that DIV_ROUND_UP() is defined as: #define DIV_ROUND_UP(n,d) (((n) + (d) - 1) / (d))
..this will obviously overflow if (n + d - 1) is bigger than UINT_MAX.
Reported-by: Tommi Rantala tt.rantala@gmail.com Signed-off-by: David Herrmann dh.herrmann@gmail.com --- drivers/gpu/drm/drm_crtc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c index fe94cc1..55057f7 100644 --- a/drivers/gpu/drm/drm_crtc.c +++ b/drivers/gpu/drm/drm_crtc.c @@ -4397,7 +4397,7 @@ int drm_mode_create_dumb_ioctl(struct drm_device *dev,
/* overflow checks for 32bit size calculations */ cpp = DIV_ROUND_UP(args->bpp, 8); - if (cpp > 0xffffffffU / args->width) + if (!cpp || cpp > 0xffffffffU / args->width) return -EINVAL; stride = cpp * args->width; if (args->height > 0xffffffffU / stride)
On Sun, Aug 24, 2014 at 1:23 PM, David Herrmann dh.herrmann@gmail.com wrote:
Kinda unexpected, but DIV_ROUND_UP() can overflow if passed an argument bigger than UINT_MAX - DIVISOR. Fix this by testing for "!cpp" before using it in the following division.
Note that DIV_ROUND_UP() is defined as: #define DIV_ROUND_UP(n,d) (((n) + (d) - 1) / (d))
..this will obviously overflow if (n + d - 1) is bigger than UINT_MAX.
Reported-by: Tommi Rantala tt.rantala@gmail.com Signed-off-by: David Herrmann dh.herrmann@gmail.com
drivers/gpu/drm/drm_crtc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c index fe94cc1..55057f7 100644 --- a/drivers/gpu/drm/drm_crtc.c +++ b/drivers/gpu/drm/drm_crtc.c @@ -4397,7 +4397,7 @@ int drm_mode_create_dumb_ioctl(struct drm_device *dev,
/* overflow checks for 32bit size calculations */ cpp = DIV_ROUND_UP(args->bpp, 8);
if (cpp > 0xffffffffU / args->width)
might be an idea to add:
+ /* NOTE: DIV_ROUND_UP() can overflow */
or something along those lines.. I also assumed that DIV_ROUND_UP() would not overflow, and would otherwise find that code funny looking.
(yeah, technically someone could figure that out via git-blame.. but still..)
other than that,
Reviewed-by: Rob Clark robdclark@gmail.com
if (!cpp || cpp > 0xffffffffU / args->width) return -EINVAL; stride = cpp * args->width; if (args->height > 0xffffffffU / stride)
-- 2.1.0
dri-devel@lists.freedesktop.org