Message ID | 1408901006-3751-1-git-send-email-dh.herrmann@gmail.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
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 --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)
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(-)