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
This commit is contained in:
parent
383d0a419f
commit
f045f459d9
|
@ -552,6 +552,7 @@ nouveau_fbcon_init(struct drm_device *dev)
|
||||||
if (ret)
|
if (ret)
|
||||||
goto fini;
|
goto fini;
|
||||||
|
|
||||||
|
fbcon->helper.fbdev->pixmap.buf_align = 4;
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
fini:
|
fini:
|
||||||
|
|
|
@ -82,7 +82,6 @@ nv04_fbcon_imageblit(struct fb_info *info, const struct fb_image *image)
|
||||||
uint32_t fg;
|
uint32_t fg;
|
||||||
uint32_t bg;
|
uint32_t bg;
|
||||||
uint32_t dsize;
|
uint32_t dsize;
|
||||||
uint32_t width;
|
|
||||||
uint32_t *data = (uint32_t *)image->data;
|
uint32_t *data = (uint32_t *)image->data;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
|
@ -93,9 +92,6 @@ nv04_fbcon_imageblit(struct fb_info *info, const struct fb_image *image)
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
width = ALIGN(image->width, 8);
|
|
||||||
dsize = ALIGN(width * image->height, 32) >> 5;
|
|
||||||
|
|
||||||
if (info->fix.visual == FB_VISUAL_TRUECOLOR ||
|
if (info->fix.visual == FB_VISUAL_TRUECOLOR ||
|
||||||
info->fix.visual == FB_VISUAL_DIRECTCOLOR) {
|
info->fix.visual == FB_VISUAL_DIRECTCOLOR) {
|
||||||
fg = ((uint32_t *) info->pseudo_palette)[image->fg_color];
|
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)
|
||||||
((image->dx + image->width) & 0xffff));
|
((image->dx + image->width) & 0xffff));
|
||||||
OUT_RING(chan, bg);
|
OUT_RING(chan, bg);
|
||||||
OUT_RING(chan, fg);
|
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->height << 16) | image->width);
|
||||||
OUT_RING(chan, (image->dy << 16) | (image->dx & 0xffff));
|
OUT_RING(chan, (image->dy << 16) | (image->dx & 0xffff));
|
||||||
|
|
||||||
|
dsize = ALIGN(image->width * image->height, 32) >> 5;
|
||||||
while (dsize) {
|
while (dsize) {
|
||||||
int iter_len = dsize > 128 ? 128 : dsize;
|
int iter_len = dsize > 128 ? 128 : dsize;
|
||||||
|
|
||||||
|
|
|
@ -95,7 +95,7 @@ nv50_fbcon_imageblit(struct fb_info *info, const struct fb_image *image)
|
||||||
struct nouveau_fbdev *nfbdev = info->par;
|
struct nouveau_fbdev *nfbdev = info->par;
|
||||||
struct nouveau_drm *drm = nouveau_drm(nfbdev->dev);
|
struct nouveau_drm *drm = nouveau_drm(nfbdev->dev);
|
||||||
struct nouveau_channel *chan = drm->channel;
|
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 mask = ~(~0 >> (32 - info->var.bits_per_pixel));
|
||||||
uint32_t *palette = info->pseudo_palette;
|
uint32_t *palette = info->pseudo_palette;
|
||||||
int ret;
|
int ret;
|
||||||
|
@ -107,9 +107,6 @@ nv50_fbcon_imageblit(struct fb_info *info, const struct fb_image *image)
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
width = ALIGN(image->width, 32);
|
|
||||||
dwords = (width * image->height) >> 5;
|
|
||||||
|
|
||||||
BEGIN_NV04(chan, NvSub2D, 0x0814, 2);
|
BEGIN_NV04(chan, NvSub2D, 0x0814, 2);
|
||||||
if (info->fix.visual == FB_VISUAL_TRUECOLOR ||
|
if (info->fix.visual == FB_VISUAL_TRUECOLOR ||
|
||||||
info->fix.visual == FB_VISUAL_DIRECTCOLOR) {
|
info->fix.visual == FB_VISUAL_DIRECTCOLOR) {
|
||||||
|
@ -128,6 +125,7 @@ nv50_fbcon_imageblit(struct fb_info *info, const struct fb_image *image)
|
||||||
OUT_RING(chan, 0);
|
OUT_RING(chan, 0);
|
||||||
OUT_RING(chan, image->dy);
|
OUT_RING(chan, image->dy);
|
||||||
|
|
||||||
|
dwords = ALIGN(image->width * image->height, 32) >> 5;
|
||||||
while (dwords) {
|
while (dwords) {
|
||||||
int push = dwords > 2047 ? 2047 : dwords;
|
int push = dwords > 2047 ? 2047 : dwords;
|
||||||
|
|
||||||
|
|
|
@ -95,7 +95,7 @@ nvc0_fbcon_imageblit(struct fb_info *info, const struct fb_image *image)
|
||||||
struct nouveau_fbdev *nfbdev = info->par;
|
struct nouveau_fbdev *nfbdev = info->par;
|
||||||
struct nouveau_drm *drm = nouveau_drm(nfbdev->dev);
|
struct nouveau_drm *drm = nouveau_drm(nfbdev->dev);
|
||||||
struct nouveau_channel *chan = drm->channel;
|
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 mask = ~(~0 >> (32 - info->var.bits_per_pixel));
|
||||||
uint32_t *palette = info->pseudo_palette;
|
uint32_t *palette = info->pseudo_palette;
|
||||||
int ret;
|
int ret;
|
||||||
|
@ -107,9 +107,6 @@ nvc0_fbcon_imageblit(struct fb_info *info, const struct fb_image *image)
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
width = ALIGN(image->width, 32);
|
|
||||||
dwords = (width * image->height) >> 5;
|
|
||||||
|
|
||||||
BEGIN_NVC0(chan, NvSub2D, 0x0814, 2);
|
BEGIN_NVC0(chan, NvSub2D, 0x0814, 2);
|
||||||
if (info->fix.visual == FB_VISUAL_TRUECOLOR ||
|
if (info->fix.visual == FB_VISUAL_TRUECOLOR ||
|
||||||
info->fix.visual == FB_VISUAL_DIRECTCOLOR) {
|
info->fix.visual == FB_VISUAL_DIRECTCOLOR) {
|
||||||
|
@ -128,6 +125,7 @@ nvc0_fbcon_imageblit(struct fb_info *info, const struct fb_image *image)
|
||||||
OUT_RING (chan, 0);
|
OUT_RING (chan, 0);
|
||||||
OUT_RING (chan, image->dy);
|
OUT_RING (chan, image->dy);
|
||||||
|
|
||||||
|
dwords = ALIGN(image->width * image->height, 32) >> 5;
|
||||||
while (dwords) {
|
while (dwords) {
|
||||||
int push = dwords > 2047 ? 2047 : dwords;
|
int push = dwords > 2047 ? 2047 : dwords;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue