| From foo@baz Sun Jun 17 12:07:34 CEST 2018 |
| From: Dan Carpenter <dan.carpenter@oracle.com> |
| Date: Wed, 16 May 2018 17:00:26 +0300 |
| Subject: drm/dumb-buffers: Integer overflow in drm_mode_create_ioctl() |
| |
| From: Dan Carpenter <dan.carpenter@oracle.com> |
| |
| [ Upstream commit 2b6207291b7b277a5df9d1aab44b56815a292dba ] |
| |
| There is a comment here which says that DIV_ROUND_UP() and that's where |
| the problem comes from. Say you pick: |
| |
| args->bpp = UINT_MAX - 7; |
| args->width = 4; |
| args->height = 1; |
| |
| The integer overflow in DIV_ROUND_UP() means "cpp" is UINT_MAX / 8 and |
| because of how we picked args->width that means cpp < UINT_MAX / 4. |
| |
| I've fixed it by preventing the integer overflow in DIV_ROUND_UP(). I |
| removed the check for !cpp because it's not possible after this change. |
| I also changed all the 0xffffffffU references to U32_MAX. |
| |
| Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com> |
| Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch> |
| Link: https://patchwork.freedesktop.org/patch/msgid/20180516140026.GA19340@mwanda |
| Signed-off-by: Sasha Levin <alexander.levin@microsoft.com> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| --- |
| drivers/gpu/drm/drm_dumb_buffers.c | 7 ++++--- |
| 1 file changed, 4 insertions(+), 3 deletions(-) |
| |
| --- a/drivers/gpu/drm/drm_dumb_buffers.c |
| +++ b/drivers/gpu/drm/drm_dumb_buffers.c |
| @@ -65,12 +65,13 @@ int drm_mode_create_dumb_ioctl(struct dr |
| return -EINVAL; |
| |
| /* overflow checks for 32bit size calculations */ |
| - /* NOTE: DIV_ROUND_UP() can overflow */ |
| + if (args->bpp > U32_MAX - 8) |
| + return -EINVAL; |
| cpp = DIV_ROUND_UP(args->bpp, 8); |
| - if (!cpp || cpp > 0xffffffffU / args->width) |
| + if (cpp > U32_MAX / args->width) |
| return -EINVAL; |
| stride = cpp * args->width; |
| - if (args->height > 0xffffffffU / stride) |
| + if (args->height > U32_MAX / stride) |
| return -EINVAL; |
| |
| /* test for wrap-around */ |