diff mbox

drm: fix division-by-zero on dumb_create()

Message ID 1408901006-3751-1-git-send-email-dh.herrmann@gmail.com (mailing list archive)
State New, archived
Headers show

Commit Message

David Herrmann Aug. 24, 2014, 5:23 p.m. UTC
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(-)

Comments

Rob Clark Aug. 24, 2014, 8:57 p.m. UTC | #1
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
>
diff mbox

Patch

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)