Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f045f459 authored by Ben Skeggs's avatar Ben Skeggs
Browse files

drm/nouveau/fbcon: fix out-of-bounds memory accesses



Reported by KASAN.

Signed-off-by: default avatarBen Skeggs <bskeggs@redhat.com>
Cc: stable@vger.kernel.org
parent 383d0a41
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -552,6 +552,7 @@ nouveau_fbcon_init(struct drm_device *dev)
	if (ret)
		goto fini;

	fbcon->helper.fbdev->pixmap.buf_align = 4;
	return 0;

fini:
+2 −5
Original line number Diff line number Diff line
@@ -82,7 +82,6 @@ nv04_fbcon_imageblit(struct fb_info *info, const struct fb_image *image)
	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 *info, const struct fb_image *image)
	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 *info, const struct fb_image *image)
			 ((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;

+2 −4
Original line number Diff line number Diff line
@@ -95,7 +95,7 @@ nv50_fbcon_imageblit(struct fb_info *info, const struct fb_image *image)
	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 *info, const struct fb_image *image)
	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 *info, const struct fb_image *image)
	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;

+2 −4
Original line number Diff line number Diff line
@@ -95,7 +95,7 @@ nvc0_fbcon_imageblit(struct fb_info *info, const struct fb_image *image)
	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 *info, const struct fb_image *image)
	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 *info, const struct fb_image *image)
	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;