diff options
author | Ben Skeggs <bskeggs@redhat.com> | 2016-06-01 22:23:31 -0400 |
---|---|---|
committer | Ben Skeggs <bskeggs@redhat.com> | 2016-06-01 23:53:44 -0400 |
commit | f045f459d925138fe7d6193a8c86406bda7e49da (patch) | |
tree | f00acbaf667b587b9e0cbdcb00d16826cbc12429 | |
parent | 383d0a419f8e63e3d65e706c3c515fa9505ce364 (diff) |
drm/nouveau/fbcon: fix out-of-bounds memory accesses
Reported by KASAN.
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
Cc: stable@vger.kernel.org
-rw-r--r-- | drivers/gpu/drm/nouveau/nouveau_fbcon.c | 1 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nv04_fbcon.c | 7 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nv50_fbcon.c | 6 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nvc0_fbcon.c | 6 |
4 files changed, 7 insertions, 13 deletions
diff --git a/drivers/gpu/drm/nouveau/nouveau_fbcon.c b/drivers/gpu/drm/nouveau/nouveau_fbcon.c index 57aaf98a26f9..300ea03be8f0 100644 --- a/drivers/gpu/drm/nouveau/nouveau_fbcon.c +++ b/drivers/gpu/drm/nouveau/nouveau_fbcon.c | |||
@@ -552,6 +552,7 @@ nouveau_fbcon_init(struct drm_device *dev) | |||
552 | if (ret) | 552 | if (ret) |
553 | goto fini; | 553 | goto fini; |
554 | 554 | ||
555 | fbcon->helper.fbdev->pixmap.buf_align = 4; | ||
555 | return 0; | 556 | return 0; |
556 | 557 | ||
557 | fini: | 558 | fini: |
diff --git a/drivers/gpu/drm/nouveau/nv04_fbcon.c b/drivers/gpu/drm/nouveau/nv04_fbcon.c index 0f3e4bb411cc..7d9248b8c664 100644 --- 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 *info, const struct fb_image *image) | |||
82 | uint32_t fg; | 82 | uint32_t fg; |
83 | uint32_t bg; | 83 | uint32_t bg; |
84 | uint32_t dsize; | 84 | uint32_t dsize; |
85 | uint32_t width; | ||
86 | uint32_t *data = (uint32_t *)image->data; | 85 | uint32_t *data = (uint32_t *)image->data; |
87 | int ret; | 86 | int ret; |
88 | 87 | ||
@@ -93,9 +92,6 @@ nv04_fbcon_imageblit(struct fb_info *info, const struct fb_image *image) | |||
93 | if (ret) | 92 | if (ret) |
94 | return ret; | 93 | return ret; |
95 | 94 | ||
96 | width = ALIGN(image->width, 8); | ||
97 | dsize = ALIGN(width * image->height, 32) >> 5; | ||
98 | |||
99 | if (info->fix.visual == FB_VISUAL_TRUECOLOR || | 95 | if (info->fix.visual == FB_VISUAL_TRUECOLOR || |
100 | info->fix.visual == FB_VISUAL_DIRECTCOLOR) { | 96 | info->fix.visual == FB_VISUAL_DIRECTCOLOR) { |
101 | fg = ((uint32_t *) info->pseudo_palette)[image->fg_color]; | 97 | fg = ((uint32_t *) info->pseudo_palette)[image->fg_color]; |
@@ -111,10 +107,11 @@ nv04_fbcon_imageblit(struct fb_info *info, const struct fb_image *image) | |||
111 | ((image->dx + image->width) & 0xffff)); | 107 | ((image->dx + image->width) & 0xffff)); |
112 | OUT_RING(chan, bg); | 108 | OUT_RING(chan, bg); |
113 | OUT_RING(chan, fg); | 109 | OUT_RING(chan, fg); |
114 | OUT_RING(chan, (image->height << 16) | width); | 110 | OUT_RING(chan, (image->height << 16) | image->width); |
115 | OUT_RING(chan, (image->height << 16) | image->width); | 111 | OUT_RING(chan, (image->height << 16) | image->width); |
116 | OUT_RING(chan, (image->dy << 16) | (image->dx & 0xffff)); | 112 | OUT_RING(chan, (image->dy << 16) | (image->dx & 0xffff)); |
117 | 113 | ||
114 | dsize = ALIGN(image->width * image->height, 32) >> 5; | ||
118 | while (dsize) { | 115 | while (dsize) { |
119 | int iter_len = dsize > 128 ? 128 : dsize; | 116 | int iter_len = dsize > 128 ? 128 : dsize; |
120 | 117 | ||
diff --git a/drivers/gpu/drm/nouveau/nv50_fbcon.c b/drivers/gpu/drm/nouveau/nv50_fbcon.c index 33d9ee0fac40..1aeb698e9707 100644 --- 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 *info, const struct fb_image *image) | |||
95 | struct nouveau_fbdev *nfbdev = info->par; | 95 | struct nouveau_fbdev *nfbdev = info->par; |
96 | struct nouveau_drm *drm = nouveau_drm(nfbdev->dev); | 96 | struct nouveau_drm *drm = nouveau_drm(nfbdev->dev); |
97 | struct nouveau_channel *chan = drm->channel; | 97 | struct nouveau_channel *chan = drm->channel; |
98 | uint32_t width, dwords, *data = (uint32_t *)image->data; | 98 | uint32_t dwords, *data = (uint32_t *)image->data; |
99 | uint32_t mask = ~(~0 >> (32 - info->var.bits_per_pixel)); | 99 | uint32_t mask = ~(~0 >> (32 - info->var.bits_per_pixel)); |
100 | uint32_t *palette = info->pseudo_palette; | 100 | uint32_t *palette = info->pseudo_palette; |
101 | int ret; | 101 | int ret; |
@@ -107,9 +107,6 @@ nv50_fbcon_imageblit(struct fb_info *info, const struct fb_image *image) | |||
107 | if (ret) | 107 | if (ret) |
108 | return ret; | 108 | return ret; |
109 | 109 | ||
110 | width = ALIGN(image->width, 32); | ||
111 | dwords = (width * image->height) >> 5; | ||
112 | |||
113 | BEGIN_NV04(chan, NvSub2D, 0x0814, 2); | 110 | BEGIN_NV04(chan, NvSub2D, 0x0814, 2); |
114 | if (info->fix.visual == FB_VISUAL_TRUECOLOR || | 111 | if (info->fix.visual == FB_VISUAL_TRUECOLOR || |
115 | info->fix.visual == FB_VISUAL_DIRECTCOLOR) { | 112 | info->fix.visual == FB_VISUAL_DIRECTCOLOR) { |
@@ -128,6 +125,7 @@ nv50_fbcon_imageblit(struct fb_info *info, const struct fb_image *image) | |||
128 | OUT_RING(chan, 0); | 125 | OUT_RING(chan, 0); |
129 | OUT_RING(chan, image->dy); | 126 | OUT_RING(chan, image->dy); |
130 | 127 | ||
128 | dwords = ALIGN(image->width * image->height, 32) >> 5; | ||
131 | while (dwords) { | 129 | while (dwords) { |
132 | int push = dwords > 2047 ? 2047 : dwords; | 130 | int push = dwords > 2047 ? 2047 : dwords; |
133 | 131 | ||
diff --git a/drivers/gpu/drm/nouveau/nvc0_fbcon.c b/drivers/gpu/drm/nouveau/nvc0_fbcon.c index a0913359ac05..839f4c8c1805 100644 --- 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 *info, const struct fb_image *image) | |||
95 | struct nouveau_fbdev *nfbdev = info->par; | 95 | struct nouveau_fbdev *nfbdev = info->par; |
96 | struct nouveau_drm *drm = nouveau_drm(nfbdev->dev); | 96 | struct nouveau_drm *drm = nouveau_drm(nfbdev->dev); |
97 | struct nouveau_channel *chan = drm->channel; | 97 | struct nouveau_channel *chan = drm->channel; |
98 | uint32_t width, dwords, *data = (uint32_t *)image->data; | 98 | uint32_t dwords, *data = (uint32_t *)image->data; |
99 | uint32_t mask = ~(~0 >> (32 - info->var.bits_per_pixel)); | 99 | uint32_t mask = ~(~0 >> (32 - info->var.bits_per_pixel)); |
100 | uint32_t *palette = info->pseudo_palette; | 100 | uint32_t *palette = info->pseudo_palette; |
101 | int ret; | 101 | int ret; |
@@ -107,9 +107,6 @@ nvc0_fbcon_imageblit(struct fb_info *info, const struct fb_image *image) | |||
107 | if (ret) | 107 | if (ret) |
108 | return ret; | 108 | return ret; |
109 | 109 | ||
110 | width = ALIGN(image->width, 32); | ||
111 | dwords = (width * image->height) >> 5; | ||
112 | |||
113 | BEGIN_NVC0(chan, NvSub2D, 0x0814, 2); | 110 | BEGIN_NVC0(chan, NvSub2D, 0x0814, 2); |
114 | if (info->fix.visual == FB_VISUAL_TRUECOLOR || | 111 | if (info->fix.visual == FB_VISUAL_TRUECOLOR || |
115 | info->fix.visual == FB_VISUAL_DIRECTCOLOR) { | 112 | info->fix.visual == FB_VISUAL_DIRECTCOLOR) { |
@@ -128,6 +125,7 @@ nvc0_fbcon_imageblit(struct fb_info *info, const struct fb_image *image) | |||
128 | OUT_RING (chan, 0); | 125 | OUT_RING (chan, 0); |
129 | OUT_RING (chan, image->dy); | 126 | OUT_RING (chan, image->dy); |
130 | 127 | ||
128 | dwords = ALIGN(image->width * image->height, 32) >> 5; | ||
131 | while (dwords) { | 129 | while (dwords) { |
132 | int push = dwords > 2047 ? 2047 : dwords; | 130 | int push = dwords > 2047 ? 2047 : dwords; |
133 | 131 | ||