0903551
From 02510a8805db2c3f8ca2926f90c4b3793934404a Mon Sep 17 00:00:00 2001
0903551
From: Fedora Kernel Team <kernel-team@fedoraproject.org>
0903551
Date: Mon, 20 Jun 2016 14:51:45 +0200
0903551
Subject: [PATCH 2/6] drm/nouveau/fbcon: fix out-of-bounds memory accesses
0903551
0903551
Upstream: drm-fixes for 4.7 (and cc'd 4.6-stable)
0903551
commit f045f459d925138fe7d6193a8c86406bda7e49da
0903551
0903551
Author:     Ben Skeggs <bskeggs@redhat.com>
0903551
AuthorDate: Thu Jun 2 12:23:31 2016 +1000
0903551
Commit:     Ben Skeggs <bskeggs@redhat.com>
0903551
CommitDate: Thu Jun 2 13:53:44 2016 +1000
0903551
0903551
    drm/nouveau/fbcon: fix out-of-bounds memory accesses
0903551
0903551
    Reported by KASAN.
0903551
0903551
    Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
0903551
    Cc: stable@vger.kernel.org
0903551
---
0903551
 drivers/gpu/drm/nouveau/nouveau_fbcon.c | 1 +
0903551
 drivers/gpu/drm/nouveau/nv04_fbcon.c    | 7 ++-----
0903551
 drivers/gpu/drm/nouveau/nv50_fbcon.c    | 6 ++----
0903551
 drivers/gpu/drm/nouveau/nvc0_fbcon.c    | 6 ++----
0903551
 4 files changed, 7 insertions(+), 13 deletions(-)
0903551
0903551
diff --git a/drivers/gpu/drm/nouveau/nouveau_fbcon.c b/drivers/gpu/drm/nouveau/nouveau_fbcon.c
0903551
index 59f27e7..bd89c86 100644
0903551
--- a/drivers/gpu/drm/nouveau/nouveau_fbcon.c
0903551
+++ b/drivers/gpu/drm/nouveau/nouveau_fbcon.c
0903551
@@ -557,6 +557,7 @@ nouveau_fbcon_init(struct drm_device *dev)
0903551
 	if (ret)
0903551
 		goto fini;
0903551
 
0903551
+	fbcon->helper.fbdev->pixmap.buf_align = 4;
0903551
 	return 0;
0903551
 
0903551
 fini:
0903551
diff --git a/drivers/gpu/drm/nouveau/nv04_fbcon.c b/drivers/gpu/drm/nouveau/nv04_fbcon.c
0903551
index 789dc29..8f715fe 100644
0903551
--- a/drivers/gpu/drm/nouveau/nv04_fbcon.c
0903551
+++ b/drivers/gpu/drm/nouveau/nv04_fbcon.c
0903551
@@ -82,7 +82,6 @@ nv04_fbcon_imageblit(struct fb_info *info, const struct fb_image *image)
0903551
 	uint32_t fg;
0903551
 	uint32_t bg;
0903551
 	uint32_t dsize;
0903551
-	uint32_t width;
0903551
 	uint32_t *data = (uint32_t *)image->data;
0903551
 	int ret;
0903551
 
0903551
@@ -93,9 +92,6 @@ nv04_fbcon_imageblit(struct fb_info *info, const struct fb_image *image)
0903551
 	if (ret)
0903551
 		return ret;
0903551
 
0903551
-	width = ALIGN(image->width, 8);
0903551
-	dsize = ALIGN(width * image->height, 32) >> 5;
0903551
-
0903551
 	if (info->fix.visual == FB_VISUAL_TRUECOLOR ||
0903551
 	    info->fix.visual == FB_VISUAL_DIRECTCOLOR) {
0903551
 		fg = ((uint32_t *) info->pseudo_palette)[image->fg_color];
0903551
@@ -111,10 +107,11 @@ nv04_fbcon_imageblit(struct fb_info *info, const struct fb_image *image)
0903551
 			 ((image->dx + image->width) & 0xffff));
0903551
 	OUT_RING(chan, bg);
0903551
 	OUT_RING(chan, fg);
0903551
-	OUT_RING(chan, (image->height << 16) | width);
0903551
+	OUT_RING(chan, (image->height << 16) | image->width);
0903551
 	OUT_RING(chan, (image->height << 16) | image->width);
0903551
 	OUT_RING(chan, (image->dy << 16) | (image->dx & 0xffff));
0903551
 
0903551
+	dsize = ALIGN(image->width * image->height, 32) >> 5;
0903551
 	while (dsize) {
0903551
 		int iter_len = dsize > 128 ? 128 : dsize;
0903551
 
0903551
diff --git a/drivers/gpu/drm/nouveau/nv50_fbcon.c b/drivers/gpu/drm/nouveau/nv50_fbcon.c
0903551
index e05499d..a4e259a 100644
0903551
--- a/drivers/gpu/drm/nouveau/nv50_fbcon.c
0903551
+++ b/drivers/gpu/drm/nouveau/nv50_fbcon.c
0903551
@@ -95,7 +95,7 @@ nv50_fbcon_imageblit(struct fb_info *info, const struct fb_image *image)
0903551
 	struct nouveau_fbdev *nfbdev = info->par;
0903551
 	struct nouveau_drm *drm = nouveau_drm(nfbdev->dev);
0903551
 	struct nouveau_channel *chan = drm->channel;
0903551
-	uint32_t width, dwords, *data = (uint32_t *)image->data;
0903551
+	uint32_t dwords, *data = (uint32_t *)image->data;
0903551
 	uint32_t mask = ~(~0 >> (32 - info->var.bits_per_pixel));
0903551
 	uint32_t *palette = info->pseudo_palette;
0903551
 	int ret;
0903551
@@ -107,9 +107,6 @@ nv50_fbcon_imageblit(struct fb_info *info, const struct fb_image *image)
0903551
 	if (ret)
0903551
 		return ret;
0903551
 
0903551
-	width = ALIGN(image->width, 32);
0903551
-	dwords = (width * image->height) >> 5;
0903551
-
0903551
 	BEGIN_NV04(chan, NvSub2D, 0x0814, 2);
0903551
 	if (info->fix.visual == FB_VISUAL_TRUECOLOR ||
0903551
 	    info->fix.visual == FB_VISUAL_DIRECTCOLOR) {
0903551
@@ -128,6 +125,7 @@ nv50_fbcon_imageblit(struct fb_info *info, const struct fb_image *image)
0903551
 	OUT_RING(chan, 0);
0903551
 	OUT_RING(chan, image->dy);
0903551
 
0903551
+	dwords = ALIGN(image->width * image->height, 32) >> 5;
0903551
 	while (dwords) {
0903551
 		int push = dwords > 2047 ? 2047 : dwords;
0903551
 
0903551
diff --git a/drivers/gpu/drm/nouveau/nvc0_fbcon.c b/drivers/gpu/drm/nouveau/nvc0_fbcon.c
0903551
index c97395b..f28315e 100644
0903551
--- a/drivers/gpu/drm/nouveau/nvc0_fbcon.c
0903551
+++ b/drivers/gpu/drm/nouveau/nvc0_fbcon.c
0903551
@@ -95,7 +95,7 @@ nvc0_fbcon_imageblit(struct fb_info *info, const struct fb_image *image)
0903551
 	struct nouveau_fbdev *nfbdev = info->par;
0903551
 	struct nouveau_drm *drm = nouveau_drm(nfbdev->dev);
0903551
 	struct nouveau_channel *chan = drm->channel;
0903551
-	uint32_t width, dwords, *data = (uint32_t *)image->data;
0903551
+	uint32_t dwords, *data = (uint32_t *)image->data;
0903551
 	uint32_t mask = ~(~0 >> (32 - info->var.bits_per_pixel));
0903551
 	uint32_t *palette = info->pseudo_palette;
0903551
 	int ret;
0903551
@@ -107,9 +107,6 @@ nvc0_fbcon_imageblit(struct fb_info *info, const struct fb_image *image)
0903551
 	if (ret)
0903551
 		return ret;
0903551
 
0903551
-	width = ALIGN(image->width, 32);
0903551
-	dwords = (width * image->height) >> 5;
0903551
-
0903551
 	BEGIN_NVC0(chan, NvSub2D, 0x0814, 2);
0903551
 	if (info->fix.visual == FB_VISUAL_TRUECOLOR ||
0903551
 	    info->fix.visual == FB_VISUAL_DIRECTCOLOR) {
0903551
@@ -128,6 +125,7 @@ nvc0_fbcon_imageblit(struct fb_info *info, const struct fb_image *image)
0903551
 	OUT_RING  (chan, 0);
0903551
 	OUT_RING  (chan, image->dy);
0903551
 
0903551
+	dwords = ALIGN(image->width * image->height, 32) >> 5;
0903551
 	while (dwords) {
0903551
 		int push = dwords > 2047 ? 2047 : dwords;
0903551
 
0903551
-- 
0903551
2.7.4
0903551