| From f045f459d925138fe7d6193a8c86406bda7e49da Mon Sep 17 00:00:00 2001 |
| From: Ben Skeggs <bskeggs@redhat.com> |
| Date: Thu, 2 Jun 2016 12:23:31 +1000 |
| Subject: drm/nouveau/fbcon: fix out-of-bounds memory accesses |
| |
| From: Ben Skeggs <bskeggs@redhat.com> |
| |
| commit f045f459d925138fe7d6193a8c86406bda7e49da upstream. |
| |
| Reported by KASAN. |
| |
| Signed-off-by: Ben Skeggs <bskeggs@redhat.com> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| |
| --- |
| drivers/gpu/drm/nouveau/nouveau_fbcon.c | 1 + |
| drivers/gpu/drm/nouveau/nv04_fbcon.c | 7 ++----- |
| drivers/gpu/drm/nouveau/nv50_fbcon.c | 6 ++---- |
| drivers/gpu/drm/nouveau/nvc0_fbcon.c | 6 ++---- |
| 4 files changed, 7 insertions(+), 13 deletions(-) |
| |
| --- a/drivers/gpu/drm/nouveau/nouveau_fbcon.c |
| +++ b/drivers/gpu/drm/nouveau/nouveau_fbcon.c |
| @@ -557,6 +557,7 @@ nouveau_fbcon_init(struct drm_device *de |
| if (ret) |
| goto fini; |
| |
| + fbcon->helper.fbdev->pixmap.buf_align = 4; |
| return 0; |
| |
| fini: |
| --- a/drivers/gpu/drm/nouveau/nv04_fbcon.c |
| +++ b/drivers/gpu/drm/nouveau/nv04_fbcon.c |
| @@ -82,7 +82,6 @@ nv04_fbcon_imageblit(struct fb_info *inf |
| uint32_t fg; |
| uint32_t bg; |
| uint32_t dsize; |
| - uint32_t width; |
| uint32_t *data = (uint32_t *)image->data; |
| int ret; |
| |
| @@ -93,9 +92,6 @@ nv04_fbcon_imageblit(struct fb_info *inf |
| if (ret) |
| return ret; |
| |
| - width = ALIGN(image->width, 8); |
| - dsize = ALIGN(width * image->height, 32) >> 5; |
| - |
| if (info->fix.visual == FB_VISUAL_TRUECOLOR || |
| info->fix.visual == FB_VISUAL_DIRECTCOLOR) { |
| fg = ((uint32_t *) info->pseudo_palette)[image->fg_color]; |
| @@ -111,10 +107,11 @@ nv04_fbcon_imageblit(struct fb_info *inf |
| ((image->dx + image->width) & 0xffff)); |
| OUT_RING(chan, bg); |
| OUT_RING(chan, fg); |
| - OUT_RING(chan, (image->height << 16) | width); |
| + OUT_RING(chan, (image->height << 16) | image->width); |
| OUT_RING(chan, (image->height << 16) | image->width); |
| OUT_RING(chan, (image->dy << 16) | (image->dx & 0xffff)); |
| |
| + dsize = ALIGN(image->width * image->height, 32) >> 5; |
| while (dsize) { |
| int iter_len = dsize > 128 ? 128 : dsize; |
| |
| --- a/drivers/gpu/drm/nouveau/nv50_fbcon.c |
| +++ b/drivers/gpu/drm/nouveau/nv50_fbcon.c |
| @@ -95,7 +95,7 @@ nv50_fbcon_imageblit(struct fb_info *inf |
| struct nouveau_fbdev *nfbdev = info->par; |
| struct nouveau_drm *drm = nouveau_drm(nfbdev->dev); |
| struct nouveau_channel *chan = drm->channel; |
| - uint32_t width, dwords, *data = (uint32_t *)image->data; |
| + uint32_t dwords, *data = (uint32_t *)image->data; |
| uint32_t mask = ~(~0 >> (32 - info->var.bits_per_pixel)); |
| uint32_t *palette = info->pseudo_palette; |
| int ret; |
| @@ -107,9 +107,6 @@ nv50_fbcon_imageblit(struct fb_info *inf |
| if (ret) |
| return ret; |
| |
| - width = ALIGN(image->width, 32); |
| - dwords = (width * image->height) >> 5; |
| - |
| BEGIN_NV04(chan, NvSub2D, 0x0814, 2); |
| if (info->fix.visual == FB_VISUAL_TRUECOLOR || |
| info->fix.visual == FB_VISUAL_DIRECTCOLOR) { |
| @@ -128,6 +125,7 @@ nv50_fbcon_imageblit(struct fb_info *inf |
| OUT_RING(chan, 0); |
| OUT_RING(chan, image->dy); |
| |
| + dwords = ALIGN(image->width * image->height, 32) >> 5; |
| while (dwords) { |
| int push = dwords > 2047 ? 2047 : dwords; |
| |
| --- a/drivers/gpu/drm/nouveau/nvc0_fbcon.c |
| +++ b/drivers/gpu/drm/nouveau/nvc0_fbcon.c |
| @@ -95,7 +95,7 @@ nvc0_fbcon_imageblit(struct fb_info *inf |
| struct nouveau_fbdev *nfbdev = info->par; |
| struct nouveau_drm *drm = nouveau_drm(nfbdev->dev); |
| struct nouveau_channel *chan = drm->channel; |
| - uint32_t width, dwords, *data = (uint32_t *)image->data; |
| + uint32_t dwords, *data = (uint32_t *)image->data; |
| uint32_t mask = ~(~0 >> (32 - info->var.bits_per_pixel)); |
| uint32_t *palette = info->pseudo_palette; |
| int ret; |
| @@ -107,9 +107,6 @@ nvc0_fbcon_imageblit(struct fb_info *inf |
| if (ret) |
| return ret; |
| |
| - width = ALIGN(image->width, 32); |
| - dwords = (width * image->height) >> 5; |
| - |
| BEGIN_NVC0(chan, NvSub2D, 0x0814, 2); |
| if (info->fix.visual == FB_VISUAL_TRUECOLOR || |
| info->fix.visual == FB_VISUAL_DIRECTCOLOR) { |
| @@ -128,6 +125,7 @@ nvc0_fbcon_imageblit(struct fb_info *inf |
| OUT_RING (chan, 0); |
| OUT_RING (chan, image->dy); |
| |
| + dwords = ALIGN(image->width * image->height, 32) >> 5; |
| while (dwords) { |
| int push = dwords > 2047 ? 2047 : dwords; |
| |